Пример #1
0
 /**
  * @args {"description": "Delay: Clean offline client and helpdesk every minute"}
  */
 public function perform()
 {
     $accounts = Account::findAll([]);
     foreach ($accounts as $account) {
         $accountId = $account->_id;
         $setting = HelpDeskSetting::findOne(['accountId' => $accountId]);
         if (!empty($setting)) {
             $maxWaitTime = $setting->maxWaitTime;
             // Close timeout conversation
             $chatConversations = ChatConversation::findAll(['accountId' => $accountId, 'status' => ChatConversation::STATUS_OPEN, 'lastChatTime' => ['$lt' => TimeUtil::msTime(time() - $maxWaitTime * 60)]]);
             foreach ($chatConversations as $chatConversation) {
                 HelpDesk::disconnect($chatConversation->_id, ['type' => 'brake']);
             }
             // Delete timeout pending client
             $pendingClients = PendingClient::findAll(['accountId' => $accountId, 'lastPingTime' => ['$lt' => TimeUtil::msTime(time() - PendingClient::PING_THRESHOLD)]]);
             foreach ($pendingClients as $pendingClient) {
                 $pendingClient->delete();
             }
             // Clean offline helpdesk
             $cache = Yii::$app->cache;
             $onlineHelpDesks = $cache->get(HelpDesk::CACHE_PREFIX_HELPDESK_PING . $accountId);
             if (!empty($onlineHelpDesks)) {
                 foreach ($onlineHelpDesks as $deskId => $lastPingTime) {
                     if ($lastPingTime < TimeUtil::msTime(time() - HelpDesk::PING_THRESHOLD)) {
                         HelpDesk::leave($deskId, $accountId, ['type' => 'droping']);
                     }
                 }
             }
         }
     }
 }
Пример #2
0
 public function actionIndex()
 {
     $accountId = $this->getAccountId();
     $currentHelpdeskId = $this->getUserId();
     $query = HelpDesk::find();
     $clientOpenId = $this->getQuery('clientOpenId');
     if ($orderBy = $this->getQuery('orderBy')) {
         if (StringUtil::isJson($orderBy)) {
             $orderBy = Json::decode($orderBy, true);
             foreach ($orderBy as $key => $value) {
                 if ($value === 'asc' || $value === 'ASC') {
                     $orderBy[$key] = SORT_ASC;
                 } else {
                     $orderBy[$key] = SORT_DESC;
                 }
             }
         } else {
             $orderBy = [$orderBy => SORT_DESC];
         }
         $query->orderBy($orderBy);
     }
     $allHelpdesks = $query->where(['accountId' => $accountId, 'isDeleted' => false, 'isActivated' => true, 'isEnabled' => true])->andWhere(['not in', '_id', [$currentHelpdeskId]])->orderBy(['clientCount' => SORT_ASC])->all();
     $result = [];
     if ($allHelpdesks) {
         foreach ($allHelpdesks as $helpdesk) {
             array_push($result, $helpdesk->toArray());
         }
     }
     $lastChatConversation = ChatConversation::getLastChatByClient($clientOpenId, $currentHelpdeskId, $accountId);
     if ($lastChatConversation) {
         $lastServeHelpdeskId = (string) $lastChatConversation->desk['id'];
         if (!empty($result)) {
             $allOnlineHelpdesks = [];
             foreach ($result as $index => $item) {
                 if ($item['isOnline'] && $item['id'] === $lastServeHelpdeskId) {
                     $item['isLastChat'] = true;
                     array_unshift($allOnlineHelpdesks, $item);
                 } else {
                     if ($item['isOnline']) {
                         array_push($allOnlineHelpdesks, $item);
                     }
                 }
             }
             $result = $allOnlineHelpdesks;
         }
     }
     return $result;
 }
Пример #3
0
 /**
  * Login
  *
  * <b>Request Type</b>: POST<br/><br/>
  * <b>Request Endpoint</b>:http://{server-domain}/chat/site/login<br/><br/>
  * <b>Content-type</b>: application/json<br/><br/>
  * <b>Summary</b>: This api is used for the help desk to login.
  * <br/><br/>
  *
  * <b>Request Params</b>:<br/>
  *     email: string, the user email, required<br/>
  *     password: string, the user password, required<br/>
  *     <br/><br/>
  *
  * <b>Response Params:</b><br/>
  *     ack: integer, mark the create result, 0 means create successfully, 1 means create fail<br/>
  *     msg: string, if create fail, it contains the error message<br/>
  *     data: array, json array to describe the users detail information<br/>
  *     <br/><br/>
  *
  * <b>Request Example:</b><br/>
  * <pre>
  * {
  *     "email"    : "*****@*****.**",
  *     "password" : "abc123"
  * }
  * </pre>
  * <br/><br/>
  *
  * <b>Response Example</b>:<br/>
  * <pre>
  * {
  *    'ack'  : 1,
  *    'data' : {
  *        "accessToken" : "7f2d1e92-9629-8429-00be-2d9c6d64acdb",
  *        "userInfo"    : {
  *            "name"   : "harry",
  *            "avatar" : "path/to/avatar"
  *        }
  *    }
  * }
  * </pre>
  */
 public function actionLogin()
 {
     $params = $this->getParams();
     $deviceToken = $this->getParams('deviceToken');
     $environment = $this->getParams('environment');
     if (empty($params['email']) || empty($params['password'])) {
         throw new BadRequestHttpException("parameters missing");
     }
     $helpdesk = HelpDesk::getByEmail($params['email']);
     if (empty($helpdesk)) {
         throw new ForbiddenHttpException("用戶不存在");
     }
     if (!$helpdesk->isActivated) {
         throw new ForbiddenHttpException("用戶未激活,请激活后使用");
     }
     if (!$helpdesk->isEnabled) {
         throw new ForbiddenHttpException("该账号已被禁用,请与管理员联系");
     }
     if ($helpdesk->validatePassword($params['password'])) {
         $tokens = Token::getUnexpiredByUserId($helpdesk->_id);
         if (!empty($tokens)) {
             $data = ['isForcedOffline' => true, 'id' => $helpdesk->_id . ''];
             $accountId = $tokens[0]->accountId;
             Yii::$app->tuisongbao->triggerEvent(ChatConversation::EVENT_FORCED_OFFLINE, $data, [ChatConversation::CHANNEL_GLOBAL . $accountId]);
             //deviceToken changed, push forcedOffline
             if (empty($deviceToken) && !empty($helpdesk->deviceToken) || !empty($deviceToken) && !empty($helpdesk->deviceToken) && $deviceToken != $helpdesk->deviceToken) {
                 $extra = ['deskId' => $helpdesk->_id . '', 'sentTime' => TimeUtil::msTime()];
                 ChatConversation::pushMessage($helpdesk->_id, ChatConversation::EVENT_FORCED_OFFLINE, $extra);
             }
             Token::updateAll(['$set' => ['expireTime' => new \MongoDate()]], ['_id' => ['$in' => Token::getIdList($tokens)]]);
         }
         $isFirstLogin = empty($helpdesk->lastLoginAt);
         $accessToken = Token::createByHelpDesk($helpdesk);
         if (isset($deviceToken)) {
             $helpdesk->loginDevice = HelpDesk::MOBILEAPP;
         } else {
             $helpdesk->loginDevice = HelpDesk::BROWSER;
         }
         $helpdesk->deviceToken = $deviceToken;
         $helpdesk->environment = $environment;
         $helpdesk->lastLoginAt = new \MongoDate();
         $helpdesk->save(true, ['deviceToken', 'loginDevice', 'environment', 'lastLoginAt']);
         $userInfo = ['badge' => $helpdesk->badge, 'name' => $helpdesk->name, 'email' => $helpdesk->email, 'language' => $helpdesk->language, 'avatar' => empty($helpdesk->avatar) ? '' : $helpdesk->avatar, 'id' => (string) $helpdesk->_id, 'accountId' => (string) $helpdesk['accountId'], 'notificationType' => $helpdesk->notificationType, 'isFirstLogin' => $isFirstLogin];
         return ["accessToken" => $accessToken['accessToken'], 'userInfo' => $userInfo];
     } else {
         throw new ForbiddenHttpException("密码错误");
     }
 }
Пример #4
0
 public function actionIndex()
 {
     $deskId = $this->getQuery('deskId');
     $clientOpenId = $this->getQuery('clientOpenId');
     $sentTime = $this->getQuery('sentTime');
     $page = $this->getQuery('page', 1);
     $perPage = $this->getQuery('per-page', 10);
     $start = ($page - 1) * $perPage;
     if (empty($clientOpenId) || empty($deskId) || !isset($sentTime)) {
         throw new BadRequestHttpException('Missing required fields');
     }
     $accountId = $this->getAccountId();
     $conversations = ChatConversation::getByClient($clientOpenId, $accountId, new \MongoId($deskId));
     $conversationIds = ChatConversation::getIdList($conversations);
     $chatMessages = ChatMessage::getByConversations($conversationIds, $perPage, $start, $sentTime);
     $messages = [];
     foreach ($chatMessages as $chatMessage) {
         $messages[] = ['conversationId' => $chatMessage['conversationId'] . '', 'messageId' => $chatMessage->_id . '', 'content' => $chatMessage['content'], 'isReply' => $chatMessage['isReply'], 'sentTime' => $chatMessage['sentTime']];
     }
     return $messages;
 }
 public function actionIndex()
 {
     $params = $this->getQuery();
     if (empty($params['memberId'])) {
         throw new BadRequestHttpException(Yii::t('common', 'parameters_missing'));
     }
     //get members openIds
     $member = Member::findByPk(new MongoId($params['memberId']));
     $openIds = empty($member->socials) ? [] : ArrayHelper::getColumn($member->socials, 'openId');
     $openIds[] = $member->openId;
     //get lastChatDate
     $lastConversation = ChatConversation::getLastByOpenIds($openIds);
     $lastChatDate = empty($lastConversation) ? '' : $lastConversation->date;
     //get conversations
     $params['openIds'] = $openIds;
     $accountId = $this->getAccountId();
     $conversations = ChatConversation::search($params, $accountId);
     $result = $this->serializeData($conversations);
     $result['lastChatDate'] = $lastChatDate;
     return $result;
 }
 public function actionStatistics()
 {
     $startTime = $this->getQuery('startTime');
     $endTime = $this->getQuery('endTime');
     $accountId = $this->getAccountId();
     $condition = ['accountId' => $accountId, 'isDeleted' => BaseModel::NOT_DELETED];
     if (!empty($startTime) && !empty($endTime)) {
         $condition['createdAt'] = ['$gt' => new \MongoDate(TimeUtil::ms2sTime($startTime)), '$lt' => new \MongoDate(TimeUtil::ms2sTime($endTime))];
     }
     //get the original statistics from db.(raw data)
     $clientCount = ChatConversation::getClientCount($condition);
     $conversationCount = ChatConversation::count($condition);
     $clientMessageCount = ChatMessage::countClientMessage($condition);
     $conversationDailyStatistics = ChatConversation::getDailyData($condition);
     $messageDailyStatistics = ChatMessage::getDailyData($condition);
     //format the statistics for chart
     $categories = [];
     $messageCountSeries = [];
     $clientCountSeries = [];
     $conversationCountSeries = [];
     foreach ($conversationDailyStatistics as $conversationDay) {
         foreach ($messageDailyStatistics as $messageDay) {
             if ($conversationDay['date'] == $messageDay['date']) {
                 $conversationDay['messageCount'] = $messageDay['messageCount'];
             }
         }
         if (empty($conversationDay['messageCount'])) {
             $conversationDay['messageCount'] = 0;
         }
         $categories[] = $conversationDay['date'];
         $messageCountSeries[] = $conversationDay['messageCount'];
         $clientCountSeries[] = $conversationDay['clientCount'];
         $conversationCountSeries[] = $conversationDay['conversationCount'];
     }
     $statistics = ['categories' => $categories, 'series' => [['name' => 'helpdesk_users_count', 'data' => $clientCountSeries], ['name' => 'helpdesk_sessions_count', 'data' => $conversationCountSeries], ['name' => 'helpdesk_sent_message_count', 'data' => $messageCountSeries]]];
     return ['clientCount' => $clientCount, 'conversationCount' => $conversationCount, 'clientMessageCount' => $clientMessageCount, 'statistics' => $statistics];
 }
 /**
  * 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']);
     }
 }
Пример #8
0
 public static function saveRecord($desk, $client, $status, $accountId)
 {
     $chatConversation = new ChatConversation();
     $channelName = self::getChannelName($desk->_id, $client['openId']);
     $chatConversation->conversation = $channelName;
     $chatConversation->status = $status;
     $chatConversation->desk = ['id' => $desk->_id, 'badge' => $desk->badge, 'email' => $desk->email, 'avatar' => $desk->avatar, 'name' => $desk->name];
     $chatConversation->client = $client;
     $chatConversation->accountId = $accountId;
     $chatConversation->lastChatTime = TimeUtil::msTime();
     if (!$chatConversation->save()) {
         LogUtil::error(['message' => 'save chat conversation failed', 'error' => $chatConversation->errors], 'helpdesk');
         throw new ServerErrorHttpException('save chatConversation failed');
     } else {
         HelpDesk::incClientCount($desk->_id);
     }
     return $chatConversation;
 }
Пример #9
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);
     }
 }
Пример #10
0
 public static function saveRecord($content, $sentTime, $isReply, $conversationId, $accountId)
 {
     $chatMessage = new ChatMessage();
     $chatMessage->content = $content;
     $chatMessage->sentTime = $sentTime;
     $chatMessage->isReply = $isReply;
     $chatMessage->conversationId = $conversationId;
     $chatMessage->accountId = $accountId;
     if (!$chatMessage->save()) {
         LogUtil::error(['message' => 'save chatMessage failed', 'error' => $chatMessage->errors], 'helpdesk');
         throw new ServerErrorHttpException('save chatConversation failed');
     }
     //update the lastChatTime for chatConversation
     ChatConversation::setLastChatTime($sentTime, $conversationId);
     return $chatMessage;
 }
Пример #11
0
 /**
  * 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'];
 }