/** * 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']); } }
/** * Initialize the conversation between helpdesk and client under an account. * Update redis cache and store the chat conversations in mongodb * @param array $conversations the conversations stored in redis cache * @param array $client the client information, containing openId, nick, avatar * @param string $deskId the helpdesk UUID * @param MongoId $accountId the account UUID * @return array response for pushing clientJoined state and connect event for wechat */ public static function createConnection($client, $deskId, $accountId) { //update the conversation information in cache $conversations = Yii::$app->cache->get('conversations' . $accountId); $conversations[$deskId][] = $client['openId']; Yii::$app->cache->set('conversations' . $accountId, $conversations); //get the helpDesk information $deskMongoId = new \MongoId($deskId); $helpDesk = HelpDesk::findOne(['_id' => $deskMongoId]); //create chatConversation record in db $chatConversation = ChatConversation::saveRecord($helpDesk, $client, ChatConversation::STATUS_OPEN, $accountId); //get the history statistics $lastChatTime = ChatConversation::getLastChatTime($deskMongoId, $client['openId'], $accountId); $previousChatTime = ChatConversation::getLastChatTime($deskMongoId, $client['openId'], $accountId, 1); $chatTimes = ChatConversation::getChatTimes($client['openId'], $accountId); //trigger the client joined event $desk = $chatConversation->desk; $desk['id'] = $deskId; $channelName = ChatConversation::getChannelName($deskId, $client['openId']); $data = ['conversationId' => (string) $chatConversation->_id, 'desk' => $desk, 'client' => $client, 'channel' => $channelName, 'lastChatTime' => $lastChatTime, 'previousChatTime' => $previousChatTime, 'chatTimes' => $chatTimes, 'startTime' => TimeUtil::msTime()]; Yii::$app->tuisongbao->triggerEvent(ChatConversation::EVENT_CLIENT_JOINED, $data, [ChatConversation::CHANNEL_GLOBAL . $accountId]); self::sendSystemReplyByType($client, $accountId, HelpDeskSetting::REPLY_SUCCESS); //push the client join event to helpdesk when helpdesk login in mobile $pushExtra = ['openId' => $client['openId'], 'conversationId' => (string) $chatConversation->_id, 'sentTime' => TimeUtil::msTime()]; $pushMessage = ChatConversation::PUSH_MESSAGE_NEW_CLIENT; ChatConversation::pushMessage($desk['id'], ChatConversation::EVENT_CLIENT_JOINED, $pushExtra, $pushMessage); LogUtil::info(['event' => ChatConversation::EVENT_CLIENT_JOINED, 'desk' => $helpDesk->toArray(), 'client' => $client], 'helpdesk'); return array_merge($data, ['status' => 'ok']); }