/** * Used for tuisongbao web hook, realtime engine will call the service when user subscribe or unsubscribe a channel * @return string json status */ public function actionUserState() { $body = $this->getParams(); $headers = Yii::$app->request->getHeaders(); $signature = hash_hmac('sha256', json_encode($body), TUISONGBAO_SECRET); LogUtil::info(['body' => $body, 'signature' => $signature], 'webhook'); // Check whether it is called by the tuisongbao web hook if ($signature === $headers['X-Engine-Signature']) { //TODO: First event may not be the correct one $time = $body['timestamp']; $event = $body['events'][0]; $userId = $event['userId']; $eventName = $event['name']; //Tip: Only handle the user_removed event on global channel here if (strpos($event['channel'], ChatConversation::CHANNEL_GLOBAL) !== false && ChatConversation::MONGOID_LENGTH === strlen($userId)) { $helpdesk = HelpDesk::findByPk(new \MongoId($userId)); if (!empty($helpdesk)) { if ($eventName == ChatConversation::EVENT_USER_ADDED || $eventName == ChatConversation::EVENT_USER_REMOVED) { $updateTimePrefix = 'wm-update-time'; $cache = Yii::$app->cache; $lastTime = $cache->get($updateTimePrefix . $userId); // failed events will be send again, but timestamp will not change // if a event is failed and other event has success, skip that failed event // Event_1. user_add failed; Event_2, user_remove successed; Event_1. user_add successed // skip Event_1. user_add successed if (empty($lastTime) || $lastTime < $time) { $cache->set($updateTimePrefix . $userId, $time); HelpDesk::cacheOnlineDesks($helpdesk->_id . '', $helpdesk->accountId . '', $eventName); } } } } } }