├── .gitattributes
├── .gitignore
├── CHANGELOG
├── Command
├── BotMessagingCommand.php
├── ChangeChannelsTopicCommand.php
├── DebugCommand.php
├── MessageCommand.php
└── UsersCommand.php
├── DZunkeSlackBundle.php
├── DependencyInjection
├── Configuration.php
└── DZunkeSlackExtension.php
├── Event.php
├── Events
└── MessageEvent.php
├── LICENSE
├── Monolog
└── Handler
│ └── SlackHandler.php
├── README.md
├── Resources
├── config
│ └── services.yml
└── doc
│ ├── actions-list.md
│ ├── basic-usage.md
│ ├── commands.md
│ ├── configuration.md
│ ├── index.md
│ ├── installation.md
│ ├── monolog.md
│ ├── roadmap.md
│ ├── services.md
│ ├── silex.md
│ ├── slack.md
│ └── symfony-usage.md
├── Silex
└── Provider
│ └── SlackServiceProvider.php
├── Slack
├── Channels.php
├── Client.php
├── Client
│ ├── Actions.php
│ ├── Actions
│ │ ├── ActionsInterface.php
│ │ ├── ApiTest.php
│ │ ├── AuthTest.php
│ │ ├── ChannelsCreate.php
│ │ ├── ChannelsHistory.php
│ │ ├── ChannelsInfo.php
│ │ ├── ChannelsInvite.php
│ │ ├── ChannelsList.php
│ │ ├── ChannelsSetTopic.php
│ │ ├── ChatPostMessage.php
│ │ ├── FilesUpload.php
│ │ └── UsersList.php
│ ├── Connection.php
│ └── Response.php
├── Entity
│ ├── Message.php
│ └── MessageAttachment.php
├── Messaging.php
├── Messaging
│ ├── Identity.php
│ └── IdentityBag.php
└── Users.php
└── composer.json
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.lock
2 | composer.phar
3 | vendor
4 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | SlackBundle v2.6.0
2 | ==================
3 | - Feature: Support file upload api with multipart form data (by @pmishev)
4 | - Feature: Add support for threads in file upload api (by @pmishev)
5 |
6 | SlackBundle v2.5.0
7 | ==================
8 | - Feature: Removed symfony/symfony as required package by splitting requirements (by @makasim)
9 | - FIX: Symfony 4 Warnings when calling public services (by @syunta)
10 |
11 | SlackBundle v2.4.1
12 | ==================
13 | - FIX: Symfony 2.8 support was defect by removed classes in services.yml
14 |
15 | SlackBundle v2.4.0
16 | ==================
17 | - Feature: Commands compatible to Symfony 3.4 (by @alister)
18 | - (NOT BC) Feature: Remove old command prefixes (see v1.3) (by @alister)
19 | - Patch: removed different typos (by @alister)
20 | - Feature: Support for more fields in attachments and additional client options for Messaging::message() (by @pmishev)
21 | - Support for Symfony 4.0
22 |
23 | SlackBundle v2.3.0
24 | ==================
25 | - Feature: Add channel.create action
26 | - Bug: Fixed dumb error with post requesting
27 |
28 | SlackBundle v2.2.0
29 | ==================
30 | - Feature: Add Support to send Requests as POST instead of GET
31 | - Patch: Fix UsersList-Action, users email could be empty (by @mediafigaro)
32 | - Patch: Fix channel history (found in fork by @elmpp)
33 |
34 | SlackBundle v2.1.0
35 | ==================
36 | - Add Support to disable SSL Verification at Guzzle Client
37 |
38 | SlackBundle v2.0.0
39 | ==================
40 | - (NOT BC) Feature: Upgrade to Guzzle 6 (thanks for Support @alister)
41 |
42 | SlackBundle v1.4.0
43 | ==================
44 | - Feature: Monolog-Logger uses colored attachments based on the log level (by @jdecoster)
45 | - Patch: Quoting Services to Support Symfony > 2.8 (by @carlosmasip)
46 | - Patch: Fix deprecation in configuration
47 | - Patch: Enable Symfony 3.0 and PHP 7
48 |
49 | SlackBundle v1.3.0
50 | ==================
51 | - Feature: File upload service now accepts an array of channels, string usage is deprecated
52 | - Feature: Implement action to invite users to a channel
53 | - Feature: Implement action and service to get details about users on the team
54 | - Feature: Implement console command to read userdata from api
55 | - Patch: File upload no longer need to lookup channel id due to api changes
56 | - Patch: Set aliases for command names - old names with dzunke: prefix will be removed in the future!
57 |
58 | SlackBundle v1.2.2
59 | ==================
60 | - Patch: MessageAttachment support complete attachment-api (by @shimmi)
61 |
62 | SlackBundle v1.2.1
63 | ==================
64 | - Patch Feature: Customize icon_url and icon_emoji on single message-action (by @tobiassjosten)
65 |
66 | SlackBundle v1.2.0
67 | ==================
68 | - Feature: Added FileUploads
69 | - Feature: Added Basic Implementation for Event-Driven Bots
70 |
71 | SlackBundle v1.1.1
72 | ==================
73 | - Feature: Downgraded requirement for GuzzleClient Version to 3.7.0 (by @toooni)
74 |
75 | SlackBundle v1.1.0
76 | ==================
77 | - Feature: Added Provider for Silex-Integration
78 | - Feature: Added Attachments to the Messaging-Methods
79 | - (NOT BC) Refactor: Identities are only needed for Chat, so no general use is needed
80 |
81 | SlackBundle v1.0.0
82 | ==================
83 | - Initial Release
84 |
--------------------------------------------------------------------------------
/Command/BotMessagingCommand.php:
--------------------------------------------------------------------------------
1 | channels = $channels;
37 | $this->eventDispatcher = $eventDispatcher;
38 | parent::__construct();
39 | }
40 |
41 | protected function configure()
42 | {
43 | $this
44 | ->setName(static::$defaultName)
45 | ->setDescription('Running the Bot-User to a Channel')
46 | ->addArgument(
47 | 'channel',
48 | InputArgument::REQUIRED,
49 | 'Channel to Watch over'
50 | );
51 | }
52 |
53 | protected function execute(InputInterface $input, OutputInterface $output)
54 | {
55 | $logger = new Logger(new StreamHandler('php://output'));
56 |
57 | $channel = $this->channels->getId($input->getArgument('channel'));
58 | if (empty($channel)) {
59 | $logger->error('channel "' . $channel . '" does not exists');
60 | return;
61 | }
62 |
63 | $lastTimestamp = time();
64 | while (true) {
65 |
66 | try {
67 | $latestMessages = $this->channels->history($channel, $lastTimestamp);
68 |
69 | foreach ($latestMessages as $message) {
70 | if ($message->isBot() === true) {
71 | continue;
72 | }
73 |
74 | $logger->debug('Handling Message of Type : "' . $message->getType() . '"');
75 |
76 | $event = Event::MESSAGE;
77 | switch ($message->getType()) {
78 | case Message::TYPE_MESSAGE :
79 | $event = Event::MESSAGE;
80 | break;
81 | case Message::TYPE_CHANNEL_JOIN:
82 | $event = Event::JOIN;
83 | break;
84 | case Message::TYPE_CHANNEL_LEAVE:
85 | $event = Event::LEAVE;
86 | break;
87 | }
88 |
89 | $logger->debug('Dispatching "' . $event . '"');
90 |
91 | $this->eventDispatcher->dispatch(
92 | $event,
93 | new Events\MessageEvent($channel, $message)
94 | );
95 |
96 | $lastTimestamp = $message->getId();
97 | }
98 |
99 | $logger->debug('Handled ' . count($latestMessages) . ' Messages');
100 |
101 | } catch (\Exception $e) {
102 | $logger->error($e->getMessage());
103 | $logger->error($e->getTraceAsString());
104 | }
105 |
106 | sleep(self::PROCESS_ITERATION_SLEEP);
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/Command/ChangeChannelsTopicCommand.php:
--------------------------------------------------------------------------------
1 | channels = $channels;
25 | parent::__construct();
26 | }
27 |
28 | protected function configure()
29 | {
30 | $this
31 | ->setName(static::$defaultName)
32 | ->setDescription('Changing the Topic of a Channel')
33 | ->addOption('discover', 'd', InputOption::VALUE_NONE, 'channel name is given, so discover the id')
34 | ->addArgument('channel', InputArgument::REQUIRED, 'an existing channel in your team to change the topic')
35 | ->addArgument('topic', InputArgument::REQUIRED, 'the topic you want to set in the channel');
36 | }
37 |
38 | protected function execute(InputInterface $input, OutputInterface $output)
39 | {
40 | try {
41 | if ($input->getOption('discover')) {
42 | $channelId = $this->channels->getId($input->getArgument('channel'));
43 | } else {
44 | $channelId = $input->getArgument('channel');
45 | }
46 |
47 | $response = $this->channels->setTopic(
48 | $channelId,
49 | $input->getArgument('topic')
50 | );
51 |
52 | if ($response->getStatus() === false) {
53 | $output->writeln('✘ request got an error from slack: "' . $response->getError() . '"');
54 |
55 | return;
56 | }
57 |
58 | $output->writeln('✔ changed topic');
59 |
60 | if ($output->getVerbosity() == OutputInterface::VERBOSITY_VERBOSE) {
61 | $output->writeln('Old Topic: ' . $response->getData()['old_topic']);
62 | $output->writeln('New Topic: ' . $response->getData()['new_topic']);
63 | }
64 |
65 | } catch (\Exception $e) {
66 | $output->writeln('✘ there was an error while changing topic: "' . $e->getMessage() . '"');
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Command/DebugCommand.php:
--------------------------------------------------------------------------------
1 | client = $client;
34 | parent::__construct();
35 | }
36 |
37 | protected function configure()
38 | {
39 | $this
40 | ->setName(static::$defaultName)
41 | ->setDescription('Gives some Debug Informations about the SlackBundle');
42 | }
43 |
44 |
45 | protected function execute(InputInterface $input, OutputInterface $output)
46 | {
47 | $this->input = $input;
48 | $this->output = $output;
49 |
50 | $config = $this->getContainer()->getParameter('d_zunke_slack.config');
51 |
52 | $this->renderConnection($config);
53 | $this->output->writeln('');
54 | $this->renderIdentities($config);
55 | $this->output->writeln('');
56 | $this->renderSlackChannels($config);
57 | }
58 |
59 | protected function renderSlackChannels()
60 | {
61 | $this->output->writeln('Available Channels');
62 |
63 | $channels = $this->client->send(
64 | Client\Actions::ACTION_CHANNELS_LIST,
65 | [],
66 | null
67 | );
68 |
69 | if ($channels->getStatus() === false) {
70 | $this->output->writeln('' . $channels->getError() . '');
71 |
72 | return;
73 | }
74 |
75 | $table = new Table($this->output);
76 |
77 | $index = 0;
78 | foreach ($channels->getData() as $name => $channel) {
79 |
80 | if ($index > 0) {
81 | $table->addRow(new TableSeparator());
82 | }
83 |
84 | $table->addRow(['' . $name . '']);
85 | $table->addRow(
86 | [
87 | ' id',
88 | $channel['id']
89 | ]
90 | );
91 |
92 | $index++;
93 | }
94 |
95 | $table->render();
96 | }
97 |
98 | protected function renderIdentities(array $config)
99 | {
100 | $this->output->writeln('Identities');
101 |
102 | $table = new Table($this->output);
103 |
104 | $index = 0;
105 | foreach ($config['identities'] as $username => $userConfig) {
106 |
107 | if ($index > 0) {
108 | $table->addRow(new TableSeparator());
109 | }
110 |
111 | $table->addRow(['' . $username . '']);
112 |
113 | foreach ($userConfig as $configName => $configValue) {
114 | $table->addRow(
115 | [
116 | " " . $configName,
117 | is_null($configValue) ? 'null' : $configValue
118 | ]
119 | );
120 | }
121 |
122 | $index++;
123 | }
124 |
125 | $table->render();
126 | }
127 |
128 | protected function renderConnection(array $config)
129 | {
130 | $this->output->writeln('Connection');
131 |
132 | $table = new Table($this->output);
133 |
134 | $table->addRow(['endpoint', $config['endpoint']]);
135 | $table->addRow(['token', $config['token']]);
136 |
137 | $table->addRow(new TableSeparator());
138 | $table->addRow(['ConnectionStatus', $this->connectionTest()]);
139 | $table->addRow(['Authorization', $this->authTest()]);
140 |
141 | $table->render();
142 | }
143 |
144 | protected function connectionTest()
145 | {
146 | $connectionTest = $this->client->send(
147 | Client\Actions::ACTION_API_TEST,
148 | [],
149 | null
150 | );
151 |
152 | if ($connectionTest->getStatus()) {
153 | $statusMessage = 'Ok';
154 | } else {
155 | $statusMessage = '' . $connectionTest->getError() . '';
156 | }
157 |
158 | return $statusMessage;
159 | }
160 |
161 | protected function authTest()
162 | {
163 | $authTest = $this->client->send(
164 | Client\Actions::ACTION_AUTH_TEST,
165 | [],
166 | null
167 | );
168 |
169 | if ($authTest->getStatus()) {
170 | $statusMessage = 'Ok - User: ' . $authTest->getData()['user'] . '';
171 | } else {
172 | $statusMessage = '' . $authTest->getError() . '';
173 | }
174 |
175 | return $statusMessage;
176 | }
177 |
178 | }
179 |
--------------------------------------------------------------------------------
/Command/MessageCommand.php:
--------------------------------------------------------------------------------
1 | messenger = $messenger;
19 | parent::__construct();
20 | }
21 |
22 | protected function configure()
23 | {
24 | $this
25 | ->setName(static::$defaultName)
26 | ->setDescription('Sending a Message to a Channel or User')
27 | ->addArgument('channel', InputArgument::REQUIRED, 'an existing channel in your team to send to')
28 | ->addArgument('username', InputArgument::REQUIRED, 'an username from configured identities to send with')
29 | ->addArgument('message', InputArgument::REQUIRED, 'the message to send');
30 | }
31 |
32 | protected function execute(InputInterface $input, OutputInterface $output)
33 | {
34 | try {
35 | $response = $this->messenger->message(
36 | $input->getArgument('channel'),
37 | $input->getArgument('message'),
38 | $input->getArgument('username')
39 | );
40 |
41 | if ($response->getStatus() === false) {
42 | $output->writeln('✘ request got an error from slack: "' . $response->getError() . '"');
43 | return;
44 | }
45 |
46 | $output->writeln('✔ message was sent to ' . $input->getArgument('channel') . '');
47 | } catch (\Exception $e) {
48 | $output->writeln('✘ there was an error while sending message: "' . $e->getMessage() . '"');
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Command/UsersCommand.php:
--------------------------------------------------------------------------------
1 | api = $users;
24 | parent::__construct();
25 | }
26 |
27 | protected function configure()
28 | {
29 | $this
30 | ->setName(static::$defaultName)
31 | ->setDescription('work with the users of your team')
32 | ->addOption('only-active', 'a', InputOption::VALUE_NONE, 'lists only active users')
33 | ->addOption('only-deleted', 'd', InputOption::VALUE_NONE, 'lists only deleted users')
34 | ->addOption('user', 'u', InputOption::VALUE_REQUIRED, 'get a single user');
35 | }
36 |
37 | protected function execute(InputInterface $input, OutputInterface $output)
38 | {
39 | $formatter = $this->getHelper('formatter');
40 |
41 | try {
42 | if ($input->getOption('only-active')) {
43 | $response = $this->api->getActiveUsers();
44 | } elseif ($input->getOption('only-deleted')) {
45 | $response = $this->api->getDeletedUsers();
46 | } elseif ($input->getOption('user')) {
47 | $response = $this->api->getUser($input->getOption('user'));
48 |
49 | if (is_array($response)) {
50 | $response = [$response['name'] => $response];
51 | }
52 | } else {
53 | $response = $this->api->getUsers();
54 | }
55 |
56 | if (empty($response)) {
57 | $output->writeln($formatter->formatBlock('✘ no data found', 'error'));
58 | return;
59 | }
60 |
61 | array_walk(
62 | $response,
63 | function (&$row) {
64 | foreach ($row as &$col) {
65 | if (is_bool($col)) {
66 | $col = $col ? 'true' : 'false';
67 | }
68 | }
69 | }
70 | );
71 |
72 | $table = new Table($output);
73 | $table->setHeaders(array_keys(reset($response)))->setRows($response);
74 | $table->render($output);
75 |
76 | } catch (\Exception $e) {
77 | $output->writeln(
78 | $formatter->formatBlock(
79 | sprintf('✘ there was an error with your request: "%s"', $e->getMessage()),
80 | 'error'
81 | )
82 | );
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/DZunkeSlackBundle.php:
--------------------------------------------------------------------------------
1 | root('d_zunke_slack');
19 | $rootNode->children()
20 | ->scalarNode('endpoint')
21 | ->defaultValue('https://slack.com/api')
22 | ->end()
23 | ->scalarNode('token')
24 | ->isRequired()
25 | ->defaultNull()
26 | ->cannotBeEmpty()
27 | ->end()
28 | ->integerNode('limit_retries')
29 | ->defaultValue(3)
30 | ->min(1)
31 | ->info('The amount of retries for the connection if the Rate Limits of Slack are reached')
32 | ->end()
33 | ->booleanNode('verify_ssl')
34 | ->defaultTrue()
35 | ->end()
36 | ->booleanNode('use_http_post')
37 | ->defaultFalse()
38 | ->end()
39 | ->end();
40 |
41 | $rootNode->append($this->addIdentities());
42 |
43 | return $treeBuilder;
44 | }
45 |
46 | /**
47 | * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
48 | */
49 | private function addIdentities()
50 | {
51 | $treeBuilder = new TreeBuilder();
52 | $node = $treeBuilder->root('identities');
53 |
54 | /** @var $connectionNode ArrayNodeDefinition */
55 | $microservicesNode = $node->requiresAtLeastOneElement()
56 | ->useAttributeAsKey('username')
57 | ->info('Usernames to use for Communication inside the Messaging')
58 | ->prototype('array');
59 |
60 |
61 | $microservicesNode
62 | ->children()
63 | ->scalarNode('icon_url')
64 | ->defaultNull()
65 | ->info('An Url to a specific picture to use as Icon, be sure no emoji is set')
66 | ->end()
67 | ->scalarNode('icon_emoji')
68 | ->defaultNull()
69 | ->info('The Icon to use from an emoji like :smile:')
70 | ->end()
71 | ->end();
72 |
73 | return $node;
74 | }
75 |
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/DependencyInjection/DZunkeSlackExtension.php:
--------------------------------------------------------------------------------
1 | getConfiguration($configs, $container);
20 | $config = $this->processConfiguration($configuration, $configs);
21 |
22 | $container->setParameter('d_zunke_slack.config', $config);
23 |
24 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
25 | $loader->load('services.yml');
26 |
27 | $this->configureSlackIdentityBag($config, $container);
28 | $this->configureSlackConnection($config, $container);
29 | }
30 |
31 | /**
32 | * @param array $config
33 | * @param ContainerBuilder $container
34 | */
35 | protected function configureSlackIdentityBag(array $config, ContainerBuilder $container)
36 | {
37 | $definition = $container->getDefinition('dz.slack.identity_bag');
38 |
39 | $definition->addMethodCall('createIdentities', [$config['identities']]);
40 | }
41 |
42 | /**
43 | * @param array $config
44 | * @param ContainerBuilder $container
45 | */
46 | protected function configureSlackConnection(array $config, ContainerBuilder $container)
47 | {
48 | $definition = $container->getDefinition('dz.slack.connection');
49 |
50 | $definition->addMethodCall('setEndpoint', [$config['endpoint']]);
51 | $definition->addMethodCall('setToken', [$config['token']]);
52 | $definition->addMethodCall('setLimitRetries', [$config['limit_retries']]);
53 | $definition->addMethodCall('setVerifySsl', [$config['verify_ssl']]);
54 |
55 | if ($config['use_http_post'] === true) {
56 | $definition->addMethodCall('isHttpPostMethod');
57 | }
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/Event.php:
--------------------------------------------------------------------------------
1 | message = $message;
22 | }
23 |
24 | /**
25 | * @return Message
26 | */
27 | public function getMessage()
28 | {
29 | return $this->message;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Denis Zunke
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Monolog/Handler/SlackHandler.php:
--------------------------------------------------------------------------------
1 | messagingClient = $messaging;
39 | $this->channel = $channel;
40 | $this->username = $username;
41 |
42 | if (!$this->messagingClient->getIdentityBag()->has($username)) {
43 | throw new \InvalidArgumentException('Invalid Username given');
44 | }
45 |
46 | parent::__construct($level, $bubble);
47 | }
48 |
49 | protected function write(array $record)
50 | {
51 | $attachment = new MessageAttachment();
52 |
53 | switch($record['level']) {
54 | case Logger::DEBUG:
55 | case Logger::INFO:
56 | $attachment->setColor('good');
57 | break;
58 | case Logger::NOTICE:
59 | case Logger::WARNING:
60 | $attachment->setColor('warning');
61 | break;
62 | case Logger::ERROR:
63 | case Logger::CRITICAL:
64 | case Logger::ALERT:
65 | case Logger::EMERGENCY:
66 | $attachment->setColor('danger');
67 | break;
68 | }
69 |
70 | $attachment->addField($record['level_name'], $record['formatted']);
71 |
72 | $this->messagingClient->message($this->channel, '', $this->username, [$attachment]);
73 | }
74 |
75 | /**
76 | * {@inheritDoc}
77 | */
78 | protected function getDefaultFormatter()
79 | {
80 | return new LineFormatter();
81 | }
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## PROJECT ARCHIVED
2 |
3 | You may want to use the symfony notifier component which can also send messages to slack -> More Information here: https://symfony.com/doc/current/notifier.html
4 |
5 |
6 | ---
7 |
8 | ## Symfony SlackBundle [](https://packagist.org/packages/dzunke/slack-bundle)
9 |
10 | [](https://www.versioneye.com/user/projects/53f7cb30e09da3d0bf00047b) [](https://insight.sensiolabs.com/projects/12c02e49-a1a8-42f7-a213-71d4288fc75d) [](https://packagist.org/packages/dzunke/slack-bundle) [](https://packagist.org/packages/dzunke/slack-bundle)
11 |
12 | The Bundle will integrate [Slack](https://slack.com/) Team-Communication-Software into your Symfony2 Project and in the future will deliver a set of Project-Management-Tools to use between your Symfony-Project and Slack.
13 |
14 | ## Documentation
15 |
16 | Please check the [Documentation](Resources/doc/index.md) for Help and Informations about the Usage of the Bundle. There is also a [Roadmap](Resources/doc/roadmap.md) available.
17 |
18 | ## License
19 |
20 | SlackBundle is licensed under the MIT license.
21 |
--------------------------------------------------------------------------------
/Resources/config/services.yml:
--------------------------------------------------------------------------------
1 | services:
2 |
3 | dz.slack.identity_bag:
4 | class: DZunke\SlackBundle\Slack\Messaging\IdentityBag
5 | public: true
6 |
7 | dz.slack.connection:
8 | class: DZunke\SlackBundle\Slack\Client\Connection
9 | public: true
10 |
11 | dz.slack.client:
12 | class: DZunke\SlackBundle\Slack\Client
13 | public: true
14 | arguments: ["@dz.slack.connection"]
15 |
16 | dz.slack.messaging:
17 | class: DZunke\SlackBundle\Slack\Messaging
18 | public: true
19 | arguments: ["@dz.slack.client", "@dz.slack.identity_bag"]
20 |
21 | dz.slack.channels:
22 | class: DZunke\SlackBundle\Slack\Channels
23 | public: true
24 | arguments: ["@dz.slack.client"]
25 |
26 | dz.slack.users:
27 | class: DZunke\SlackBundle\Slack\Users
28 | public: true
29 | arguments: ["@dz.slack.client"]
30 |
31 | DZunke\SlackBundle\Slack\Messaging\IdentityBag: '@dz.slack.identity_bag'
32 |
33 | DZunke\SlackBundle\Slack\Client\Connection: '@dz.slack.connection'
34 |
35 | DZunke\SlackBundle\Slack\Client: '@dz.slack.client'
36 |
37 | DZunke\SlackBundle\Slack\Messaging: '@dz.slack.messaging'
38 |
39 | DZunke\SlackBundle\Slack\Channels: '@dz.slack.channels'
40 |
41 | DZunke\SlackBundle\Slack\Users: '@dz.slack.users'
42 |
43 | DZunke\SlackBundle\Command\BotMessagingCommand:
44 | class: DZunke\SlackBundle\Command\BotMessagingCommand
45 | arguments: ["@dz.slack.channels", "@event_dispatcher"]
46 | tags:
47 | - { name: console.command, command: slack:run-bot }
48 |
49 | DZunke\SlackBundle\Command\ChangeChannelsTopicCommand:
50 | class: DZunke\SlackBundle\Command\ChangeChannelsTopicCommand
51 | arguments: ["@dz.slack.channels"]
52 | tags:
53 | - { name: console.command, command: slack:channels:topic }
54 |
55 | DZunke\SlackBundle\Command\DebugCommand:
56 | class: DZunke\SlackBundle\Command\DebugCommand
57 | arguments: ["@dz.slack.client"]
58 | tags:
59 | - { name: console.command, command: slack:debug }
60 |
61 | DZunke\SlackBundle\Command\MessageCommand:
62 | class: DZunke\SlackBundle\Command\MessageCommand
63 | arguments: ["@dz.slack.messaging"]
64 | tags:
65 | - { name: console.command, command: slack:message }
66 |
67 | DZunke\SlackBundle\Command\UsersCommand:
68 | class: DZunke\SlackBundle\Command\UsersCommand
69 | arguments: ["@dz.slack.users"]
70 | tags:
71 | - { name: console.command, command: slack:users }
72 |
--------------------------------------------------------------------------------
/Resources/doc/actions-list.md:
--------------------------------------------------------------------------------
1 | # Available Actions for Basic Usage
2 |
3 | ## api.test
4 |
5 | [Slack Documentation](https://api.slack.com/methods/api.test)
6 |
7 | Constant: \DZunke\SlackBundle\Slack\Client::ACTION_API_TEST
8 |
9 | Available Parameters:
10 |
11 | ``` php
12 | protected $parameter = [];
13 | ```
14 |
15 | ## auth.test
16 |
17 | [Slack Documentation](https://api.slack.com/methods/auth.test)
18 |
19 | Constant: \DZunke\SlackBundle\Slack\Client::ACTION_AUTH_TEST
20 |
21 | Available Parameters:
22 |
23 | ``` php
24 | protected $parameter = [];
25 | ```
26 |
27 | ## channels.create
28 |
29 | [Slack Documentation](https://api.slack.com/methods/channels.create)
30 |
31 | Constant: \DZunke\SlackBundle\Slack\Client::ACTION_CHANNELS_CREATE
32 |
33 | Available Parameters:
34 |
35 | ``` php
36 | protected $parameter = [
37 | 'name' => null
38 | ];
39 | ```
40 |
41 | ## channels.info
42 |
43 | [Slack Documentation](https://api.slack.com/methods/channels.info)
44 |
45 | Constant: \DZunke\SlackBundle\Slack\Client::ACTION_CHANNELS_INFO
46 |
47 | Available Parameters:
48 |
49 | ``` php
50 | protected $parameter = [
51 | 'channel' => null
52 | ];
53 | ```
54 |
55 | ## channels.invite
56 |
57 | [Slack Documentation](https://api.slack.com/methods/channels.invite)
58 |
59 | Constant: \DZunke\SlackBundle\Slack\Client::ACTION_CHANNELS_INVITE
60 |
61 | Available Parameters:
62 |
63 | Both Parameters have to be the if of the entity and not the raw name
64 |
65 | ``` php
66 | protected $parameter = [
67 | 'channel' => null,
68 | 'user' => null,
69 | ];
70 | ```
71 |
72 | ## channels.list
73 |
74 | [Slack Documentation](https://api.slack.com/methods/channels.list)
75 |
76 | Constant: \DZunke\SlackBundle\Slack\Client::ACTION_CHANNELS_LIST
77 |
78 | Available Parameters:
79 |
80 | ``` php
81 | protected $parameter = [
82 | 'exclude_archived' => 1
83 | ];
84 | ```
85 |
86 | ## channels.setTopic
87 |
88 | [Slack Documentation](https://api.slack.com/methods/channels.setTopic)
89 |
90 | Constant: \DZunke\SlackBundle\Slack\Client::ACTION_CHANNELS_SET_TOPIC
91 |
92 | Available Parameters:
93 |
94 | ``` php
95 | protected $parameter = [
96 | 'channel' => null,
97 | 'topic' => null
98 | ];
99 | ```
100 |
101 | ## chat.postMessage
102 |
103 | [Slack Documentation](https://api.slack.com/methods/chat.postMessage)
104 |
105 | Constant: \DZunke\SlackBundle\Slack\Client::ACTION_POST_MESSAGE
106 |
107 | Available Parameters:
108 |
109 | ``` php
110 | protected $parameter = [
111 | 'identity' => null, # Object of Class \DZunke\SlackBundle\Slack\Messaging\Identity
112 | 'channel' => null,
113 | 'text' => null,
114 | 'icon_url' => null, # only one of icon_url or icon_emoji could be used
115 | 'icon_emoji' => null,
116 | 'parse' => 'full',
117 | 'link_names' => 1,
118 | 'unfurl_links' => 1,
119 | 'attachments' => []
120 | ];
121 | ```
122 |
123 | ## files.upload
124 |
125 | [Slack Documentation](https://api.slack.com/methods/files.upload)
126 |
127 | Constant: \DZunke\SlackBundle\Slack\Client::ACTION_FILES_UPLOAD
128 |
129 | ``` php
130 | protected $parameter = [
131 | 'content' => null,
132 | 'filetype' => null,
133 | 'filename' => null,
134 | 'title' => null,
135 | 'initial_comment' => null,
136 | 'channels' => null # If no Channel is given the File will be private to the API-User
137 | ];
138 | ```
139 |
140 | ## users.list
141 |
142 | [Slack Documentation](https://api.slack.com/methods/users.list)
143 |
144 | Constant: \DZunke\SlackBundle\Slack\Client::ACTION_USERS_LIST
145 |
146 | ``` php
147 | protected $parameter = [
148 | 'presence' => 1
149 | ];
150 | ```
151 |
--------------------------------------------------------------------------------
/Resources/doc/basic-usage.md:
--------------------------------------------------------------------------------
1 | # Basic Usage without Symfony Integration
2 |
3 | The Basic-Integration of Slack in this Bundle is usable without Symfony.
4 |
5 | ``` php
6 | $identity = new \DZunke\SlackBundle\Slack\Messaging\Identity();
7 | $identity->setUsername('CoffeeBrewer');
8 | $identity->setIconEmoji(':coffee:');
9 |
10 | $connection = new \DZunke\SlackBundle\Slack\Client\Connection();
11 | $connection->setEndpoint('slack.com/api/');
12 | $connection->setToken('YOUR API TOKEN');
13 |
14 | # Switch from GET to POST Method
15 | # $connection->isHttpPostMethod();
16 |
17 | $client = new \DZunke\SlackBundle\Slack\Client($connection);
18 |
19 | $response = $client->send(
20 | \DZunke\SlackBundle\Slack\Client\Actions::ACTION_POST_MESSAGE,
21 | [
22 | 'identity' => $identity,
23 | 'channel' => '#slack-testing',
24 | 'text' => 'Good Morning, please make sure u got a coffee before working!'
25 | ]
26 | );
27 | ```
28 |
--------------------------------------------------------------------------------
/Resources/doc/commands.md:
--------------------------------------------------------------------------------
1 | # Commands
2 |
3 | ## Debugging
4 |
5 | Output of Debug Informations like Connection, Identities, Channels etc.
6 |
7 | ``` bash
8 | php app/console slack:debug
9 | ```
10 |
11 | ## Messaging
12 |
13 | Sending a Message directly from Console
14 |
15 | ``` bash
16 | php app/console slack:message @fooUser BazUser "Lorem ipsum dolor sit amet .."
17 | php app/console slack:message "#FooChannel" BazUser "Lorem ipsum dolor sit amet .."
18 | ```
19 |
20 | ## Switch Topic of a Channel
21 |
22 | You can switch the Topic of a Channel
23 |
24 | ``` bash
25 | php app/console slack:channels:topic "C02GABTDT" "Lorem ipsum dolor sit amet .."
26 |
27 | # If you don't have the ChannelId it must be discovered while processing
28 | php app/console slack:channels:topic "#foo-channel" "Lorem ipsum dolor sit amet .." -d
29 | ```
30 |
31 | ## Read userdata from api
32 |
33 | you will get a table of userdata.
34 |
35 | ``` bash
36 | # Read all users from your team
37 | php app/console slack:users
38 |
39 | # Read a single user
40 | php app/console slack:users --user=nameOfTheUser
41 | ```
42 |
--------------------------------------------------------------------------------
/Resources/doc/configuration.md:
--------------------------------------------------------------------------------
1 | # Configuration Reference
2 |
3 | ``` yaml
4 | d_zunke_slack:
5 | endpoint: slack.com/api/
6 | token: null # Required
7 | verify_ssl: true # ssl verification at guzzle client
8 | use_http_post: false # give the ability to send request as HTTP POST
9 |
10 | # The amount of retries for the connection if the Rate Limits of Slack are reached
11 | limit_retries: 3
12 |
13 | # Usernames to use for Communication inside the Messaging
14 | identities:
15 |
16 | # Prototype
17 | username:
18 |
19 | # An Url to a specific picture to use as Icon
20 | icon_url: null
21 |
22 | # The Icon to use from an emoji like :smile:
23 | icon_emoji: null
24 |
25 | ```
26 |
--------------------------------------------------------------------------------
/Resources/doc/index.md:
--------------------------------------------------------------------------------
1 | # SlackBundle Documentation
2 |
3 | 1. [Installation](installation.md)
4 |
5 | 2. [Configuration Reference](configuration.md)
6 |
7 | 3. [Basic Usage without Symfony Integration](basic-usage.md)
8 | 4. [Basic Usage in Symfony](symfony-usage.md)
9 | 5. [Available Actions for Basic Usage](actions-list.md)
10 |
11 | 6. [Services](services.md)
12 | 7. [Commands](commands.md)
13 | 8. [Monolog Integration](monolog.md)
14 |
15 | 9. [Silex Integration](silex.md)
16 |
17 | 10. [Help for Slack](slack.md)
18 |
--------------------------------------------------------------------------------
/Resources/doc/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | ## 1. Install the Bundle
4 |
5 | You can add the Bundle by running [Composer](http://getcomposer.org) on your shell or adding it directly to your composer.json
6 |
7 | ``` bash
8 | php composer.phar require dzunke/slack-bundle:dev-master
9 | ```
10 |
11 | ``` json
12 | "require" : {
13 | "dzunke/slack-bundle": "dev-master"
14 | }
15 | ```
16 |
17 | ## 2. Register the Bundle to Symfony
18 |
19 | The Namespace will be registered by autoloading with Composer but to use the integrated features for symfony you have to register the Bundle.
20 |
21 | ``` php
22 | # app/AppKernel.php
23 | public function registerBundles()
24 | {
25 | $bundles = [
26 | // [..]
27 | new DZunke\SlackBundle\DZunkeSlackBundle(),
28 | ];
29 | }
30 | ```
31 |
32 | ## 3. Add the Configuration for the Bundle
33 |
34 | To use the Bundle without an Error you have to add the Connection-Data and finally one Identity to use with the Methods like MonologHandler or Messaging.
35 |
36 | ``` yaml
37 | # app/config/config.yml
38 | d_zunke_slack:
39 | token: "YOUR AUTH-TOKEN"
40 | identities:
41 | CoffeeBrewer: ~
42 | ```
43 |
44 |
--------------------------------------------------------------------------------
/Resources/doc/monolog.md:
--------------------------------------------------------------------------------
1 | # Monolog Integration
2 |
3 | **Please only use this Log-Handler for Errors or Criticals**
4 |
5 | In a first step you have to create a custom service for the Handler. In this Service you can define Channel and Username to work with. The Username must be registered in the [Configuration](configuration.md) to be usable otherwise you'll get an Exception.
6 |
7 | ``` yaml
8 | # app/config.yml
9 | services:
10 | my_custom_handler:
11 | class: DZunke\SlackBundle\Monolog\Handler\SlackHandler
12 | # 400 = ERROR, see Monolog::Logger for the values of log levels
13 | arguments: [@dz.slack.messaging, "#foo-channel", "bazuser", 400]
14 | ```
15 |
16 | You can create a bunch of Handlers. To Register the Handler to the Main-Logging of Symfony you'll have to add the new Service to the Monolog Configuration.
17 |
18 | ``` yaml
19 | # app/config.yml
20 | monolog:
21 | handlers:
22 | slack:
23 | type: service
24 | id: my_custom_handler
25 | ```
26 |
--------------------------------------------------------------------------------
/Resources/doc/roadmap.md:
--------------------------------------------------------------------------------
1 | # Roadmap
2 |
3 | To view a bit into the future there are some ideas for features and the will to implement them. The long term Target is to create a Set of Project-Management Features to make the daily work easier and use the full capacity of the gorgeous Slack-System.
4 |
5 | * Upload Files
6 | * Connectors for extern Tools to fetch Data and post them (maybe with a cache to only get updated content)
7 | * "iDoneThis" for Slack-Chat (Checking if it is possible with the API)
8 |
9 |
10 | The following Features could not be implemented yet because of problems with the API of Slack.
11 |
12 | * Update ChatMessage for ProgressBars etc.
13 |
--------------------------------------------------------------------------------
/Resources/doc/services.md:
--------------------------------------------------------------------------------
1 | # Services
2 |
3 | ## Messaging
4 |
5 | Sending Messages to Channel, Group or User without the need of knowing the Client
6 |
7 | ``` php
8 | $response = $container->get('dz.slack.messaging')->message(
9 | '#foo-channel',
10 | 'Good Morning, please make sure u got a coffee before working!',
11 | 'CoffeeBrewer'
12 | );
13 | ```
14 |
15 | There is also a way to use the "Attachment"-Feature of Slack. In this Case there will be a multi-column part below the Message.
16 | For this you must create deliver an Array of Attachments to the Message-Method.
17 |
18 | ``` php
19 | $attachment = new DZunke\SlackBundle\Slack\Entity\MessageAttachment();
20 | $attachment->setColor('danger');
21 | $attachment->addField('Test1', 'Test works');
22 |
23 | $response = $container->get('dz.slack.messaging')->message(
24 | '#foo-channel',
25 | 'Good Morning, please make sure u got a coffee before working!',
26 | 'CoffeeBrewer',
27 | [$attachment]
28 | );
29 | ```
30 |
31 | ### File Uploads
32 |
33 | The Messaging does include File Uploads. So the Service has an "upload"-Method to publish Reports or other Files to a Channel.
34 | You must note that every uploaded File will be associated with the API-Key-User configured for your Slack-Client.
35 |
36 | ``` php
37 | $response = $container->get('dz.slack.messaging')->upload(
38 | '#foo-channel',
39 | 'Title for this File',
40 | '/Path/to/the/file',
41 | 'Optional Comment'
42 | );
43 | ```
44 |
45 | ## Channels
46 |
47 | There are some operations you can do for a Channel. It is necessary to get the ChannelId from the Slack-API before you
48 | can do the Actions. If you do not have the Channel Ids you can execute the Debug-Command or simply execute getId() of
49 | this Service.
50 |
51 |
52 | ``` php
53 | $service = $container->get('dz.slack.channels');
54 |
55 | # get the specific id of a channel
56 | $service->getId($channelName);
57 |
58 | # list all available channels in your team
59 | $service->listAll();
60 |
61 | # creates a channel
62 | $service->create($name);
63 |
64 | # get information about just a single channel
65 | $service->info($channelId);
66 |
67 | # set the topic of a channel
68 | $service->setTopic($channelId, $newTopic);
69 | ```
70 |
71 | ## Users
72 |
73 | To get more information about the users in your team there is a service to read user specific things. In lack of an
74 | api method to load single users every method of the service will load the complete list of users in your team. Beware
75 | of using this service without caching informations you often need.
76 |
77 | ``` php
78 | $service = $container->get('dz.slack.users');
79 |
80 | # get the list of all users in your team
81 | $service->getUsers();
82 |
83 | # get all users that are not deleted
84 | $service->getActiveUsers();
85 |
86 | # get all deleted users
87 | $service->getDeletedUsers();
88 |
89 | # get the id of a single user - needed for some actions
90 | $service->getId($username);
91 |
92 | ```
93 |
--------------------------------------------------------------------------------
/Resources/doc/silex.md:
--------------------------------------------------------------------------------
1 | # Silex Integration
2 |
3 | In the Bundle there is a SilexProvider you can use with your Silex-Application. There is no need to get an extra Package. The Provider delivers the following Extensions:
4 |
5 | $app['dz.slack.connection'] # Slack/Client/Connection.php
6 | $app['dz.slack.client'] # Slack/Client.php
7 | $app['dz.slack.identity_bag'] # Slack/Messaging/IdentityBag.php
8 | $app['dz.slack.messaging'] # Slack/Messaging.php
9 |
10 | To configure the SlackBundle in Silex there is the need to set some Configuration-Values
11 |
12 | ``` php
13 | $app['dz.slack.options'] = [
14 | 'token' => 'YOUR TOKEN HERE,
15 | 'identities' => [
16 | 'YOUR IDENTITIY' => []
17 | ],
18 | 'logging' => [
19 | 'enabled' => true,
20 | 'channel' => 'YOUR CHANNEL TO LOG TO',
21 | 'identity' => 'THE IDENTITY TO LOG WITH'
22 | ]
23 | ];
24 | ```
25 |
26 | Wit these Options set you can load the Provider in your index
27 |
28 | ``` php
29 | $app->register(new DZunke\SlackBundle\Silex\Provider\SlackServiceProvider());
30 | ```
31 |
32 | ## Monolog Integration
33 |
34 | If you want to integrate the SlackHandler to an Instance of Monolog be sure the logging is enabled in the config. In that case the Provider will try to add the Handler to the default Logger ```$app['monolog']```. It will use the same LogLevel as the default Logger.
35 |
36 | Be sure that the MonologProvider is handled before!
37 |
--------------------------------------------------------------------------------
/Resources/doc/slack.md:
--------------------------------------------------------------------------------
1 | # Help for Slack
2 |
3 | ## Token
4 |
5 | To get your Token you need to be logged in into the Slack-System and visit the [API-Page](https://api.slack.com/).
6 | There is a headline "Authentication" where your Team should be listet with the possibility to get a Token.
7 |
8 | **Note:** The API-Token is linked to the user who redeems it. Maybe there should be a "System"-User in your Team for this purposes.
9 |
10 | ## Formatting Messages
11 |
12 | There are some useful help for how you can format messages.
13 |
14 | * [Enabled Markdown](https://slack.zendesk.com/hc/en-us/articles/202288908-How-can-I-add-formatting-to-my-messages-)
15 | * [Emoji Cheat Sheet](http://www.emoji-cheat-sheet.com/)
16 |
17 | ## Notifications
18 |
19 | To call Notifications for a User. First it must be enabled for the User. There are some Ways to notify:
20 |
21 | * Message: _"Foo @everyone Bar"_, will notify everyone in at the Network. Must be Used on the #general Channel
22 | * Message: _"Foo @channel Bar"_, will notify everyone in a Channel
23 | * Message: _"Foo @Bazuser Bar"_, will notify the named User
24 |
25 | ## Rate-Limit
26 |
27 | Officially the Slack-API has a [Rate Limit](https://api.slack.com/docs/rate-limits) for Requests. The API only allows
28 | one Request per Second. For short times the API will ignore if you get over this limit but maybe there comes a time
29 | the API will give an Error for this. In this Case the Client will automatically try it for two more times. If you want
30 | to raise this loop of tries you can change it in the [Configuration](configuration.md).
31 |
--------------------------------------------------------------------------------
/Resources/doc/symfony-usage.md:
--------------------------------------------------------------------------------
1 | # Basic Usage in Symfony
2 |
3 | If you followed the Setup you will have a bunch of services registered. For the Basic-Usage you only need the Client to execute all the Actions the Client has implemented.
4 |
5 | ``` php
6 | # AcmeBundle/IndexController.php
7 | public function messageAction()
8 | {
9 | $client = $this->get('dz.slack.client');
10 | $response = $client->send(
11 | \DZunke\SlackBundle\Slack\Client\Actions::ACTION_POST_MESSAGE,
12 | [
13 | 'identity' => $this->get('dz.slack.identity_bag')->get('CoffeeBrewer'),
14 | 'channel' => '#slack-testing',
15 | 'text' => 'Good Morning, please make sure u got a coffee before working!'
16 | ]
17 | );
18 | }
19 | ```
20 |
--------------------------------------------------------------------------------
/Silex/Provider/SlackServiceProvider.php:
--------------------------------------------------------------------------------
1 | 'slack.com/api/',
19 | 'token' => null,
20 | 'limit_retries' => 5,
21 | 'identities' => [
22 | 'Silex' => []
23 | ],
24 | 'logging' => [
25 | 'enabled' => false,
26 | 'channel' => '',
27 | 'identity' => ''
28 | ]
29 | ];
30 |
31 | if (isset($app['dz.slack.options'])) {
32 | $app['dz.slack.options'] = array_merge($default_options, $app['dz.slack.options']);
33 | } else {
34 | $app['dz.slack.options'] = $default_options;
35 | }
36 |
37 | $app['dz.slack.identity_bag'] = $app->share(
38 | function ($app) {
39 | $identityBag = new Messaging\IdentityBag();
40 | $identityBag->createIdentities($app['dz.slack.options']['identities']);
41 |
42 | return $identityBag;
43 | }
44 | );
45 |
46 | $app['dz.slack.connection'] = $app->share(
47 | function ($app) {
48 | $connection = new Client\Connection();
49 | $connection->setEndpoint($app['dz.slack.options']['endpoint']);
50 | $connection->setLimitRetries($app['dz.slack.options']['limit_retries']);
51 | $connection->setToken($app['dz.slack.options']['token']);
52 |
53 | return $connection;
54 | }
55 | );
56 |
57 | $app['dz.slack.client'] = $app->share(
58 | function ($app) {
59 | return new Client($app['dz.slack.connection']);
60 | }
61 | );
62 |
63 | $app['dz.slack.messaging'] = $app->share(
64 | function ($app) {
65 | return new Messaging($app['dz.slack.client'], $app['dz.slack.identity_bag']);
66 | }
67 | );
68 |
69 | if ($app['dz.slack.options']['logging']['enabled']) {
70 |
71 | $app['monolog.handler.slack'] = $app->share(
72 | function ($app) {
73 | $level = MonologServiceProvider::translateLevel($app['monolog.level']);
74 |
75 | return new SlackHandler(
76 | $app['dz.slack.messaging'],
77 | $app['dz.slack.options']['logging']['channel'],
78 | $app['dz.slack.options']['logging']['identity'],
79 | $level
80 | );
81 | }
82 | );
83 |
84 | $app['monolog']->pushHandler($app['monolog.handler.slack']);
85 |
86 | }
87 | }
88 |
89 | public function boot(Application $app)
90 | {
91 |
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/Slack/Channels.php:
--------------------------------------------------------------------------------
1 | client = $client;
23 | }
24 |
25 | /**
26 | * @return Client
27 | */
28 | public function getClient()
29 | {
30 | return $this->client;
31 | }
32 |
33 | /**
34 | * @param string $channelName
35 | * @return string
36 | */
37 | public function getId($channelName)
38 | {
39 | if ($channelName[0] === 'C') {
40 | return $channelName;
41 | }
42 |
43 | if (strpos($channelName, '#') !== false) {
44 | $channelName = str_replace('#', '', $channelName);
45 | }
46 |
47 | foreach ((array)$this->listAll()->getData() as $name => $data) {
48 | if ($name == $channelName) {
49 | return $data['id'];
50 | }
51 | }
52 |
53 | return '';
54 | }
55 |
56 | /**
57 | * @return Client\Response|bool
58 | */
59 | public function listAll()
60 | {
61 | return $this->client->send(
62 | Actions::ACTION_CHANNELS_LIST,
63 | []
64 | );
65 | }
66 |
67 | /**
68 | * @param string $channel The Id of the Channel - NOT the Name. self::getId() if needed
69 | * @return Client\Response|bool
70 | */
71 | public function info($channel)
72 | {
73 | return $this->client->send(
74 | Actions::ACTION_CHANNELS_INFO,
75 | [
76 | 'channel' => (string)$channel
77 | ]
78 | );
79 | }
80 |
81 | /**
82 | * @param string $name
83 | *
84 | * @return bool|Client\Response
85 | */
86 | public function create($name)
87 | {
88 | return $this->client->send(
89 | Actions::ACTION_CHANNELS_CREATE,
90 | [
91 | 'name' => trim($name)
92 | ]
93 | );
94 | }
95 |
96 | /**
97 | * @param string $channel The Id of the Channel - NOT the Name. self::getId() if needed
98 | * @param string $topic
99 | * @return $this|Client\Response|bool
100 | */
101 | public function setTopic($channel, $topic)
102 | {
103 | $channelInfo = $this->info($channel)->getData();
104 |
105 | $response = $this->client->send(
106 | Actions::ACTION_CHANNELS_SET_TOPIC,
107 | [
108 | 'channel' => (string)$channel,
109 | 'topic' => (string)$topic
110 | ]
111 | );
112 |
113 | if (!$response->getStatus()) {
114 | return $response;
115 | }
116 |
117 | $data = $response->getData();
118 | $data['old_topic'] = $channelInfo['topic'];
119 | $data['new_topic'] = (string)$topic;
120 |
121 | return $response->setData($data);
122 | }
123 |
124 | /**
125 | * @param string $channel
126 | * @param int $from
127 | * @param int $count
128 | * @return Message[]
129 | */
130 | public function history($channel, $from = null, $count = 10)
131 | {
132 | $messages = $this->client->send(
133 | Client\Actions::ACTION_CHANNELS_HISTORY,
134 | [
135 | 'channel' => $this->getId($channel),
136 | 'oldest' => is_null($from) ? time() : $from,
137 | 'count' => $count
138 | ]
139 | );
140 |
141 | $repository = [];
142 | if (!empty($messages->getData()['messages'])) {
143 | $messages = $messages->getData()['messages'];
144 | foreach (array_reverse($messages) as $message) {
145 | $objMsg = new Message();
146 | $objMsg->setId($message['ts']);
147 | $objMsg->setChannel($channel);
148 | $objMsg->setType(isset($message['subtype']) ? $message['subtype'] : $message['type']);
149 | $objMsg->setUserId(isset($message['user']) ? $message['user'] : null);
150 | $objMsg->setUsername(isset($message['username']) ? $message['username'] : null);
151 | $objMsg->setContent($message['text']);
152 |
153 | $repository[] = $objMsg;
154 | }
155 | }
156 |
157 | return $repository;
158 | }
159 |
160 | }
161 |
--------------------------------------------------------------------------------
/Slack/Client.php:
--------------------------------------------------------------------------------
1 | connection = $connection;
26 | }
27 |
28 | /**
29 | * @param string $action
30 | * @param array $parameter
31 | * @param bool $multipart Whether to use multipart/form-data or the default application/x-www-form-urlencoded
32 | *
33 | * @return Response|bool
34 | */
35 | public function send($action, array $parameter = [], $multipart = false)
36 | {
37 | if (!$this->connection->isValid()) {
38 | return false;
39 | }
40 |
41 | $action = Actions::loadClass($action);
42 | $action->setParameter($parameter);
43 |
44 | $parsedRequestParams = array_merge(
45 | ['token' => $this->connection->getToken()],
46 | $action->getRenderedRequestParams()
47 | );
48 |
49 | $url = $this->buildUri($action, $parsedRequestParams);
50 |
51 | $tries = 1;
52 | do {
53 | $response = $this->executeRequest(
54 | $url,
55 | $this->connection->getHttpMethod() === Request::METHOD_POST ? $parsedRequestParams : null,
56 | $multipart
57 | );
58 | $response = Response::parseGuzzleResponse($response, $action);
59 |
60 | if (
61 | $response->getStatus() === true ||
62 | ($response->getStatus() === false && $response->getError() != Response::ERROR_RATE_LIMITED)
63 | ) {
64 | break;
65 | }
66 |
67 | ++$tries;
68 |
69 | } while ($tries <= $this->connection->getLimitRetries());
70 |
71 |
72 | return $response;
73 | }
74 |
75 | /**
76 | * @param Actions\ActionsInterface $action
77 | * @param array $requestParams
78 | *
79 | * @return Uri
80 | */
81 | protected function buildUri(Actions\ActionsInterface $action, array $requestParams)
82 | {
83 | $uri = $this->connection->getEndpoint() . '/' . $action->getAction();
84 |
85 | if ($this->connection->getHttpMethod() === Request::METHOD_GET) {
86 | $uri .= '?' . http_build_query($requestParams);
87 | }
88 |
89 | return new Uri($uri);
90 | }
91 |
92 | /**
93 | * @param Uri $uri
94 | * @param array $params form post values
95 | * @param bool $multipart Whether to use multipart/form-data or the default application/x-www-form-urlencoded
96 | *
97 | * @return \GuzzleHttp\Psr7\Response
98 | */
99 | protected function executeRequest(Uri $uri, array $params = null, $multipart = false)
100 | {
101 | $guzzle = new GuzzleClient(['verify' => $this->connection->getVerifySsl()]);
102 |
103 | if (null !== $params) {
104 | if ($multipart) {
105 | $multipartParams = [];
106 | foreach ($params as $paramName => $paramValue) {
107 | $multipartParams[] = [
108 | 'name' => $paramName,
109 | 'contents' => $paramValue,
110 | ];
111 | }
112 | $postParams = ['multipart' => $multipartParams];
113 | } else {
114 | $postParams = ['form_params' => $params];
115 | }
116 | } else {
117 | $postParams = [];
118 | }
119 |
120 | return $guzzle->request(
121 | $this->connection->getHttpMethod(),
122 | $uri,
123 | $postParams
124 | );
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/Slack/Client/Actions.php:
--------------------------------------------------------------------------------
1 | 'ChatPostMessage',
26 | self::ACTION_CHANNELS_LIST => 'ChannelsList',
27 | self::ACTION_API_TEST => 'ApiTest',
28 | self::ACTION_AUTH_TEST => 'AuthTest',
29 | self::ACTION_CHANNELS_SET_TOPIC => 'ChannelsSetTopic',
30 | self::ACTION_CHANNELS_INFO => 'ChannelsInfo',
31 | self::ACTION_CHANNELS_INVITE => 'ChannelsInvite',
32 | self::ACTION_CHANNELS_HISTORY => 'ChannelsHistory',
33 | self::ACTION_CHANNELS_CREATE => 'ChannelsCreate',
34 | self::ACTION_FILES_UPLOAD => 'FilesUpload',
35 | self::ACTION_USERS_LIST => 'UsersList'
36 | ];
37 |
38 | /**
39 | * @param string $action
40 | * @return ActionsInterface
41 | * @throws \Exception
42 | */
43 | public static function loadClass($action)
44 | {
45 | if (!array_key_exists($action, self::$classes)) {
46 | throw new \Exception('the called action "' . $action . '" does not exist');
47 | }
48 |
49 | $classname = '\\DZunke\\SlackBundle\\Slack\\Client\\Actions\\' . self::$classes[$action];
50 |
51 | return new $classname;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Slack/Client/Actions/ActionsInterface.php:
--------------------------------------------------------------------------------
1 | parameter;
24 | }
25 |
26 | /**
27 | * @param array $parameter
28 | * @return $this
29 | */
30 | public function setParameter(array $parameter)
31 | {
32 | return $this;
33 | }
34 |
35 | /**
36 | * @return string
37 | */
38 | public function getAction()
39 | {
40 | return Actions::ACTION_API_TEST;
41 | }
42 |
43 | /**
44 | * @param array $response
45 | * @return array
46 | */
47 | public function parseResponse(array $response)
48 | {
49 | return [];
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Slack/Client/Actions/AuthTest.php:
--------------------------------------------------------------------------------
1 | parameter;
24 | }
25 |
26 | /**
27 | * @param array $parameter
28 | * @return $this
29 | */
30 | public function setParameter(array $parameter)
31 | {
32 | return $this;
33 | }
34 |
35 | /**
36 | * @return string
37 | */
38 | public function getAction()
39 | {
40 | return Actions::ACTION_AUTH_TEST;
41 | }
42 |
43 | /**
44 | * @param array $response
45 | * @return array
46 | */
47 | public function parseResponse(array $response)
48 | {
49 | return [
50 | 'user' => $response['user']
51 | ];
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Slack/Client/Actions/ChannelsCreate.php:
--------------------------------------------------------------------------------
1 | null
18 | ];
19 |
20 | /**
21 | * @return array
22 | * @throws \Exception
23 | */
24 | public function getRenderedRequestParams()
25 | {
26 | if (is_null($this->parameter['name'])) {
27 | throw new \Exception('the channel name must be given');
28 | }
29 |
30 | return $this->parameter;
31 | }
32 |
33 | /**
34 | * @param array $parameter
35 | * @return $this
36 | */
37 | public function setParameter(array $parameter)
38 | {
39 | foreach ($parameter as $key => $value) {
40 | if (array_key_exists($key, $this->parameter)) {
41 | $this->parameter[$key] = $value;
42 | }
43 | }
44 |
45 | return $this;
46 | }
47 |
48 | /**
49 | * @return string
50 | */
51 | public function getAction()
52 | {
53 | return Actions::ACTION_CHANNELS_CREATE;
54 | }
55 |
56 | /**
57 | * @param array $response
58 | * @return array
59 | */
60 | public function parseResponse(array $response)
61 | {
62 | return $response['channel'];
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Slack/Client/Actions/ChannelsHistory.php:
--------------------------------------------------------------------------------
1 | null,
18 | 'oldest' => null,
19 | 'count' => 10
20 | ];
21 |
22 | /**
23 | * @return array
24 | */
25 | public function getRenderedRequestParams()
26 | {
27 | return $this->parameter;
28 | }
29 |
30 | /**
31 | * @param array $parameter
32 | * @return $this
33 | */
34 | public function setParameter(array $parameter)
35 | {
36 | foreach ($parameter as $key => $value) {
37 | if (array_key_exists($key, $this->parameter)) {
38 | $this->parameter[$key] = $value;
39 | }
40 | }
41 |
42 | return $this;
43 | }
44 |
45 | /**
46 | * @return string
47 | */
48 | public function getAction()
49 | {
50 | return Actions::ACTION_CHANNELS_HISTORY;
51 | }
52 |
53 | /**
54 | * @param array $response
55 | * @return array
56 | */
57 | public function parseResponse(array $response)
58 | {
59 | return $response;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Slack/Client/Actions/ChannelsInfo.php:
--------------------------------------------------------------------------------
1 | null
18 | ];
19 |
20 | /**
21 | * @return array
22 | */
23 | public function getRenderedRequestParams()
24 | {
25 | return $this->parameter;
26 | }
27 |
28 | /**
29 | * @param array $parameter
30 | * @return $this
31 | */
32 | public function setParameter(array $parameter)
33 | {
34 | foreach ($parameter as $key => $value) {
35 | if (array_key_exists($key, $this->parameter)) {
36 | $this->parameter[$key] = $value;
37 | }
38 | }
39 |
40 | return $this;
41 | }
42 |
43 | /**
44 | * @return string
45 | */
46 | public function getAction()
47 | {
48 | return Actions::ACTION_CHANNELS_INFO;
49 | }
50 |
51 | /**
52 | * @param array $response
53 | * @return array
54 | */
55 | public function parseResponse(array $response)
56 | {
57 | return [
58 | 'id' => $response['channel']['id'],
59 | 'name' => $response['channel']['name'],
60 | 'active' => $response['channel']['is_archived'],
61 | 'topic' => $response['channel']['topic']['value'],
62 | ];
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Slack/Client/Actions/ChannelsInvite.php:
--------------------------------------------------------------------------------
1 | null,
18 | 'user' => null
19 | ];
20 |
21 | /**
22 | * @return array
23 | * @throws \Exception
24 | */
25 | public function getRenderedRequestParams()
26 | {
27 | if (is_null($this->parameter['channel']) || is_null($this->parameter['user'])) {
28 | throw new \Exception('both parameters channel and user must be given');
29 | }
30 |
31 | return $this->parameter;
32 | }
33 |
34 | /**
35 | * @param array $parameter
36 | * @return $this
37 | */
38 | public function setParameter(array $parameter)
39 | {
40 | foreach ($parameter as $key => $value) {
41 | if (array_key_exists($key, $this->parameter)) {
42 | $this->parameter[$key] = $value;
43 | }
44 | }
45 |
46 | return $this;
47 | }
48 |
49 | /**
50 | * @return string
51 | */
52 | public function getAction()
53 | {
54 | return Actions::ACTION_CHANNELS_INVITE;
55 | }
56 |
57 | /**
58 | * @param array $response
59 | * @return array
60 | */
61 | public function parseResponse(array $response)
62 | {
63 | return [];
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Slack/Client/Actions/ChannelsList.php:
--------------------------------------------------------------------------------
1 | 1
18 | ];
19 |
20 | /**
21 | * @return array
22 | */
23 | public function getRenderedRequestParams()
24 | {
25 | return $this->parameter;
26 | }
27 |
28 | /**
29 | * @param array $parameter
30 | * @return $this
31 | */
32 | public function setParameter(array $parameter)
33 | {
34 | foreach ($parameter as $key => $value) {
35 | if (array_key_exists($key, $this->parameter)) {
36 | $this->parameter[$key] = $value;
37 | }
38 | }
39 |
40 | return $this;
41 | }
42 |
43 | /**
44 | * @return string
45 | */
46 | public function getAction()
47 | {
48 | return Actions::ACTION_CHANNELS_LIST;
49 | }
50 |
51 | /**
52 | * @param array $response
53 | * @return array
54 | */
55 | public function parseResponse(array $response)
56 | {
57 | $channels = [];
58 | foreach ($response['channels'] as $channel) {
59 | $channels[$channel['name']] = [
60 | 'id' => $channel['id'],
61 | 'active' => $channel['is_archived'],
62 | 'topic' => $channel['topic']['value'],
63 | ];
64 | }
65 |
66 | return $channels;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Slack/Client/Actions/ChannelsSetTopic.php:
--------------------------------------------------------------------------------
1 | null,
18 | 'topic' => null
19 | ];
20 |
21 | /**
22 | * @return array
23 | */
24 | public function getRenderedRequestParams()
25 | {
26 | return $this->parameter;
27 | }
28 |
29 | /**
30 | * @param array $parameter
31 | * @return $this
32 | */
33 | public function setParameter(array $parameter)
34 | {
35 | foreach ($parameter as $key => $value) {
36 | if (array_key_exists($key, $this->parameter)) {
37 | $this->parameter[$key] = $value;
38 | }
39 | }
40 |
41 | return $this;
42 | }
43 |
44 | /**
45 | * @return string
46 | */
47 | public function getAction()
48 | {
49 | return Actions::ACTION_CHANNELS_SET_TOPIC;
50 | }
51 |
52 | /**
53 | * @param array $response
54 | * @return array
55 | */
56 | public function parseResponse(array $response)
57 | {
58 | return [];
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Slack/Client/Actions/ChatPostMessage.php:
--------------------------------------------------------------------------------
1 | null,
19 | 'channel' => null,
20 | 'text' => null,
21 | 'icon_url' => null,
22 | 'icon_emoji' => null,
23 | 'parse' => 'full',
24 | 'link_names' => 1,
25 | 'unfurl_links' => 1,
26 | 'attachments' => [],
27 | ];
28 |
29 | /**
30 | * @return array
31 | * @throws \Exception
32 | */
33 | public function getRenderedRequestParams()
34 | {
35 | if (is_null($this->parameter['identity']) || !$this->parameter['identity'] instanceof Identity) {
36 | throw new \Exception('no identity given');
37 | }
38 |
39 | $this->parseIdentity();
40 | $this->parseAttachments();
41 |
42 | return $this->parameter;
43 | }
44 |
45 | private function parseAttachments()
46 | {
47 | if (empty($this->parameter['attachments'])) {
48 | return;
49 | }
50 |
51 | $attachments = [];
52 | foreach ($this->parameter['attachments'] as $attachmentObj) {
53 | if (!$attachmentObj instanceof Attachment) {
54 | throw new \Exception('atachments must be instance of \DZunke\SlackBundle\Slack\Entity\MessageAttachment');
55 | }
56 |
57 | $attachments[] = $attachmentObj->toArray();
58 | }
59 | $this->parameter['attachments'] = json_encode($attachments);
60 | }
61 |
62 | private function parseIdentity()
63 | {
64 | $this->parameter['username'] = $this->parameter['identity']->getUsername();
65 | if (empty($this->parameter['icon_url']) && $iconUrl = $this->parameter['identity']->getIconUrl()) {
66 | $this->parameter['icon_url'] = $iconUrl;
67 | }
68 | if (empty($this->parameter['icon_emoji']) && $iconEmoji = $this->parameter['identity']->getIconEmoji()) {
69 | $this->parameter['icon_emoji'] = $iconEmoji;
70 | }
71 | unset($this->parameter['identity']);
72 | }
73 |
74 | /**
75 | * @param array $parameter
76 | * @return $this
77 | */
78 | public function setParameter(array $parameter)
79 | {
80 | foreach ($parameter as $key => $value) {
81 | if (array_key_exists($key, $this->parameter)) {
82 | $this->parameter[$key] = $value;
83 | }
84 | }
85 |
86 | return $this;
87 | }
88 |
89 | /**
90 | * @return string
91 | */
92 | public function getAction()
93 | {
94 | return Actions::ACTION_POST_MESSAGE;
95 | }
96 |
97 | /**
98 | * @param array $response
99 | * @return array
100 | */
101 | public function parseResponse(array $response)
102 | {
103 | return [
104 | 'timestamp' => $response['ts']
105 | ];
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/Slack/Client/Actions/FilesUpload.php:
--------------------------------------------------------------------------------
1 | null,
18 | 'filetype' => null,
19 | 'filename' => null,
20 | 'title' => null,
21 | 'initial_comment' => null,
22 | 'channels' => null
23 | ];
24 |
25 | /**
26 | * @return array
27 | */
28 | public function getRenderedRequestParams()
29 | {
30 | return $this->parameter;
31 | }
32 |
33 | /**
34 | * @param array $parameter
35 | * @return $this
36 | */
37 | public function setParameter(array $parameter)
38 | {
39 | foreach ($parameter as $key => $value) {
40 | if (array_key_exists($key, $this->parameter)) {
41 | $this->parameter[$key] = $value;
42 | }
43 | }
44 |
45 | return $this;
46 | }
47 |
48 | /**
49 | * @return string
50 | */
51 | public function getAction()
52 | {
53 | return Actions::ACTION_FILES_UPLOAD;
54 | }
55 |
56 | /**
57 | * @param array $response
58 | * @return array
59 | */
60 | public function parseResponse(array $response)
61 | {
62 | if (isset($response['ok']) && $response['ok'] === true) {
63 | return $response['file'];
64 | }
65 |
66 | return $response;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Slack/Client/Actions/UsersList.php:
--------------------------------------------------------------------------------
1 | 1
18 | ];
19 |
20 | /**
21 | * @return array
22 | */
23 | public function getRenderedRequestParams()
24 | {
25 | return $this->parameter;
26 | }
27 |
28 | /**
29 | * @param array $parameter
30 | * @return $this
31 | */
32 | public function setParameter(array $parameter)
33 | {
34 | foreach ($parameter as $key => $value) {
35 | if (array_key_exists($key, $this->parameter)) {
36 | $this->parameter[$key] = $value;
37 | }
38 | }
39 |
40 | return $this;
41 | }
42 |
43 | /**
44 | * @return string
45 | */
46 | public function getAction()
47 | {
48 | return Actions::ACTION_USERS_LIST;
49 | }
50 |
51 | /**
52 | * @param array $response
53 | * @return array
54 | */
55 | public function parseResponse(array $response)
56 | {
57 | $users = [];
58 | foreach ($response['members'] as $user) {
59 | $users[$user['name']] = [
60 | 'id' => $user['id'],
61 | 'name' => $user['name'],
62 | 'deleted' => (bool)$user['deleted'],
63 | 'real_name' => $user['profile']['real_name'],
64 | 'email' => isset($user['profile']['email']) ? $user['profile']['email'] : null,
65 | 'is_bot' => (bool)$user['is_bot'],
66 | 'presence' => isset($user['presence']) ? $user['presence'] : null
67 | ];
68 | }
69 |
70 | return $users;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Slack/Client/Connection.php:
--------------------------------------------------------------------------------
1 | endpoint;
40 | }
41 |
42 | /**
43 | * @param string $endpoint
44 | *
45 | * @return $this
46 | */
47 | public function setEndpoint($endpoint)
48 | {
49 | $this->endpoint = (string)$endpoint;
50 |
51 | return $this;
52 | }
53 |
54 | /**
55 | * @return string
56 | */
57 | public function getToken()
58 | {
59 | return $this->token;
60 | }
61 |
62 | /**
63 | * @param string $token
64 | *
65 | * @return $this
66 | */
67 | public function setToken($token)
68 | {
69 | $this->token = (string)$token;
70 |
71 | return $this;
72 | }
73 |
74 | /**
75 | * @return int
76 | */
77 | public function getLimitRetries()
78 | {
79 | return $this->limitRetries;
80 | }
81 |
82 | /**
83 | * @param int $retries
84 | *
85 | * @return $this
86 | */
87 | public function setLimitRetries($retries)
88 | {
89 | $this->limitRetries = (int)$retries;
90 |
91 | return $this;
92 | }
93 |
94 | /**
95 | * @return bool
96 | */
97 | public function getVerifySsl()
98 | {
99 | return $this->verifySsl;
100 | }
101 |
102 | /**
103 | * @param bool $verifySsl
104 | *
105 | * @return $this
106 | */
107 | public function setVerifySsl($verifySsl)
108 | {
109 | $this->verifySsl = (bool)$verifySsl;
110 |
111 | return $this;
112 | }
113 |
114 | /**
115 | * @return string
116 | */
117 | public function getHttpMethod()
118 | {
119 | return $this->httpMethod;
120 | }
121 |
122 | /**
123 | * @return $this
124 | */
125 | public function isHttpGetMethod()
126 | {
127 | $this->httpMethod = Request::METHOD_GET;
128 |
129 | return $this;
130 | }
131 |
132 | /**
133 | * @return $this
134 | */
135 | public function isHttpPostMethod()
136 | {
137 | $this->httpMethod = Request::METHOD_POST;
138 |
139 | return $this;
140 | }
141 |
142 | /**
143 | * @return bool
144 | */
145 | public function isValid()
146 | {
147 | return (!empty($this->endpoint) && !empty($this->token));
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/Slack/Client/Response.php:
--------------------------------------------------------------------------------
1 | status = (bool)$status;
42 |
43 | return $this;
44 | }
45 |
46 | /**
47 | * @return bool
48 | */
49 | public function getStatus()
50 | {
51 | return $this->status;
52 | }
53 |
54 | /**
55 | * @param string $error
56 | * @return $this
57 | */
58 | public function setError($error)
59 | {
60 | $this->error = $error;
61 |
62 | return $this;
63 | }
64 |
65 | /**
66 | * @return string
67 | */
68 | public function getError()
69 | {
70 | return $this->error;
71 | }
72 |
73 | /**
74 | * @param array $data
75 | * @return $this
76 | */
77 | public function setData(array $data)
78 | {
79 | $this->data = $data;
80 |
81 | return $this;
82 | }
83 |
84 | /**
85 | * @return array
86 | */
87 | public function getData()
88 | {
89 | return $this->data;
90 | }
91 |
92 | /**
93 | * @param \GuzzleHttp\Psr7\Response $guzzleResponse
94 | * @param ActionsInterface $action
95 | * @return Response
96 | */
97 | public static function parseGuzzleResponse(\GuzzleHttp\Psr7\Response $guzzleResponse, ActionsInterface $action)
98 | {
99 | $response = new self();
100 |
101 | if ($guzzleResponse->getStatusCode() != 200) {
102 | $response->setStatus(false);
103 | $response->setError($response::ERROR_REQUEST_ERROR);
104 |
105 | return $response;
106 | }
107 |
108 | $responseArray = json_decode($guzzleResponse->getBody()->getContents(), true);
109 |
110 | $response->setStatus($responseArray['ok']);
111 |
112 | if ($response->getStatus() === false) {
113 | $response->setError($responseArray['error']);
114 |
115 | return $response;
116 | }
117 |
118 | $response->setData($action->parseResponse($responseArray));
119 |
120 | return $response;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/Slack/Entity/Message.php:
--------------------------------------------------------------------------------
1 | id;
55 | }
56 |
57 | /**
58 | * @param string $id
59 | * @return $this
60 | */
61 | public function setId($id)
62 | {
63 | $this->id = $id;
64 |
65 | return $this;
66 | }
67 |
68 | /**
69 | * @return string
70 | */
71 | public function getChannel()
72 | {
73 | return $this->channel;
74 | }
75 |
76 | /**
77 | * @param string $channel
78 | * @return $this
79 | */
80 | public function setChannel($channel)
81 | {
82 | $this->channel = $channel;
83 |
84 | return $this;
85 | }
86 |
87 | /**
88 | * @return string
89 | */
90 | public function getType()
91 | {
92 | return $this->type;
93 | }
94 |
95 | /**
96 | * @param string $type
97 | * @return $this
98 | */
99 | public function setType($type)
100 | {
101 | $this->type = $type;
102 |
103 | return $this;
104 | }
105 |
106 | /**
107 | * @return string
108 | */
109 | public function getUserId()
110 | {
111 | return $this->userId;
112 | }
113 |
114 | /**
115 | * @param string $userId
116 | * @return $this
117 | */
118 | public function setUserId($userId)
119 | {
120 | $this->userId = $userId;
121 |
122 | return $this;
123 | }
124 |
125 | /**
126 | * @return string
127 | */
128 | public function getUsername()
129 | {
130 | return $this->username;
131 | }
132 |
133 | /**
134 | * @param string $username
135 | * @return $this
136 | */
137 | public function setUsername($username)
138 | {
139 | $this->username = $username;
140 |
141 | return $this;
142 | }
143 |
144 | /**
145 | * @return bool
146 | */
147 | public function isBot()
148 | {
149 | return !empty($this->id) && empty($this->userId) && !empty($this->username);
150 | }
151 |
152 | /**
153 | * @return string
154 | */
155 | public function getContent()
156 | {
157 | return $this->content;
158 | }
159 |
160 | /**
161 | * @param string $content
162 | * @return $this
163 | */
164 | public function setContent($content)
165 | {
166 | $this->content = $content;
167 |
168 | return $this;
169 | }
170 |
171 | /**
172 | * @return MessageAttachment[]
173 | */
174 | public function getAttachments()
175 | {
176 | return $this->attachments;
177 | }
178 |
179 | /**
180 | * @param MessageAttachment $attachment
181 | * @return $this
182 | */
183 | public function addAttachment(MessageAttachment $attachment)
184 | {
185 | $this->attachments[] = $attachment;
186 |
187 | return $this;
188 | }
189 |
190 | /**
191 | * @param MessageAttachment[] $attachments
192 | * @return $this
193 | */
194 | public function setAttachments($attachments)
195 | {
196 | $this->attachments = $attachments;
197 |
198 | return $this;
199 | }
200 |
201 | }
202 |
--------------------------------------------------------------------------------
/Slack/Entity/MessageAttachment.php:
--------------------------------------------------------------------------------
1 | authorIcon;
136 | }
137 |
138 | /**
139 | * @param string $authorIcon
140 | *
141 | * @return $this
142 | */
143 | public function setAuthorIcon($authorIcon)
144 | {
145 | $this->authorIcon = $authorIcon;
146 |
147 | return $this;
148 | }
149 |
150 | /**
151 | * @return string
152 | */
153 | public function getAuthorLink()
154 | {
155 | return $this->authorLink;
156 | }
157 |
158 | /**
159 | * @param string $authorLink
160 | *
161 | * @return $this
162 | */
163 | public function setAuthorLink($authorLink)
164 | {
165 | $this->authorLink = $authorLink;
166 |
167 | return $this;
168 | }
169 |
170 | /**
171 | * @return string
172 | */
173 | public function getAuthorName()
174 | {
175 | return $this->authorName;
176 | }
177 |
178 | /**
179 | * @param string $authorName
180 | *
181 | * @return $this
182 | */
183 | public function setAuthorName($authorName)
184 | {
185 | $this->authorName = $authorName;
186 |
187 | return $this;
188 | }
189 |
190 | /**
191 | * @param string $color
192 | *
193 | * @return $this
194 | */
195 | public function setColor($color)
196 | {
197 | $this->color = $color;
198 |
199 | return $this;
200 | }
201 |
202 | /**
203 | * @return string
204 | */
205 | public function getColor()
206 | {
207 | return $this->color;
208 | }
209 |
210 | /**
211 | * @param string $fallback
212 | *
213 | * @return $this
214 | */
215 | public function setFallback($fallback)
216 | {
217 | $this->fallback = $fallback;
218 |
219 | return $this;
220 | }
221 |
222 | /**
223 | * @return string
224 | */
225 | public function getFallback()
226 | {
227 | return $this->fallback;
228 | }
229 |
230 | /**
231 | * @return string
232 | */
233 | public function getImageUrl()
234 | {
235 | return $this->imageUrl;
236 | }
237 |
238 | /**
239 | * @param string $imageUrl
240 | *
241 | * @return $this
242 | */
243 | public function setImageUrl($imageUrl)
244 | {
245 | $this->imageUrl = $imageUrl;
246 |
247 | return $this;
248 | }
249 |
250 | /**
251 | * @param array $fields
252 | *
253 | * @return $this
254 | */
255 | public function setFields(array $fields)
256 | {
257 | $this->fields = $fields;
258 |
259 | return $this;
260 | }
261 |
262 | /**
263 | * @param string $title
264 | * @param string $text
265 | * @param bool $scale
266 | *
267 | * @return $this
268 | */
269 | public function addField($title, $text, $scale = false)
270 | {
271 | $this->fields[] = [
272 | 'title' => (string) $title,
273 | 'value' => (string) $text,
274 | 'short' => $scale,
275 | ];
276 |
277 | return $this;
278 | }
279 |
280 | /**
281 | * @return array
282 | */
283 | public function getFields()
284 | {
285 | return $this->fields;
286 | }
287 |
288 | /**
289 | * @param array $actions
290 | *
291 | * @return $this
292 | */
293 | public function setActions(array $actions)
294 | {
295 | $this->actions = $actions;
296 |
297 | return $this;
298 | }
299 |
300 | /**
301 | * @param string $text
302 | * @param string $url
303 | * @param string $style
304 | *
305 | * @return $this
306 | */
307 | public function addAction($text, $url, $style = null)
308 | {
309 | $this->actions[] = [
310 | 'type' => 'button',
311 | 'text' => (string) $text,
312 | 'url' => (string) $url,
313 | 'style' => (string) $style,
314 | ];
315 |
316 | return $this;
317 | }
318 |
319 | /**
320 | * @return array
321 | */
322 | public function getActions()
323 | {
324 | return $this->actions;
325 | }
326 |
327 | /**
328 | * @param string $pretext
329 | *
330 | * @return $this
331 | */
332 | public function setPretext($pretext)
333 | {
334 | $this->pretext = $pretext;
335 |
336 | return $this;
337 | }
338 |
339 | /**
340 | * @return string
341 | */
342 | public function getPretext()
343 | {
344 | return $this->pretext;
345 | }
346 |
347 | /**
348 | * @param string $text
349 | *
350 | * @return $this
351 | */
352 | public function setText($text)
353 | {
354 | $this->text = $text;
355 |
356 | return $this;
357 | }
358 |
359 | /**
360 | * @return string
361 | */
362 | public function getText()
363 | {
364 | return $this->text;
365 | }
366 |
367 | /**
368 | * @return string
369 | */
370 | public function getTitle()
371 | {
372 | return $this->title;
373 | }
374 |
375 | /**
376 | * @param string $title
377 | *
378 | * @return $this
379 | */
380 | public function setTitle($title)
381 | {
382 | $this->title = $title;
383 |
384 | return $this;
385 | }
386 |
387 | /**
388 | * @return string
389 | */
390 | public function getTitleLink()
391 | {
392 | return $this->titleLink;
393 | }
394 |
395 | /**
396 | * @param string $titleLink
397 | *
398 | * @return $this
399 | */
400 | public function setTitleLink($titleLink)
401 | {
402 | $this->titleLink = $titleLink;
403 |
404 | return $this;
405 | }
406 |
407 | /**
408 | * @return string
409 | */
410 | public function getThumbUrl()
411 | {
412 | return $this->thumbUrl;
413 | }
414 |
415 | /**
416 | * @param string $thumbUrl
417 | *
418 | * @return $this
419 | */
420 | public function setThumbUrl($thumbUrl)
421 | {
422 | $this->thumbUrl = $thumbUrl;
423 |
424 | return $this;
425 | }
426 |
427 | /**
428 | * @return string
429 | */
430 | public function getFooter()
431 | {
432 | return $this->footer;
433 | }
434 |
435 | /**
436 | * @param string $footer
437 | */
438 | public function setFooter($footer)
439 | {
440 | $this->footer = $footer;
441 | }
442 |
443 | /**
444 | * @return string
445 | */
446 | public function getFooterIcon()
447 | {
448 | return $this->footerIcon;
449 | }
450 |
451 | /**
452 | * @param string $footerIcon
453 | */
454 | public function setFooterIcon($footerIcon)
455 | {
456 | $this->footerIcon = $footerIcon;
457 | }
458 |
459 | /**
460 | * @return int
461 | */
462 | public function getTs()
463 | {
464 | return $this->ts;
465 | }
466 |
467 | /**
468 | * @param int $ts
469 | */
470 | public function setTs($ts)
471 | {
472 | $this->ts = $ts;
473 | }
474 |
475 | /**
476 | * @return array
477 | */
478 | public function toArray()
479 | {
480 | return [
481 | 'fallback' => $this->getFallback(),
482 | 'color' => $this->getColor(),
483 | 'pretext' => $this->getPretext(),
484 | 'author_name' => $this->getAuthorName(),
485 | 'author_link' => $this->getAuthorLink(),
486 | 'author_icon' => $this->getAuthorIcon(),
487 | 'title' => $this->getTitle(),
488 | 'title_link' => $this->getTitleLink(),
489 | 'text' => $this->getText(),
490 | 'fields' => $this->getFields(),
491 | 'image_url' => $this->getImageUrl(),
492 | 'thumb_url' => $this->getThumbUrl(),
493 | 'footer' => $this->getFooter(),
494 | 'footer_icon' => $this->getFooterIcon(),
495 | 'ts' => $this->getTs(),
496 | 'actions' => $this->getActions(),
497 | ];
498 | }
499 | }
500 |
--------------------------------------------------------------------------------
/Slack/Messaging.php:
--------------------------------------------------------------------------------
1 | client = $client;
28 | $this->identityBag = $identityBag;
29 | }
30 |
31 | /**
32 | * @return IdentityBag
33 | */
34 | public function getIdentityBag()
35 | {
36 | return $this->identityBag;
37 | }
38 |
39 | /**
40 | * @return Client
41 | */
42 | public function getClient()
43 | {
44 | return $this->client;
45 | }
46 |
47 | /**
48 | * @param string $channel
49 | * @param string $message
50 | * @param string $identity
51 | * @param Attachment[] $attachments
52 | * @param array $clientOptions
53 | *
54 | * @return Client\Response|bool
55 | *
56 | * @throws \InvalidArgumentException
57 | */
58 | public function message($channel, $message, $identity, array $attachments = [], array $clientOptions = [])
59 | {
60 | if (!$this->identityBag->has($identity)) {
61 | throw new \InvalidArgumentException(sprintf('identity "%s" is not registered', $identity));
62 | }
63 |
64 | return $this->client->send(
65 | Actions::ACTION_POST_MESSAGE,
66 | array_merge([
67 | 'identity' => $this->identityBag->get($identity),
68 | 'channel' => $channel,
69 | 'text' => $message,
70 | 'attachments' => $attachments,
71 | ], $clientOptions)
72 | );
73 | }
74 |
75 | /**
76 | * @param string|array $channel # String is DEPRECATED scince v1.3 - Deliver Array
77 | * @param string $title
78 | * @param string $file
79 | * @param string|null $comment
80 | * @param string|null $threadTs
81 | *
82 | * @return Client\Response|false
83 | */
84 | public function upload($channel, $title, $file, $comment = null, $threadTs = null)
85 | {
86 | if (!file_exists($file)) {
87 | return false;
88 | }
89 |
90 | if (!is_array($channel)) {
91 | @trigger_error('Channel as String is deprecated scince v1.3, please deliver an Array of Channels', E_USER_DEPRECATED);
92 | $channel = [$channel];
93 | }
94 |
95 | $params = [];
96 | $params['title'] = $title;
97 | $params['initial_comment'] = $comment;
98 | $params['channels'] = implode(',', $channel);
99 | $params['filename'] = basename($file);
100 | $params['file'] = fopen($file, 'r');
101 | $params['thread_ts'] = $threadTs;
102 |
103 | return $this->client->send(
104 | Actions::ACTION_FILES_UPLOAD,
105 | $params,
106 | true
107 | );
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/Slack/Messaging/Identity.php:
--------------------------------------------------------------------------------
1 | username = (string)$username;
31 |
32 | return $this;
33 | }
34 |
35 | /**
36 | * @return string
37 | */
38 | public function getUsername()
39 | {
40 | return $this->username;
41 | }
42 |
43 | /**
44 | * @param string $iconUrl
45 | * @return $this
46 | */
47 | public function setIconUrl($iconUrl)
48 | {
49 | $this->iconUrl = (string)$iconUrl;
50 |
51 | return $this;
52 | }
53 |
54 | /**
55 | * @return string
56 | */
57 | public function getIconUrl()
58 | {
59 | return $this->iconUrl;
60 | }
61 |
62 | /**
63 | * @param string $iconEmoji
64 | * @return mixed
65 | */
66 | public function setIconEmoji($iconEmoji)
67 | {
68 | $this->iconEmoji = $iconEmoji;
69 |
70 | return $this->iconEmoji;
71 | }
72 |
73 | /**
74 | * @return string
75 | */
76 | public function getIconEmoji()
77 | {
78 | return $this->iconEmoji;
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/Slack/Messaging/IdentityBag.php:
--------------------------------------------------------------------------------
1 | $config) {
25 | $identObj = new Identity();
26 | $identObj->setUsername($username);
27 | $identObj->setIconEmoji((isset($config['icon_emoji']) ? $config['icon_emoji'] : null));
28 | $identObj->setIconUrl((isset($config['icon_url']) ? $config['icon_url'] : null));
29 |
30 | $this->add($identObj);
31 | }
32 |
33 | return $this;
34 | }
35 |
36 | /**
37 | * @param string $username
38 | * @return bool
39 | */
40 | public function has($username)
41 | {
42 | if (array_key_exists($username, $this->identities)) {
43 | return true;
44 | }
45 |
46 | return false;
47 | }
48 |
49 | /**
50 | * @param Identity $identity
51 | * @return $this
52 | */
53 | public function add(Identity $identity)
54 | {
55 | $this->identities[$identity->getUsername()] = $identity;
56 |
57 | return $this;
58 | }
59 |
60 | /**
61 | * @param string $username
62 | * @return Identity
63 | * @throws \Exception
64 | */
65 | public function get($username)
66 | {
67 | if (!isset($this->identities[$username])) {
68 | throw new \Exception('identity "' . $username . '" does not exists');
69 | }
70 |
71 | return $this->identities[$username];
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/Slack/Users.php:
--------------------------------------------------------------------------------
1 | client = $client;
20 | }
21 |
22 | /**
23 | * @return Client
24 | */
25 | public function getClient()
26 | {
27 | return $this->client;
28 | }
29 |
30 | /**
31 | * @return array
32 | */
33 | public function getUsers()
34 | {
35 | return $this->client->send(Actions::ACTION_USERS_LIST)->getData();
36 | }
37 |
38 | /**
39 | * @return array
40 | */
41 | public function getActiveUsers()
42 | {
43 | return array_filter(
44 | $this->getUsers(),
45 | function ($user) {
46 | return $user['deleted'] === false;
47 | }
48 | );
49 | }
50 |
51 | /**
52 | * @return array
53 | */
54 | public function getDeletedUsers()
55 | {
56 | return array_filter(
57 | $this->getUsers(),
58 | function ($user) {
59 | return $user['deleted'] === true;
60 | }
61 | );
62 | }
63 |
64 | /**
65 | * @param string $name
66 | * @return null|array
67 | */
68 | public function getUser($name)
69 | {
70 | $users = $this->getUsers();
71 |
72 | return array_key_exists($name, $users) ? $users[$name] : null;
73 | }
74 |
75 | /**
76 | * @param string $name
77 | * @return null|array
78 | */
79 | public function getId($name)
80 | {
81 | $user = $this->getUser($name);
82 |
83 | return !is_null($user) ? $user['id'] : null;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dzunke/slack-bundle",
3 | "description": "Symfony2 Integration for Slack - supporting Monolog",
4 | "keywords": ["symfony", "api", "bundle", "slack", "monolog", "logger", "messaging"],
5 | "homepage": "https://github.com/DZunke/SlackBundle",
6 | "license": "MIT",
7 | "minimum-stability": "dev",
8 | "authors": [
9 | {
10 | "name": "Denis Zunke",
11 | "email": "denis.zunke@gmail.com"
12 | }
13 | ],
14 | "archive": {
15 | "exclude": ["/Tests"]
16 | },
17 | "require": {
18 | "php": ">=5.6",
19 | "symfony/console": "~2.8|~3.0|~4.0",
20 | "symfony/config": "~2.8|~3.0|~4.0",
21 | "symfony/dependency-injection": "~2.8|~3.0|~4.0",
22 | "symfony/http-foundation": "~2.8|~3.0|~4.0",
23 | "symfony/event-dispatcher": "~2.8|~3.0|~4.0",
24 | "monolog/monolog": "^1",
25 | "guzzlehttp/guzzle": "^6.2.1"
26 | },
27 | "autoload": {
28 | "psr-0": { "DZunke\\SlackBundle": "" }
29 | },
30 | "target-dir": "DZunke/SlackBundle",
31 | "extra": {
32 | "branch-alias": {
33 | "dev-dev": "2.0-dev"
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------