%PDF- %PDF-
Direktori : /proc/self/root/home/bitrix/www/bitrix/modules/im/lib/ |
Current File : //proc/self/root/home/bitrix/www/bitrix/modules/im/lib/bot.php |
<?php namespace Bitrix\Im; use Bitrix\Main, Bitrix\Main\Localization\Loc; Loc::loadMessages(__FILE__); class Bot { const INSTALL_TYPE_SYSTEM = 'system'; const INSTALL_TYPE_USER = 'user'; const INSTALL_TYPE_SILENT = 'silent'; const LOGIN_START = 'bot_'; const EXTERNAL_AUTH_ID = 'bot'; const LIST_ALL = 'all'; const LIST_OPENLINE = 'openline'; const TYPE_HUMAN = 'H'; const TYPE_BOT = 'B'; const TYPE_SUPERVISOR = 'S'; const TYPE_NETWORK = 'N'; const TYPE_OPENLINE = 'O'; const CACHE_TTL = 31536000; const CACHE_PATH = '/bx/im/bot/'; public static function register(array $fields) { $code = isset($fields['CODE'])? $fields['CODE']: ''; $type = in_array($fields['TYPE'], Array(self::TYPE_HUMAN, self::TYPE_BOT, self::TYPE_SUPERVISOR, self::TYPE_NETWORK, self::TYPE_OPENLINE))? $fields['TYPE']: self::TYPE_BOT; $moduleId = $fields['MODULE_ID']; $installType = in_array($fields['INSTALL_TYPE'], Array(self::INSTALL_TYPE_SYSTEM, self::INSTALL_TYPE_USER, self::INSTALL_TYPE_SILENT))? $fields['INSTALL_TYPE']: self::INSTALL_TYPE_SILENT; $botFields = $fields['PROPERTIES']; $language = isset($fields['LANG'])? $fields['LANG']: null; /* vars for module install */ $class = isset($fields['CLASS'])? $fields['CLASS']: ''; $methodBotDelete = isset($fields['METHOD_BOT_DELETE'])? $fields['METHOD_BOT_DELETE']: ''; $methodMessageAdd = isset($fields['METHOD_MESSAGE_ADD'])? $fields['METHOD_MESSAGE_ADD']: ''; $methodMessageUpdate = isset($fields['METHOD_MESSAGE_UPDATE'])? $fields['METHOD_MESSAGE_UPDATE']: ''; $methodMessageDelete = isset($fields['METHOD_MESSAGE_DELETE'])? $fields['METHOD_MESSAGE_DELETE']: ''; $methodWelcomeMessage = isset($fields['METHOD_WELCOME_MESSAGE'])? $fields['METHOD_WELCOME_MESSAGE']: ''; $textPrivateWelcomeMessage = isset($fields['TEXT_PRIVATE_WELCOME_MESSAGE'])? $fields['TEXT_PRIVATE_WELCOME_MESSAGE']: ''; $textChatWelcomeMessage = isset($fields['TEXT_CHAT_WELCOME_MESSAGE'])? $fields['TEXT_CHAT_WELCOME_MESSAGE']: ''; $openline = isset($fields['OPENLINE']) && $fields['OPENLINE'] == 'Y'? 'Y': 'N'; /* rewrite vars for openline type */ if ($type == self::TYPE_OPENLINE) { $openline = 'Y'; $installType = self::INSTALL_TYPE_SILENT; } /* vars for rest install */ $appId = isset($fields['APP_ID'])? $fields['APP_ID']: ''; $verified = isset($fields['VERIFIED']) && $fields['VERIFIED'] == 'Y'? 'Y': 'N'; if ($moduleId == 'rest') { if (empty($appId)) { return false; } } else { if (empty($class) || empty($methodMessageAdd)) { return false; } if (!(!empty($methodWelcomeMessage) || isset($fields['TEXT_PRIVATE_WELCOME_MESSAGE']))) { return false; } } $bots = self::getListCache(); if ($moduleId && $code) { foreach ($bots as $bot) { if ($bot['MODULE_ID'] == $moduleId && $bot['CODE'] == $code) { return $bot['BOT_ID']; } } } $userCode = $code? $moduleId.'_'.$code: $moduleId; $color = null; if (isset($botFields['COLOR'])) { $color = $botFields['COLOR']; unset($botFields['COLOR']); } $userId = 0; if ($installType == self::INSTALL_TYPE_USER) { if (isset($fields['USER_ID']) && intval($fields['USER_ID']) > 0) { $userId = intval($fields['USER_ID']); } else { global $USER; if (is_object($USER)) { $userId = $USER->GetID() > 0? $USER->GetID(): 0; } } if ($userId <= 0) { $installType = self::INSTALL_TYPE_SYSTEM; } } if (strlen($moduleId) <= 0) { return false; } if (!(isset($botFields['NAME']) || isset($botFields['LAST_NAME']))) { return false; } $botFields['LOGIN'] = substr(self::LOGIN_START.$userCode.'_'.randString(5), 0, 50); $botFields['PASSWORD'] = md5($botFields['LOGIN'].'|'.rand(1000,9999).'|'.time()); $botFields['CONFIRM_PASSWORD'] = $botFields['PASSWORD']; $botFields['EXTERNAL_AUTH_ID'] = self::EXTERNAL_AUTH_ID; unset($botFields['GROUP_ID']); $botFields['ACTIVE'] = 'Y'; if (IsModuleInstalled('intranet')) { $botFields['UF_DEPARTMENT'] = Array(\Bitrix\Im\Bot\Department::getId()); } else { unset($botFields['UF_DEPARTMENT']); } $botFields['WORK_POSITION'] = isset($botFields['WORK_POSITION'])? trim($botFields['WORK_POSITION']): ''; if (empty($botFields['WORK_POSITION'])) { $botFields['WORK_POSITION'] = Loc::getMessage('BOT_DEFAULT_WORK_POSITION'); } $user = new \CUser; $botId = $user->Add($botFields); if (!$botId) { return false; } $result = \Bitrix\Im\Model\BotTable::add(Array( 'BOT_ID' => $botId, 'CODE' => $code? $code: $botId, 'MODULE_ID' => $moduleId, 'CLASS' => $class, 'TYPE' => $type, 'LANG' => $language? $language: '', 'METHOD_BOT_DELETE' => $methodBotDelete, 'METHOD_MESSAGE_ADD' => $methodMessageAdd, 'METHOD_MESSAGE_UPDATE' => $methodMessageUpdate, 'METHOD_MESSAGE_DELETE' => $methodMessageDelete, 'METHOD_WELCOME_MESSAGE' => $methodWelcomeMessage, 'TEXT_PRIVATE_WELCOME_MESSAGE' => $textPrivateWelcomeMessage, 'TEXT_CHAT_WELCOME_MESSAGE' => $textChatWelcomeMessage, 'APP_ID' => $appId, 'VERIFIED' => $verified, 'OPENLINE' => $openline )); $cache = \Bitrix\Main\Data\Cache::createInstance(); $cache->cleanDir(self::CACHE_PATH); if ($result->isSuccess()) { if (\Bitrix\Main\Loader::includeModule('pull')) { $botForJs = self::getListForJs(); if ($color) { \CIMStatus::SetColor($botId, $color); } $userData = \CIMContactList::GetUserData(array( 'ID' => $botId, 'DEPARTMENT' => 'Y', 'USE_CACHE' => 'N', 'SHOW_ONLINE' => 'N', 'PHONES' => 'N' ) ); \CPullStack::AddShared(Array( 'module_id' => 'im', 'command' => 'addBot', 'params' => Array( 'bot' => $botForJs[$botId], 'user' => $userData['users'][$botId], 'userInGroup' => $userData['userInGroup'], ), 'extra' => \Bitrix\Im\Common::getPullExtra() )); if ($installType != self::INSTALL_TYPE_SILENT) { $message = ''; if ($installType == self::INSTALL_TYPE_USER && \Bitrix\Im\User::getInstance($userId)->isExists()) { $userName = \Bitrix\Im\User::getInstance($userId)->getFullName(); $userName = '[USER='.$userId.']'.$userName.'[/USER]'; $userGender = \Bitrix\Im\User::getInstance($userId)->getGender(); $message = Loc::getMessage('BOT_MESSAGE_INSTALL_USER'.($userGender == 'F'? '_F':''), Array('#USER_NAME#' => $userName)); } if (empty($message)) { $message = Loc::getMessage('BOT_MESSAGE_INSTALL_SYSTEM'); } $attach = new \CIMMessageParamAttach(null, $color); $attach->AddBot(Array( "NAME" => \Bitrix\Im\User::getInstance($botId)->getFullName(), "AVATAR" => \Bitrix\Im\User::getInstance($botId)->getAvatar(), "BOT_ID" => $botId, )); $attach->addMessage(\Bitrix\Im\User::getInstance($botId)->getWorkPosition()); \CIMChat::AddGeneralMessage(Array( 'MESSAGE' => $message, 'ATTACH' => $attach )); } } \Bitrix\Main\Application::getInstance()->getTaggedCache()->clearByTag("IM_CONTACT_LIST"); } else { $user->Delete($botId); $botId = 0; } return $botId; } public static function unRegister(array $bot) { $botId = intval($bot['BOT_ID']); $moduleId = isset($bot['MODULE_ID'])? $bot['MODULE_ID']: ''; $appId = isset($bot['APP_ID'])? $bot['APP_ID']: ''; if (intval($botId) <= 0) return false; $bots = self::getListCache(); if (!isset($bots[$botId])) return false; if (strlen($moduleId) > 0 && $bots[$botId]['MODULE_ID'] != $moduleId) return false; if (strlen($appId) > 0 && $bots[$botId]['APP_ID'] != $appId) return false; \Bitrix\Im\Model\BotTable::delete($botId); $orm = \Bitrix\Im\Model\BotChatTable::getList(Array( 'filter' => Array('=BOT_ID' => $botId) )); if ($row = $orm->fetch()) { \Bitrix\Im\Model\BotChatTable::delete($row['ID']); } $cache = \Bitrix\Main\Data\Cache::createInstance(); $cache->cleanDir(self::CACHE_PATH); $user = new \CUser; $user->Delete($botId); if (\Bitrix\Main\Loader::includeModule($bots[$botId]['MODULE_ID']) && $bots[$botId]["METHOD_BOT_DELETE"] && class_exists($bots[$botId]["CLASS"]) && method_exists($bots[$botId]["CLASS"], $bots[$botId]["METHOD_BOT_DELETE"])) { call_user_func_array(array($bots[$botId]["CLASS"], $bots[$botId]["METHOD_BOT_DELETE"]), Array($botId)); } foreach(\Bitrix\Main\EventManager::getInstance()->findEventHandlers("im", "onImBotDelete") as $event) { ExecuteModuleEventEx($event, Array($bots[$botId], $botId)); } $orm = \Bitrix\Im\Model\CommandTable::getList(Array( 'filter' => Array('=BOT_ID' => $botId) )); while ($row = $orm->fetch()) { \Bitrix\Im\Command::unRegister(Array('COMMAND_ID' => $row['ID'], 'FORCE' => 'Y')); } $orm = \Bitrix\Im\Model\AppTable::getList(Array( 'filter' => Array('=BOT_ID' => $botId) )); while ($row = $orm->fetch()) { \Bitrix\Im\App::unRegister(Array('ID' => $row['ID'], 'FORCE' => 'Y')); } if (\Bitrix\Main\Loader::includeModule('pull')) { \CPullStack::AddShared(Array( 'module_id' => 'im', 'command' => 'deleteBot', 'params' => Array( 'botId' => $botId ), 'extra' => \Bitrix\Im\Common::getPullExtra() )); } \Bitrix\Main\Application::getInstance()->getTaggedCache()->clearByTag("IM_CONTACT_LIST"); return true; } public static function update(array $bot, array $updateFields) { $botId = intval($bot['BOT_ID']); $moduleId = isset($bot['MODULE_ID'])? $bot['MODULE_ID']: ''; $appId = isset($bot['APP_ID'])? $bot['APP_ID']: ''; if ($botId <= 0) return false; if (!\Bitrix\Im\User::getInstance($botId)->isExists() || !\Bitrix\Im\User::getInstance($botId)->isBot()) return false; $bots = self::getListCache(); if (!isset($bots[$botId])) return false; if (strlen($moduleId) > 0 && $bots[$botId]['MODULE_ID'] != $moduleId) return false; if (strlen($appId) > 0 && $bots[$botId]['APP_ID'] != $appId) return false; if (isset($updateFields['PROPERTIES'])) { $update = $updateFields['PROPERTIES']; // update user properties unset($update['ACTIVE']); unset($update['LOGIN']); unset($update['PASSWORD']); unset($update['CONFIRM_PASSWORD']); unset($update['EXTERNAL_AUTH_ID']); unset($update['GROUP_ID']); unset($update['UF_DEPARTMENT']); if (isset($update['NAME']) && strlen(trim($update['NAME'])) <= 0) { unset($update['NAME']); } if (isset($update['WORK_POSITION']) && strlen(trim($update['WORK_POSITION'])) <= 0) { $update['WORK_POSITION'] = Loc::getMessage('BOT_DEFAULT_WORK_POSITION'); } $user = new \CUser; $user->Update($botId, $update); } $update = Array(); if (isset($updateFields['CLASS']) && !empty($updateFields['CLASS'])) { $update['CLASS'] = $updateFields['CLASS']; } if (isset($updateFields['CODE']) && !empty($updateFields['CODE'])) { $update['CODE'] = $updateFields['CODE']; } if (isset($updateFields['LANG'])) { $update['LANG'] = $updateFields['LANG']? $updateFields['LANG']: ''; } if (isset($updateFields['METHOD_BOT_DELETE'])) { $update['METHOD_BOT_DELETE'] = $updateFields['METHOD_BOT_DELETE']; } if (isset($updateFields['METHOD_MESSAGE_ADD'])) { $update['METHOD_MESSAGE_ADD'] = $updateFields['METHOD_MESSAGE_ADD']; } if (isset($updateFields['METHOD_MESSAGE_UPDATE'])) { $update['METHOD_MESSAGE_UPDATE'] = $updateFields['METHOD_MESSAGE_UPDATE']; } if (isset($updateFields['METHOD_MESSAGE_DELETE'])) { $update['METHOD_MESSAGE_DELETE'] = $updateFields['METHOD_MESSAGE_DELETE']; } if (isset($updateFields['METHOD_WELCOME_MESSAGE'])) { $update['METHOD_WELCOME_MESSAGE'] = $updateFields['METHOD_WELCOME_MESSAGE']; } if (isset($updateFields['TEXT_PRIVATE_WELCOME_MESSAGE'])) { $update['TEXT_PRIVATE_WELCOME_MESSAGE'] = $updateFields['TEXT_PRIVATE_WELCOME_MESSAGE']; } if (isset($updateFields['TEXT_CHAT_WELCOME_MESSAGE'])) { $update['TEXT_CHAT_WELCOME_MESSAGE'] = $updateFields['TEXT_CHAT_WELCOME_MESSAGE']; } if (isset($updateFields['VERIFIED'])) { $update['VERIFIED'] = $updateFields['VERIFIED'] == 'Y'? 'Y': 'N'; } if (!empty($update)) { \Bitrix\Im\Model\BotTable::update($botId, $update); $cache = \Bitrix\Main\Data\Cache::createInstance(); $cache->cleanDir(self::CACHE_PATH); } if (\Bitrix\Main\Loader::includeModule('pull')) { $botForJs = self::getListForJs(); $userData = \CIMContactList::GetUserData(array( 'ID' => $botId, 'DEPARTMENT' => 'Y', 'USE_CACHE' => 'N', 'SHOW_ONLINE' => 'N', 'PHONES' => 'N' ) ); \CPullStack::AddShared(Array( 'module_id' => 'im', 'command' => 'updateBot', 'params' => Array( 'bot' => $botForJs[$botId], 'user' => $userData['users'][$botId], 'userInGroup' => $userData['userInGroup'], ), 'extra' => \Bitrix\Im\Common::getPullExtra() )); } \Bitrix\Main\Application::getInstance()->getTaggedCache()->clearByTag("IM_CONTACT_LIST"); return true; } public static function onMessageAdd($messageId, $messageFields) { $botExecModule = self::getBotsForMessage($messageFields); if (!$botExecModule) return true; if ($messageFields['MESSAGE_TYPE'] != IM_MESSAGE_PRIVATE) { $messageFields['MESSAGE_ORIGINAL'] = $messageFields['MESSAGE']; if (preg_match("/\[USER=([0-9]{1,})\](.*?)\[\/USER\]/i", $messageFields['MESSAGE'], $matches)) { $messageFields['TO_USER_ID'] = $matches[1]; } else { $messageFields['TO_USER_ID'] = 0; } $messageFields['MESSAGE'] = trim(preg_replace('#\[(?P<tag>USER)=\d+\].+?\[/(?P=tag)\],?#', '', $messageFields['MESSAGE'])); } $messageFields['DIALOG_ID'] = \Bitrix\Im\Bot::getDialogId($messageFields); $messageFields = self::removeFieldsToEvent($messageFields); foreach ($botExecModule as $params) { if (!$params['MODULE_ID'] || !\Bitrix\Main\Loader::includeModule($params['MODULE_ID'])) continue; $messageFields['BOT_ID'] = $params['BOT_ID']; if ($params["METHOD_MESSAGE_ADD"] && class_exists($params["CLASS"]) && method_exists($params["CLASS"], $params["METHOD_MESSAGE_ADD"])) { \Bitrix\Im\Model\BotTable::update($params['BOT_ID'], array( "COUNT_MESSAGE" => new \Bitrix\Main\DB\SqlExpression("?# + 1", "COUNT_MESSAGE") )); call_user_func_array(array($params["CLASS"], $params["METHOD_MESSAGE_ADD"]), Array($messageId, $messageFields)); } else if (class_exists($params["CLASS"]) && method_exists($params["CLASS"], "onMessageAdd")) { call_user_func_array(array($params["CLASS"], "onMessageAdd"), Array($messageId, $messageFields)); } } unset($messageFields['BOT_ID']); foreach(\Bitrix\Main\EventManager::getInstance()->findEventHandlers("im", "onImBotMessageAdd") as $event) { ExecuteModuleEventEx($event, Array($botExecModule, $messageId, $messageFields)); } if ($messageFields['CHAT_ENTITY_TYPE'] == 'LINES' && trim($messageFields['MESSAGE']) == '0' && \Bitrix\Main\Loader::includeModule('imopenlines')) { $chat = new \Bitrix\Imopenlines\Chat($messageFields['TO_CHAT_ID']); $chat->endBotSession(); } return true; } public static function onMessageUpdate($messageId, $messageFields) { $botExecModule = self::getBotsForMessage($messageFields); if (!$botExecModule) return true; if ($messageFields['MESSAGE_TYPE'] != IM_MESSAGE_PRIVATE) { $messageFields['MESSAGE_ORIGINAL'] = $messageFields['MESSAGE']; if (preg_match("/\[USER=([0-9]{1,})\](.*?)\[\/USER\]/i", $messageFields['MESSAGE'], $matches)) { $messageFields['TO_USER_ID'] = $matches[1]; } else { $messageFields['TO_USER_ID'] = 0; } $messageFields['MESSAGE'] = trim(preg_replace('#\[(?P<tag>USER)=\d+\].+?\[/(?P=tag)\],?#', '', $messageFields['MESSAGE'])); } $messageFields['DIALOG_ID'] = \Bitrix\Im\Bot::getDialogId($messageFields); $messageFields = self::removeFieldsToEvent($messageFields); foreach ($botExecModule as $params) { if (!$params['MODULE_ID'] || !\Bitrix\Main\Loader::includeModule($params['MODULE_ID'])) continue; $messageFields['BOT_ID'] = $params['BOT_ID']; if ($params["METHOD_MESSAGE_UPDATE"] && class_exists($params["CLASS"]) && method_exists($params["CLASS"], $params["METHOD_MESSAGE_UPDATE"])) { call_user_func_array(array($params["CLASS"], $params["METHOD_MESSAGE_UPDATE"]), Array($messageId, $messageFields)); } else if (class_exists($params["CLASS"]) && method_exists($params["CLASS"], "onMessageUpdate")) { call_user_func_array(array($params["CLASS"], "onMessageUpdate"), Array($messageId, $messageFields)); } } unset($messageFields['BOT_ID']); foreach(\Bitrix\Main\EventManager::getInstance()->findEventHandlers("im", "onImBotMessageUpdate") as $event) { ExecuteModuleEventEx($event, Array($botExecModule, $messageId, $messageFields)); } return true; } public static function onMessageDelete($messageId, $messageFields) { $botExecModule = self::getBotsForMessage($messageFields); if (!$botExecModule) return true; $messageFields['DIALOG_ID'] = \Bitrix\Im\Bot::getDialogId($messageFields); $messageFields = self::removeFieldsToEvent($messageFields); foreach ($botExecModule as $params) { if (!$params['MODULE_ID'] || !\Bitrix\Main\Loader::includeModule($params['MODULE_ID'])) continue; $messageFields['BOT_ID'] = $params['BOT_ID']; if ($params["METHOD_MESSAGE_DELETE"] && class_exists($params["CLASS"]) && method_exists($params["CLASS"], $params["METHOD_MESSAGE_DELETE"])) { call_user_func_array(array($params["CLASS"], $params["METHOD_MESSAGE_DELETE"]), Array($messageId, $messageFields)); } else if (class_exists($params["CLASS"]) && method_exists($params["CLASS"], "onMessageDelete")) { call_user_func_array(array($params["CLASS"], "onMessageDelete"), Array($messageId, $messageFields)); } } unset($messageFields['BOT_ID']); foreach(\Bitrix\Main\EventManager::getInstance()->findEventHandlers("im", "onImBotMessageDelete") as $event) { ExecuteModuleEventEx($event, Array($botExecModule, $messageId, $messageFields)); } return true; } public static function onJoinChat($dialogId, $joinFields) { $bots = self::getListCache(); if (empty($bots)) return true; if (!isset($joinFields['BOT_ID']) || !$bots[$joinFields['BOT_ID']]) return false; $bot = $bots[$joinFields['BOT_ID']]; if (!\Bitrix\Main\Loader::includeModule($bot['MODULE_ID'])) return false; if ($joinFields['CHAT_TYPE'] == IM_MESSAGE_PRIVATE) { $updateCounter = array("COUNT_USER" => new \Bitrix\Main\DB\SqlExpression("?# + 1", "COUNT_USER")); } else { $updateCounter = array("COUNT_CHAT" => new \Bitrix\Main\DB\SqlExpression("?# + 1", "COUNT_CHAT")); } \Bitrix\Im\Model\BotTable::update($joinFields['BOT_ID'], $updateCounter); if ($joinFields['CHAT_TYPE'] != IM_MESSAGE_PRIVATE && $bot['TYPE'] == self::TYPE_SUPERVISOR) { $botName = \Bitrix\Im\User::getInstance($joinFields['BOT_ID'])->getName(); \CIMMessenger::Add(Array( 'DIALOG_ID' => $dialogId, 'MESSAGE_TYPE' => $joinFields['CHAT_TYPE'], 'MESSAGE' => str_replace(Array('#BOT_NAME#'), Array('[USER='.$joinFields['BOT_ID'].']'.$botName.'[/USER]'), $joinFields['ACCESS_HISTORY']? Loc::getMessage('BOT_SUPERVISOR_NOTICE_ALL_MESSAGES'): Loc::getMessage('BOT_SUPERVISOR_NOTICE_NEW_MESSAGES')), 'SYSTEM' => 'Y', 'SKIP_COMMAND' => 'Y', 'PARAMS' => Array( "CLASS" => "bx-messenger-content-item-system" ), )); } if ($bot["METHOD_WELCOME_MESSAGE"] && class_exists($bot["CLASS"]) && method_exists($bot["CLASS"], $bot["METHOD_WELCOME_MESSAGE"])) { call_user_func_array(array($bot["CLASS"], $bot["METHOD_WELCOME_MESSAGE"]), Array($dialogId, $joinFields)); } else if (strlen($bot["TEXT_PRIVATE_WELCOME_MESSAGE"]) > 0 && $joinFields['CHAT_TYPE'] == IM_MESSAGE_PRIVATE && $joinFields['FROM_USER_ID'] != $joinFields['BOT_ID']) { if ($bot['TYPE'] == self::TYPE_HUMAN) { \Bitrix\Im\Bot::startWriting(Array('BOT_ID' => $joinFields['BOT_ID']), $dialogId); } $userName = \Bitrix\Im\User::getInstance($joinFields['USER_ID'])->getName(); \Bitrix\Im\Bot::addMessage(Array('BOT_ID' => $joinFields['BOT_ID']), Array( 'DIALOG_ID' => $dialogId, 'MESSAGE' => str_replace(Array('#USER_NAME#'), Array($userName), $bot["TEXT_PRIVATE_WELCOME_MESSAGE"]), )); } else if (strlen($bot["TEXT_CHAT_WELCOME_MESSAGE"]) > 0 && ($joinFields['CHAT_TYPE'] == IM_MESSAGE_CHAT || $joinFields['CHAT_TYPE'] == IM_MESSAGE_OPEN_LINE) && $joinFields['FROM_USER_ID'] != $joinFields['BOT_ID']) { if ($bot['TYPE'] == self::TYPE_HUMAN) { \Bitrix\Im\Bot::startWriting(Array('BOT_ID' => $joinFields['BOT_ID']), $dialogId); } $userName = \Bitrix\Im\User::getInstance($joinFields['USER_ID'])->getName(); \Bitrix\Im\Bot::addMessage(Array('BOT_ID' => $joinFields['BOT_ID']), Array( 'DIALOG_ID' => $dialogId, 'MESSAGE' => str_replace(Array('#USER_NAME#'), Array($userName), $bot["TEXT_CHAT_WELCOME_MESSAGE"]), )); } foreach(\Bitrix\Main\EventManager::getInstance()->findEventHandlers("im", "onImBotJoinChat") as $event) { ExecuteModuleEventEx($event, Array($bot, $dialogId, $joinFields)); } return true; } public static function onLeaveChat($dialogId, $leaveFields) { $bots = self::getListCache(); if (empty($bots)) return true; if (!isset($leaveFields['BOT_ID']) || !$bots[$leaveFields['BOT_ID']]) return false; $bot = $bots[$leaveFields['BOT_ID']]; if (!\Bitrix\Main\Loader::includeModule($bot['MODULE_ID'])) return false; if ($leaveFields['CHAT_TYPE'] == IM_MESSAGE_PRIVATE) { $updateCounter = array("COUNT_USER" => new \Bitrix\Main\DB\SqlExpression("?# - 1", "COUNT_USER")); } else { $updateCounter = array("COUNT_CHAT" => new \Bitrix\Main\DB\SqlExpression("?# - 1", "COUNT_CHAT")); } \Bitrix\Im\Model\BotTable::update($leaveFields['BOT_ID'], $updateCounter); foreach(\Bitrix\Main\EventManager::getInstance()->findEventHandlers("im", "onImBotLeaveChat") as $event) { ExecuteModuleEventEx($event, Array($bot, $dialogId, $leaveFields)); } return true; } public static function startWriting(array $bot, $dialogId, $userName = '') { $botId = $bot['BOT_ID']; $moduleId = isset($bot['MODULE_ID'])? $bot['MODULE_ID']: ''; $appId = isset($bot['APP_ID'])? $bot['APP_ID']: ''; if (intval($botId) <= 0) return false; if (!\Bitrix\Im\User::getInstance($botId)->isExists() || !\Bitrix\Im\User::getInstance($botId)->isBot()) return false; $bots = self::getListCache(); if (!isset($bots[$botId])) return false; if (strlen($moduleId) > 0 && $bots[$botId]['MODULE_ID'] != $moduleId) return false; if (strlen($appId) > 0 && $bots[$botId]['APP_ID'] != $appId) return false; \CIMMessenger::StartWriting($dialogId, $botId, $userName); return true; } public static function addMessage(array $bot, array $messageFields) { $botId = $bot['BOT_ID']; $moduleId = isset($bot['MODULE_ID'])? $bot['MODULE_ID']: ''; $appId = isset($bot['APP_ID'])? $bot['APP_ID']: ''; if (intval($botId) <= 0) return false; if (!\Bitrix\Im\User::getInstance($botId)->isExists() || !\Bitrix\Im\User::getInstance($botId)->isBot()) return false; $bots = self::getListCache(); if (!isset($bots[$botId])) return false; if (strlen($moduleId) > 0 && $bots[$botId]['MODULE_ID'] != $moduleId) return false; if (strlen($appId) > 0 && $bots[$botId]['APP_ID'] != $appId) return false; $isPrivateSystem = false; if ($messageFields['FROM_USER_ID'] && $messageFields['TO_USER_ID']) { $messageFields['SYSTEM'] = 'Y'; $messageFields['DIALOG_ID'] = $messageFields['TO_USER_ID']; $isPrivateSystem = true; } else if (empty($messageFields['DIALOG_ID'])) { return false; } $messageFields['MENU'] = $messageFields['MENU']? $messageFields['MENU']: null; $messageFields['ATTACH'] = $messageFields['ATTACH']? $messageFields['ATTACH']: null; $messageFields['KEYBOARD'] = $messageFields['KEYBOARD']? $messageFields['KEYBOARD']: null; $messageFields['PARAMS'] = $messageFields['PARAMS']? $messageFields['PARAMS']: Array(); if (Common::isChatId($messageFields['DIALOG_ID'])) { $chatId = intval(substr($messageFields['DIALOG_ID'], 4)); if ($chatId <= 0) return false; if (\CIMChat::GetGeneralChatId() == $chatId && !\CIMChat::CanSendMessageToGeneralChat($botId)) { return false; } else { $ar = Array( "FROM_USER_ID" => $botId, "TO_CHAT_ID" => $chatId, "ATTACH" => $messageFields['ATTACH'], "KEYBOARD" => $messageFields['KEYBOARD'], "MENU" => $messageFields['MENU'], "PARAMS" => $messageFields['PARAMS'], ); if (isset($messageFields['MESSAGE']) && (!empty($messageFields['MESSAGE']) || $messageFields['MESSAGE'] === "0")) { $ar['MESSAGE'] = $messageFields['MESSAGE']; } if (isset($messageFields['SYSTEM']) && $messageFields['SYSTEM'] == 'Y') { $ar['SYSTEM'] = 'Y'; $attach = new \CIMMessageParamAttach(10000, \CIMMessageParamAttach::TRANSPARENT); $attach->AddBot(Array( "NAME" => \Bitrix\Im\User::getInstance($botId)->getFullName(), "AVATAR" => \Bitrix\Im\User::getInstance($botId)->getAvatar(), "BOT_ID" => $botId, )); $ar['MESSAGE'] = "[ATTACH=10000]".$ar['MESSAGE']; $ar['ATTACH'][] = $attach; } if (isset($messageFields['URL_PREVIEW']) && $messageFields['URL_PREVIEW'] == 'N') { $ar['URL_PREVIEW'] = 'N'; } $ar['SKIP_COMMAND'] = 'Y'; $id = \CIMChat::AddMessage($ar); } } else { if ($isPrivateSystem) { $fromUserId = intval($messageFields['FROM_USER_ID']); if ($botId > 0) { $messageFields['MESSAGE'] = Loc::getMessage("BOT_MESSAGE_FROM", Array("#BOT_NAME#" => "[USER=".$botId."]".\Bitrix\Im\User::getInstance($botId)->getFullName()."[/USER][BR]")).$messageFields['MESSAGE']; } } else { $fromUserId = $botId; } $userId = intval($messageFields['DIALOG_ID']); $ar = Array( "FROM_USER_ID" => $fromUserId, "TO_USER_ID" => $userId, "ATTACH" => $messageFields['ATTACH'], "KEYBOARD" => $messageFields['KEYBOARD'], "MENU" => $messageFields['MENU'], "PARAMS" => $messageFields['PARAMS'], ); if (isset($messageFields['MESSAGE']) && (!empty($messageFields['MESSAGE']) || $messageFields['MESSAGE'] === "0")) { $ar['MESSAGE'] = $messageFields['MESSAGE']; } if (isset($messageFields['SYSTEM']) && $messageFields['SYSTEM'] == 'Y') { $ar['SYSTEM'] = 'Y'; } if (isset($messageFields['URL_PREVIEW']) && $messageFields['URL_PREVIEW'] == 'N') { $ar['URL_PREVIEW'] = 'N'; } $ar['SKIP_COMMAND'] = 'Y'; $id = \CIMMessage::Add($ar); } return $id; } public static function updateMessage(array $bot, array $messageFields) { $botId = $bot['BOT_ID']; $moduleId = isset($bot['MODULE_ID'])? $bot['MODULE_ID']: ''; $appId = isset($bot['APP_ID'])? $bot['APP_ID']: ''; if (intval($botId) <= 0) return false; if (!\Bitrix\Im\User::getInstance($botId)->isExists() || !\Bitrix\Im\User::getInstance($botId)->isBot()) return false; $bots = self::getListCache(); if (!isset($bots[$botId])) return false; if (strlen($moduleId) > 0 && $bots[$botId]['MODULE_ID'] != $moduleId) return false; if (strlen($appId) > 0 && $bots[$botId]['APP_ID'] != $appId) return false; $messageId = intval($messageFields['MESSAGE_ID']); if ($messageId <= 0) return false; $message = \CIMMessenger::CheckPossibilityUpdateMessage(IM_CHECK_UPDATE, $messageId, $botId); if (!$message) return false; if (isset($messageFields['ATTACH'])) { if (empty($messageFields['ATTACH']) || $messageFields['ATTACH'] == 'N') { \CIMMessageParam::Set($messageId, Array('ATTACH' => Array())); } else if ($messageFields['ATTACH'] instanceof \CIMMessageParamAttach) { if ($messageFields['ATTACH']->IsAllowSize()) { \CIMMessageParam::Set($messageId, Array('ATTACH' => $messageFields['ATTACH'])); } } } if (isset($messageFields['KEYBOARD'])) { if (empty($messageFields['KEYBOARD']) || $messageFields['KEYBOARD'] == 'N') { \CIMMessageParam::Set($messageId, Array('KEYBOARD' => 'N')); } else if ($messageFields['KEYBOARD'] instanceof \Bitrix\Im\Bot\Keyboard) { if ($messageFields['KEYBOARD']->isAllowSize()) { \CIMMessageParam::Set($messageId, Array('KEYBOARD' => $messageFields['KEYBOARD'])); } } } if (isset($messageFields['MENU'])) { if (empty($messageFields['MENU']) || $messageFields['MENU'] == 'N') { \CIMMessageParam::Set($messageId, Array('MENU' => 'N')); } else if ($messageFields['MENU'] instanceof \Bitrix\Im\Bot\ContextMenu) { if ($messageFields['MENU']->isAllowSize()) { \CIMMessageParam::Set($messageId, Array('MENU' => $messageFields['MENU'])); } } } if (isset($messageFields['MESSAGE'])) { $urlPreview = isset($messageFields['URL_PREVIEW']) && $messageFields['URL_PREVIEW'] == "N"? false: true; $skipConnector = isset($messageFields['SKIP_CONNECTOR']) && $messageFields['SKIP_CONNECTOR'] == "Y"? true: false; $editFlag = isset($messageFields['EDIT_FLAG']) && $messageFields['EDIT_FLAG'] == "Y"? true: false; $res = \CIMMessenger::Update($messageId, $messageFields['MESSAGE'], $urlPreview, $editFlag, $botId, $skipConnector); if (!$res) { return false; } } \CIMMessageParam::SendPull($messageId, Array('KEYBOARD', 'ATTACH', 'MENU')); return true; } public static function deleteMessage(array $bot, $messageId) { $botId = $bot['BOT_ID']; $moduleId = isset($bot['MODULE_ID'])? $bot['MODULE_ID']: ''; $appId = isset($bot['APP_ID'])? $bot['APP_ID']: ''; $messageId = intval($messageId); if ($messageId <= 0) return false; if (intval($botId) <= 0) return false; if (!\Bitrix\Im\User::getInstance($botId)->isExists() || !\Bitrix\Im\User::getInstance($botId)->isBot()) return false; $bots = self::getListCache(); if (!isset($bots[$botId])) return false; if (strlen($moduleId) > 0 && $bots[$botId]['MODULE_ID'] != $moduleId) return false; if (strlen($appId) > 0 && $bots[$botId]['APP_ID'] != $appId) return false; return \CIMMessenger::Delete($messageId, $botId); } public static function likeMessage(array $bot, $messageId, $action = 'AUTO') { $botId = $bot['BOT_ID']; $moduleId = isset($bot['MODULE_ID'])? $bot['MODULE_ID']: ''; $appId = isset($bot['APP_ID'])? $bot['APP_ID']: ''; $messageId = intval($messageId); if ($messageId <= 0) return false; if (intval($botId) <= 0) return false; if (!\Bitrix\Im\User::getInstance($botId)->isExists() || !\Bitrix\Im\User::getInstance($botId)->isBot()) return false; $bots = self::getListCache(); if (!isset($bots[$botId])) return false; if (strlen($moduleId) > 0 && $bots[$botId]['MODULE_ID'] != $moduleId) return false; if (strlen($appId) > 0 && $bots[$botId]['APP_ID'] != $appId) return false; return \CIMMessenger::Like($messageId, $action, $botId); } public static function getDialogId($messageFields) { if ($messageFields['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE) { $dialogId = $messageFields['FROM_USER_ID']; } else { $dialogId = 'chat'.$messageFields['TO_CHAT_ID']; } return $dialogId; } private static function findBots($fields) { $result = Array(); if (intval($fields['BOT_ID']) <= 0) return $result; $bots = self::getListCache(); if ($fields['TYPE'] == IM_MESSAGE_PRIVATE) { if (isset($bots[$fields['BOT_ID']])) { $result = $bots[$fields['BOT_ID']]; } } else { if (isset($bots[$fields['BOT_ID']])) { $chats = self::getChatListCache($fields['BOT_ID']); if (isset($chats[$fields['CHAT_ID']])) { $result = $bots[$fields['BOT_ID']]; } } } return $result; } public static function getCache($botId) { $botList = self::getListCache(); return isset($botList[$botId])? $botList[$botId]: false; } public static function clearCache() { $cache = \Bitrix\Main\Data\Cache::createInstance(); $cache->cleanDir(self::CACHE_PATH); return true; } public static function getListCache($type = self::LIST_ALL) { $cache = \Bitrix\Main\Data\Cache::createInstance(); if($cache->initCache(self::CACHE_TTL, 'list_r4', self::CACHE_PATH)) { $result = $cache->getVars(); } else { $result = Array(); $orm = \Bitrix\Im\Model\BotTable::getList(); while ($row = $orm->fetch()) { $row['LANG'] = $row['LANG']? $row['LANG']: null; $result[$row['BOT_ID']] = $row; } $cache->startDataCache(); $cache->endDataCache($result); } if ($type == self::LIST_OPENLINE) { foreach ($result as $botId => $botData) { if ($botData['OPENLINE'] != 'Y' || $botData['CODE'] == 'marta') { unset($result[$botId]); } } } return $result; } public static function getListForJs() { $result = Array(); $bots = self::getListCache(); foreach ($bots as $bot) { $type = 'bot'; if ($bot['TYPE'] == self::TYPE_HUMAN) { $type = 'human'; } else if ($bot['TYPE'] == self::TYPE_NETWORK) { $type = 'network'; } else if ($bot['TYPE'] == self::TYPE_OPENLINE) { $type = 'openline'; } else if ($bot['TYPE'] == self::TYPE_SUPERVISOR) { $type = 'supervisor'; } $result[$bot['BOT_ID']] = Array( 'id' => $bot['BOT_ID'], 'code' => $bot['CODE'], 'type' => $type, 'openline' => $bot['OPENLINE'] == 'Y', ); } return $result; } private static function removeFieldsToEvent($messageFields) { unset($messageFields['BOT_IN_CHAT']); unset($messageFields['MESSAGE_OUT']); unset($messageFields['NOTIFY_EVENT']); unset($messageFields['NOTIFY_MODULE']); unset($messageFields['URL_PREVIEW']); unset($messageFields['DATE_CREATE']); unset($messageFields['EMAIL_TEMPLATE']); unset($messageFields['RECENT_ADD']); unset($messageFields['SKIP_USER_CHECK']); unset($messageFields['DATE_CREATE']); unset($messageFields['EMAIL_TEMPLATE']); unset($messageFields['NOTIFY_TYPE']); unset($messageFields['NOTIFY_TAG']); unset($messageFields['NOTIFY_TITLE']); unset($messageFields['NOTIFY_BUTTONS']); unset($messageFields['NOTIFY_READ']); unset($messageFields['NOTIFY_READ']); unset($messageFields['IMPORT_ID']); unset($messageFields['NOTIFY_SUB_TAG']); unset($messageFields['CHAT_PARENT_ID']); unset($messageFields['CHAT_PARENT_MID']); unset($messageFields['DATE_MODIFY']); return $messageFields; } private static function getChatListCache($botId) { $botId = intval($botId); if ($botId <= 0) return Array(); $cache = \Bitrix\Main\Data\Cache::createInstance(); if($cache->initCache(self::CACHE_TTL, 'chat'.$botId, self::CACHE_PATH)) { $result = $cache->getVars(); } else { $result = Array(); $orm = \Bitrix\Im\Model\BotChatTable::getList(Array( 'filter' => Array('=BOT_ID' => $botId) )); while ($row = $orm->fetch()) { $result[$row['CHAT_ID']] = $row; } $cache->startDataCache(); $cache->endDataCache($result); } return $result; } public static function changeChatMembers($chatId, $botId, $append = true) { $chatId = intval($chatId); $botId = intval($botId); if ($chatId <= 0 || $botId <= 0) return false; $chats = self::getChatListCache($botId); if ($append) { if (isset($chats[$chatId])) { return true; } \Bitrix\Im\Model\BotChatTable::add(Array( 'BOT_ID' => $botId, 'CHAT_ID' => $chatId )); } else { if (!isset($chats[$chatId])) { return true; } $orm = \Bitrix\Im\Model\BotChatTable::getList(Array( 'filter' => Array('=BOT_ID' => $botId, '=CHAT_ID' => $chatId) )); if ($row = $orm->fetch()) { \Bitrix\Im\Model\BotChatTable::delete($row['ID']); } } $cache = \Bitrix\Main\Data\Cache::createInstance(); $cache->clean('chat'.$botId, self::CACHE_PATH); return true; } public static function getDefaultLanguage() { $cache = \Bitrix\Main\Data\Cache::createInstance(); if($cache->initCache(self::CACHE_TTL, 'language_v2', '/bx/im/')) { $languageId = $cache->getVars(); } else { $languageId = ''; $siteIterator = \Bitrix\Main\SiteTable::getList(array( 'select' => array('LANGUAGE_ID'), 'filter' => array('=DEF' => 'Y', '=ACTIVE' => 'Y') )); if ($site = $siteIterator->fetch()) $languageId = (string)$site['LANGUAGE_ID']; if ($languageId == '') { if (\Bitrix\Main\Loader::includeModule('bitrix24')) { $languageId = \CBitrix24::getLicensePrefix(); } else { $languageId = LANGUAGE_ID; } } if ($languageId == '') { $languageId = 'en'; } $languageId = strtolower($languageId); $cache->startDataCache(); $cache->endDataCache($languageId); } return $languageId; } public static function deleteExpiredTokenAgent() { $orm = \Bitrix\Im\Model\BotTokenTable::getList(Array( 'filter' => array( '<DATE_EXPIRE' => new \Bitrix\Main\Type\DateTime(), ), 'select' => array('ID'), 'limit' => 1 )); if ($token = $orm->fetch()) { $application = \Bitrix\Main\Application::getInstance(); $connection = $application->getConnection(); $sqlHelper = $connection->getSqlHelper(); $connection->query(" DELETE FROM b_im_bot_token WHERE DATE_EXPIRE < ".$sqlHelper->getCurrentDateTimeFunction()." "); } return "\\Bitrix\\Im\\Bot::deleteExpiredTokenAgent();"; } /** * @param $messageFields * @return array */ private static function getBotsForMessage($messageFields) { $bots = self::getListCache(); if (empty($bots)) return Array(); if (isset($bots[$messageFields['FROM_USER_ID']])) return Array(); $botExecModule = Array(); if ($messageFields['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE) { if (isset($bots[$messageFields['TO_USER_ID']])) { $botExecModule[$messageFields['TO_USER_ID']] = $bots[$messageFields['TO_USER_ID']]; } } else { $botFound = Array(); if ($messageFields['CHAT_ENTITY_TYPE'] == 'LINES') { $botFound = $messageFields['BOT_IN_CHAT']; } else if (preg_match_all("/\[USER=([0-9]{1,})\](.*?)\[\/USER\]/i", $messageFields['MESSAGE'], $matches)) { foreach ($matches[1] as $userId) { if (isset($bots[$userId]) && isset($messageFields['BOT_IN_CHAT'][$userId])) { $botFound[$userId] = $userId; } } } foreach ($messageFields['BOT_IN_CHAT'] as $botId) { if (isset($bots[$botId]) && $bots[$botId]['TYPE'] == self::TYPE_SUPERVISOR) { $botFound[$botId] = $botId; } } if (!empty($botFound)) { foreach ($botFound as $botId) { if (!isset($bots[$botId])) { continue; } if ($messageFields['CHAT_ENTITY_TYPE'] == 'LINES' && $bots[$botId]['OPENLINE'] == 'N') { continue; } $botExecModule[$botId] = $bots[$botId]; } } } return $botExecModule; } }