コード例 #1
0
 public function perform()
 {
     $args = $this->args;
     $message = $args['message'];
     $type = $message['msgType'];
     $content = $message['content'];
     $WEConnectAccountInfo = $args['account'];
     $WEConnectUserInfo = $args['user'];
     $accountId = new \MongoId($args['accountId']);
     $accountInfoType = null;
     $source = null;
     switch ($WEConnectAccountInfo['channel']) {
         case 'WEIBO':
             $source = ChatConversation::TYPE_WEIBO;
             $accountInfoType = 'WEIBO';
             break;
         case 'ALIPAY':
             $source = ChatConversation::TYPE_ALIPAY;
             $accountInfoType = 'ALIPAY';
             break;
         case 'WEIXIN':
             $source = ChatConversation::TYPE_WECHAT;
             $accountInfoType = $WEConnectAccountInfo['accountType'];
             break;
         default:
             throw new BadRequestHttpException("Unsupported channel type");
             break;
     }
     $client = ['nick' => $WEConnectUserInfo['nickname'], 'avatar' => $WEConnectUserInfo['headerImgUrl'], 'openId' => $WEConnectUserInfo['id'], 'originId' => $WEConnectUserInfo['originId'], 'source' => $source, 'sourceChannel' => $WEConnectUserInfo['accountId'], 'accountId' => $accountId, 'accountInfo' => ['type' => $accountInfoType, 'name' => $WEConnectAccountInfo['name']]];
     ResqueUtil::log(['message' => 'get message from wechat', 'WEConnectAccountInfo' => $WEConnectAccountInfo, 'WEConnectUserInfo' => $WEConnectUserInfo, 'accountId' => $accountId]);
     if (empty($type) || empty($content)) {
         ResqueUtil::log(['message' => 'missing required fields', 'senario' => 'accepting messages from WeConnect', 'WEConnectAccountInfo' => $WEConnectAccountInfo, 'WEConnectUserInfo' => $WEConnectUserInfo]);
         HelpDesk::sendSystemReplyByType($client, $accountId, HelpDeskSetting::REPLY_ERROR);
         return;
     }
     try {
         if ('EVENT' === $type) {
             switch ($content) {
                 case 'CONNECT':
                     $isInWorkingHour = HelpDeskSetting::isInWorkingHours($accountId);
                     if ($isInWorkingHour) {
                         if (empty($WEConnectAccountInfo)) {
                             ResqueUtil::log(['message' => 'Account parameters missing', 'senario' => 'Wechat message, event connect']);
                             HelpDesk::sendSystemReplyByType($client, $accountId, HelpDeskSetting::REPLY_ERROR);
                             return;
                         }
                         //check if the wechat enduser has connected to a helpdesk
                         $conversation = ChatConversation::findOpenByClientId($WEConnectUserInfo['id'], $accountId);
                         if (!empty($conversation)) {
                             ResqueUtil::log(['message' => 'Have connect to helpdesk already', 'senario' => 'Wechat message, event connect', 'user' => $WEConnectUserInfo, 'accountId' => $accountId]);
                             HelpDesk::sendSystemReplyByType($client, $accountId, HelpDeskSetting::REPLY_CUSTOM, ChatConversation::NO_DUPLICATE_CLIENT);
                             return;
                         }
                         return HelpDesk::connect($client, $accountId);
                     } else {
                         //send the disconnect event to WeConnect
                         Yii::$app->weConnect->sendCustomerServiceMessage($WEConnectUserInfo['id'], $WEConnectUserInfo['accountId'], ['msgType' => ChatConversation::WECHAT_MESSAGE_TYPE_EVENT, 'content' => 'DISCONNECT']);
                         HelpDesk::sendSystemReplyByType($client, $accountId, HelpDeskSetting::REPLY_NONWORKING);
                     }
                     break;
                 case 'DISCONNECT':
                     //get the conversationId
                     $conversation = ChatConversation::findOpenByClientId($WEConnectUserInfo['id'], $accountId, ['type' => 'left']);
                     if (empty($conversation)) {
                         return ['status' => 'ok'];
                     }
                     //disconnect
                     return HelpDesk::disconnect($conversation->_id, ['type' => 'brake']);
                     break;
                 default:
                     throw new BadRequestHttpException("Unsupported event content type");
                     break;
             }
         } else {
             //get the conversation information
             $conversation = ChatConversation::findOpenByClientId($WEConnectUserInfo['id'], $accountId);
             if (empty($conversation)) {
                 $pendingClient = PendingClient::findOne(['openId' => $WEConnectUserInfo['id'], 'accountId' => $accountId]);
                 if (!empty($pendingClient)) {
                     HelpDesk::sendSystemReplyByType($client, $accountId, HelpDeskSetting::REPLY_WAITTING);
                     return ['status' => 'ok'];
                 } else {
                     return HelpDesk::connect($client, $accountId);
                 }
             }
             $desk = $conversation->desk;
             $desk['id'] = (string) $desk['id'];
             $client = $conversation->client;
             $sentTime = TimeUtil::msTime();
             //trigger send message event
             $name = ChatConversation::EVENT_CHAT_MESSAGE;
             $data = ['conversationId' => (string) $conversation->_id, 'desk' => $desk, 'client' => $client, 'chatMessage' => ['content' => ['msgType' => $type, 'body' => $content], 'sentTime' => $sentTime], 'isReply' => false];
             //add chatMessage record
             $chatMessage = ChatMessage::saveRecord(['msgType' => $type, 'body' => $content], $sentTime, false, $conversation->_id, $accountId);
             //helpDesk web client message
             $channels = [ChatConversation::getChannelName($desk['id'], $client['openId'])];
             $data['messageId'] = (string) $chatMessage->_id;
             Yii::$app->tuisongbao->triggerEvent($name, $data, $channels);
             //helpDesk mobile client message
             $pushExtra = ['messageId' => (string) $chatMessage->_id, 'openId' => $client['openId'], 'conversationId' => (string) $conversation->_id, 'sentTime' => $chatMessage->sentTime];
             $pushMessage = empty($client['nick']) ? $content : $client['nick'] . ':' . $content;
             ChatConversation::pushMessage($desk['id'], ChatConversation::EVENT_CHAT_MESSAGE, $pushExtra, $pushMessage);
             return ['status' => 'ok'];
         }
     } catch (Exception $e) {
         LogUtil::error(['message' => $e->getMessage()], 'helpdesk');
         return HelpDesk::sendSystemReplyByType($client, $account, HelpDeskSetting::REPLY_ERROR);
     }
 }
コード例 #2
0
 /**
  * Tranfer client to another helpdesk
  *
  * <b>Request Type: </b>POST<br/>
  * <b>Request Endpoint: </b>http://{server-domain}/api/chat/conversation/transfer
  * <b>Summary: </b> This api is for transfer helpdesk.<br/>
  *
  * <b>Request Parameters: </b><br/>
  *     accesstoken: string<br/>
  *     deskId: string, id of the desk.<br/>
  *     clientOpenId: string, the openId of the client.<br/>
  *     conversationId: string, the id of chatConversation.<br/>
  *     targetDeskId: string, the id of the target desk
  *
  * <b>Response Example: </b><br/>
  * {
  *     "status" => "ok"
  * }
  */
 public function actionTransfer()
 {
     $cache = Yii::$app->cache;
     $targetDeskId = $this->getParams('targetDeskId');
     $conversationId = $this->getParams('conversationId');
     $accountId = $this->getAccountId();
     $conversations = $cache->get('conversations' . $accountId);
     if ($conversations) {
         $lastChatConversation = ChatConversation::findByPk(new \MongoId($conversationId));
         if ($lastChatConversation->status === ChatConversation::STATUS_CLOSED) {
             throw new BadRequestHttpException('ChatConversation has been closed');
         }
         $client = $lastChatConversation->client;
         $clientOpenId = $lastChatConversation->client['openId'];
         $deskMongoId = $lastChatConversation->desk['id'];
         $deskId = (string) $deskMongoId;
         $targetDeskMongoId = new \MongoId($targetDeskId);
         $helpDesk = HelpDesk::findByPk($deskMongoId);
         $targetHelpDesk = HelpDesk::findByPk($targetDeskMongoId);
         $maxClientLimit = HelpDeskSetting::getMaxClientCount($accountId);
         if ($targetHelpDesk->clientCount >= $maxClientLimit) {
             throw new BadRequestHttpException('Target helpdesk has exceed the max serve number');
         }
         // Set the previous chat conversation status to 'closed'
         $lastChatConversation->status = ChatConversation::STATUS_CLOSED;
         if (!$lastChatConversation->update()) {
             LogUtil::error(['message' => 'Update previous helpdesk chatConversation status failed', 'error' => $lastChatConversation->errors], 'helpdesk');
             throw new ServerErrorHttpException('Update previous helpdesk chatConversation status failed');
         } else {
             HelpDesk::decClientCount($deskMongoId);
         }
         // Remove the client from original desk client list, and add to transfered desk client list
         foreach ($conversations[$deskId] as $index => $openId) {
             if ($openId == $clientOpenId) {
                 unset($conversations[$deskId][$index]);
             }
         }
         $conversations[$targetDeskId][] = $clientOpenId;
         Yii::$app->cache->set('conversations' . $accountId, $conversations);
         // Create chatConversation record in db
         $chatConversation = ChatConversation::saveRecord($targetHelpDesk, $client, ChatConversation::STATUS_OPEN, $accountId);
         // Generate response data
         $newChannelName = ChatConversation::getChannelName($targetDeskId, $clientOpenId);
         $lastChatTime = ChatConversation::getLastChatTime($targetDeskMongoId, $clientOpenId, $accountId);
         $chatTimes = ChatConversation::getChatTimes($clientOpenId, $accountId);
         $previousDesk = $lastChatConversation->desk;
         $previousDesk['id'] = $deskId;
         $desk = $chatConversation->desk;
         $desk['id'] = $targetDeskId;
         $data = ['conversationId' => (string) $chatConversation->_id, 'desk' => $desk, 'previousDesk' => $previousDesk, 'client' => $client, 'channel' => $newChannelName, 'lastChatTime' => $lastChatTime, 'chatTimes' => $chatTimes, 'startTime' => TimeUtil::msTime()];
         // Trigger transfer event to global channel, and the desk-client channel to make the client change listening channel
         Yii::$app->tuisongbao->triggerEvent(ChatConversation::EVENT_DESK_TRANSFER, $data, [ChatConversation::CHANNEL_GLOBAL . $accountId, $lastChatConversation->conversation]);
         // Push state
         $pushExtra = ['openId' => $clientOpenId, 'conversationId' => (string) $chatConversation->_id, 'previousDeskId' => $deskId, 'sentTime' => TimeUtil::msTime()];
         $previousDeskName = empty($previousDesk['name']) ? '' : $previousDesk['name'];
         $pushMessage = str_replace('{desk}', $previousDeskName, ChatConversation::PUSH_MESSAGE_TRANSFER);
         ChatConversation::pushMessage($previousDesk['id'], ChatConversation::EVENT_DESK_TRANSFER, $pushExtra);
         ChatConversation::pushMessage($desk['id'], ChatConversation::EVENT_DESK_TRANSFER, $pushExtra, $pushMessage);
         LogUtil::info(['event' => ChatConversation::EVENT_DESK_TRANSFER, 'desk' => $desk, 'previousDesk' => $previousDesk, 'client' => $client], 'helpdesk');
         return array_merge($data, ['status' => 'ok']);
     }
 }
コード例 #3
0
ファイル: HelpDesk.php プロジェクト: timelessmemory/uhkklp
 /**
  * HelpDesk offline
  * @param string $deskId
  * @param MongoId $accountId
  * @param  Object $extra
  * @return array
  */
 public static function leave($deskId, $accountId, $extra)
 {
     $cache = Yii::$app->cache;
     //remove it from conversation caches
     $conversations = $cache->get('conversations' . $accountId);
     unset($conversations[$deskId]);
     $cache->set('conversations' . $accountId, $conversations);
     //remove it from online caches
     self::cacheOnlineDesks($deskId, (string) $accountId, ChatConversation::EVENT_USER_REMOVED);
     //remove the helpdesk ping time
     $onlineHelpDesks = $cache->get(HelpDesk::CACHE_PREFIX_HELPDESK_PING . $accountId);
     unset($onlineHelpDesks[$deskId]);
     $cache->set(HelpDesk::CACHE_PREFIX_HELPDESK_PING . $accountId, $onlineHelpDesks);
     //get the conversation records in db according to the deskId
     $conversationInstances = ChatConversation::findOpenByDeskId(new \MongoId($deskId), $accountId);
     foreach ($conversationInstances as $conversationInstance) {
         $clientTemp = $conversationInstance->client;
         $desk = $conversationInstance->desk;
         //trigger deskLeft event
         $data = ['conversationId' => (string) $conversationInstance['_id'], 'desk' => $desk, 'client' => $clientTemp, 'extra' => $extra, 'sentTime' => TimeUtil::msTime()];
         $channels = [ChatConversation::getChannelName($deskId, $clientTemp['openId'])];
         Yii::$app->tuisongbao->triggerEvent(ChatConversation::EVENT_DESK_LEFT, $data, $channels);
         //set the status of the chatConversation to "closed"
         ChatConversation::closeById($conversationInstance['_id']);
         HelpDesk::sendSystemReplyByType($clientTemp, $accountId, isset($extra['type']) ? $extra['type'] : HelpDeskSetting::REPLY_CLOSE);
     }
     //flush the client count in db
     helpDesk::flushClientCount(new \MongoId($deskId));
     LogUtil::info(['event' => 'deskLeft', 'deskId' => $deskId], 'helpdesk');
     return ['status' => 'ok'];
 }