/** * @param Payload $payload * @param OutputInterface $output */ private function onReaction(Payload $payload, OutputInterface $output) { try { // Always ignore messages without a user if ($payload->offsetExists('user') == false) { return; } $reaction = Reaction::fromSlack($payload->offsetGet('reaction'), $payload->offsetGet('event_ts'), $payload->offsetGet('item')['ts'], $payload->offsetGet('user')); $this->reactionProcessor->process($reaction); } catch (\Exception $e) { $output->writeln(sprintf('<error>Error: %s, %s</error>', get_class($e), $e->getMessage())); } }
/** * @return bool|AbstractCommand */ public function resolveCommand() { $message = $this->payload->getData()['text']; $parts = explode(':', $message); $command = ucfirst(strtolower($parts[0])); $commandClass = '\\T3Bot\\Commands\\' . $command . 'Command'; if (class_exists($commandClass)) { return new $commandClass($this->payload, $this->client); } $parts = explode(' ', $message); $command = ucfirst(strtolower($parts[0])); $commandClass = '\\T3Bot\\Commands\\' . $command . 'Command'; if (class_exists($commandClass)) { return new $commandClass($this->payload, $this->client); } $resultCommand = false; if (strpos($message, 'botty') !== false || strpos($message, $GLOBALS['config']['slack']['botId']) !== false) { $resultCommand = new BottyCommand($this->payload, $this->client); } return $resultCommand; }
/** * Handles incoming websocket messages, parses them, and emits them as remote events. * * @param WebSocketMessageInterface $messageRaw A websocket message. */ private function onMessage(WebSocketMessageInterface $message) { // parse the message and get the event name $payload = Payload::fromJson($message->getData()); if (isset($payload['type'])) { switch ($payload['type']) { case 'hello': $this->connected = true; break; case 'team_rename': $this->team->data['name'] = $payload['name']; break; case 'team_domain_change': $this->team->data['domain'] = $payload['domain']; break; case 'channel_created': $this->getChannelById($payload['channel']['id'])->then(function (Channel $channel) { $this->channels[$channel->getId()] = $channel; }); break; case 'channel_deleted': unset($this->channels[$payload['channel']['id']]); break; case 'channel_rename': $this->channels[$payload['channel']['id']]->data['name'] = $payload['channel']['name']; break; case 'channel_archive': $this->channels[$payload['channel']['id']]->data['is_archived'] = true; break; case 'channel_unarchive': $this->channels[$payload['channel']['id']]->data['is_archived'] = false; break; case 'group_joined': $group = new Group($this, $payload['channel']); $this->groups[$group->getId()] = $group; break; case 'group_rename': $this->groups[$payload['group']['id']]->data['name'] = $payload['channel']['name']; break; case 'group_archive': $this->groups[$payload['group']['id']]->data['is_archived'] = true; break; case 'group_unarchive': $this->groups[$payload['group']['id']]->data['is_archived'] = false; break; case 'im_created': $dm = new DirectMessageChannel($this, $payload['channel']); $this->dms[$dm->getId()] = $dm; break; } // emit an event with the attached json $this->emit($payload['type'], [$payload]); } else { // If reply_to is set, then it is a server confirmation for a previously // sent message if (isset($payload['reply_to'])) { if (isset($this->pendingMessages[$payload['reply_to']])) { $deferred = $this->pendingMessages[$payload['reply_to']]; // Resolve or reject the promise that was waiting for the reply. if (isset($payload['ok']) && $payload['ok'] === true) { $deferred->resolve(); } else { $deferred->reject($payload['error']); } unset($this->pendingMessages[$payload['reply_to']]); } } } }
/** * @param \T3Bot\Slack\Message|string $messageToSent * @param string $user * @param string $channel the channel id */ public function sendResponse($messageToSent, $user = null, $channel = null) { $data = []; if ($user !== null) { $this->client->apiCall('im.open', ['user' => $user])->then(function (Payload $response) use($messageToSent) { $channel = $response->getData()['channel']['id']; if ($messageToSent instanceof Message) { $data = []; $data['unfurl_links'] = false; $data['unfurl_media'] = false; $data['parse'] = 'none'; $data['text'] = $messageToSent->getText(); $data['channel'] = $channel; $attachments = $messageToSent->getAttachments(); if (count($attachments)) { $data['attachments'] = array(); } /** @var \T3Bot\Slack\Message\Attachment $attachment */ foreach ($attachments as $attachment) { $data['attachments'][] = Attachment::fromData(['title' => $attachment->getTitle(), 'title_link' => $attachment->getTitleLink(), 'text' => $attachment->getText(), 'fallback' => $attachment->getFallback(), 'color' => $attachment->getColor(), 'pretext' => $attachment->getPretext(), 'author_name' => $attachment->getAuthorName(), 'author_icon' => $attachment->getAuthorIcon(), 'author_link' => $attachment->getAuthorLink(), 'image_url' => $attachment->getImageUrl(), 'thumb_url' => $attachment->getThumbUrl()]); } $message = new \Slack\Message\Message($this->client, $data); $this->client->postMessage($message); } elseif (is_string($messageToSent)) { $data = []; $data['unfurl_links'] = false; $data['unfurl_media'] = false; $data['parse'] = 'none'; $data['text'] = $messageToSent; $data['channel'] = $channel; $data['as_user'] = true; $this->client->apiCall('chat.postMessage', $data); } }); } else { $channel = $channel !== null ? $channel : $this->payload->getData()['channel']; if ($messageToSent instanceof Message) { $data['unfurl_links'] = false; $data['unfurl_media'] = false; $data['parse'] = 'none'; $data['text'] = $messageToSent->getText(); $data['channel'] = $channel; $attachments = $messageToSent->getAttachments(); if (count($attachments)) { $data['attachments'] = array(); } /** @var \T3Bot\Slack\Message\Attachment $attachment */ foreach ($attachments as $attachment) { $data['attachments'][] = Attachment::fromData(['title' => $attachment->getTitle(), 'title_link' => $attachment->getTitleLink(), 'text' => $attachment->getText(), 'fallback' => $attachment->getFallback(), 'color' => $attachment->getColor(), 'pretext' => $attachment->getPretext(), 'author_name' => $attachment->getAuthorName(), 'author_icon' => $attachment->getAuthorIcon(), 'author_link' => $attachment->getAuthorLink(), 'image_url' => $attachment->getImageUrl(), 'thumb_url' => $attachment->getThumbUrl()]); } $message = new \Slack\Message\Message($this->client, $data); $this->client->postMessage($message); } elseif (is_string($messageToSent)) { $data['unfurl_links'] = false; $data['unfurl_media'] = false; $data['parse'] = 'none'; $data['text'] = $messageToSent; $data['channel'] = $channel; $data['as_user'] = true; $this->client->apiCall('chat.postMessage', $data); } } }
/** * Sends an API request. * * @param string $method The API method to call. * @param array $args An associative array of arguments to pass to the * method call. * * @return \React\Promise\PromiseInterface A promise for an API response. */ public function apiCall($method, array $args = []) { // create the request url $requestUrl = self::BASE_URL . $method; // set the api token $args['token'] = $this->token; // send a post request with all arguments $promise = $this->httpClient->postAsync($requestUrl, ['form_params' => $args]); // Add requests to the event loop to be handled at a later date. $this->loop->futureTick(function () use($promise) { $promise->wait(); }); // When the response has arrived, parse it and resolve. Note that our // promises aren't pretty; Guzzle promises are not compatible with React // promises, so the only Guzzle promises ever used die in here and it is // React from here on out. $deferred = new Deferred(); $promise->then(function (ResponseInterface $response) use($deferred) { // get the response as a json object $payload = Payload::fromJson((string) $response->getBody()); // check if there was an error if (isset($payload['ok']) && $payload['ok'] === true) { $deferred->resolve($payload); } else { // make a nice-looking error message and throw an exception $niceMessage = ucfirst(str_replace('_', ' ', $payload['error'])); $deferred->reject(new ApiException($niceMessage)); } }); return $deferred->promise(); }
public function __construct(ApiClient $client, Payload $payload) { $this->client = $client; parent::__construct($payload->getData()); }