Ejemplo n.º 1
0
 /**
  * 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']]);
             }
         }
     }
 }
Ejemplo n.º 2
0
 /**
  * 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();
 }