/**
  * Send out message
  *
  * <b>Request Type: </b>POST<br/>
  * <b>Content-Type: </b>application/json<br/>
  * <b>Request Endpoint: </b>http://{server-domain}/api/chat/conversation/message<br/>
  * <b>Summary: </b>This api is for post a message from helpDesk to client<br/>
  *
  * <b>Request Parameters: </b><br/>
  *     content: object, the content for the message<br/>
  *         content.msgType: string, "text"<br/>
  *         content.body: mixed, the body of the content<br/>
  *     isReply: boolean
  *     conversationId: string, the id of the conversation
  *
  * <b>Response Example</b>
  * <pre>{"status":"ok"}</pre>
  */
 public function actionMessage()
 {
     //parse the parameters
     $content = $this->getParams('content');
     $conversationId = $this->getParams('conversationId');
     $isReply = $this->getParams('isReply');
     $sentTime = TimeUtil::msTime();
     if (empty($content) || empty($conversationId)) {
         throw new BadRequestHttpException('Missing required fields');
     }
     $conversation = ChatConversation::findByPk(new \MongoId($conversationId));
     if (empty($conversation)) {
         throw new BadRequestHttpException("Illegal conversationId");
     }
     //Check conversation status
     if ($conversation->status == ChatConversation::STATUS_CLOSED) {
         throw new BadRequestHttpException('Conversation has been closed');
     }
     $accountId = $conversation->accountId;
     $client = $conversation->client;
     $desk = $conversation->desk;
     $desk['id'] = (string) $desk['id'];
     //Trigger the send message event
     $data = ['conversationId' => $conversationId, 'desk' => $desk, 'client' => $client, 'chatMessage' => ['content' => $content, 'sentTime' => $sentTime], 'isReply' => $isReply];
     //Add chatMessage record
     $chatMessage = ChatMessage::saveRecord($content, $sentTime, $isReply, $conversation->_id, $accountId);
     //Trigger client message
     $channels = [ChatConversation::getChannelName($desk['id'], $client['openId'])];
     $data['messageId'] = (string) $chatMessage->_id;
     Yii::$app->tuisongbao->triggerEvent(ChatConversation::EVENT_CHAT_MESSAGE, $data, $channels);
     //Send message based on the client source type
     switch ($client['source']) {
         case ChatConversation::TYPE_WEBSITE:
             if (!$isReply) {
                 //helpDesk mobile client message
                 $pushExtra = ['messageId' => (string) $chatMessage->_id, 'openId' => $client['openId'], 'conversationId' => (string) $conversationId, 'sentTime' => $chatMessage->sentTime];
                 $pushMessage = empty($client['nick']) ? $content['body'] : $client['nick'] . ':' . $content['body'];
                 ChatConversation::pushMessage($desk['id'], ChatConversation::EVENT_CHAT_MESSAGE, $pushExtra, $pushMessage);
             }
             break;
         case ChatConversation::TYPE_WECHAT:
         case ChatConversation::TYPE_WEIBO:
         case ChatConversation::TYPE_ALIPAY:
             $message = ['msgType' => $content['msgType'], 'content' => $content['body'], 'createTime' => $sentTime];
             Yii::$app->weConnect->sendCustomerServiceMessage($client['openId'], $client['sourceChannel'], $message);
             break;
         default:
             throw new BadRequestHttpException('Unsupported source type');
             break;
     }
     return ['status' => 'ok', 'sentTime' => $sentTime];
 }
Exemplo n.º 2
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);
     }
 }