Сразу оговорюсь, что это не готовый модуль с кнопкой, который надо только включить, чтобы заработал. Будет общее описание и куски кода, которые частично или полностью могут использоваться у вас.
[spoiler]
Итак, ситуация следующая: мы общаемся с клиентом в чате, в какой-то момент понимаем, что вопрос требует существенно больше времени и подключения другого специалиста. При этом другой специалист работает в тикетах. Необходимо передать ему всю информацию и при этом не заставлять клиента делать дополнительные телодвижения.
На помощь приходит механизм
У нас открытые линии и тикеты живут на разных установках, интеграция идёт через REST. Если у вас одна установка, реализация будет несколько проще. Её легко собрать из предложенного кода.
По шагам
1. Скачиваем архив
В классе бота находим строки:
const URL = "https://my_ticket_place/rest.php"; // путь к файлу, который публикует информацию в тикеты const SECRET = "UNIQUE STRING"; // секретная строка для публикации сообщений |
И устанавливаем адрес установки, на которой живут тикеты, и путь к файлу, принимающему запросы из чата (дальше будет информация о нём). Здесь надо обязательно указать свой секрет, чтобы посторонние не могли создать тикет у вас.
2.Теперь надо зарегистрировать бота, для этого в php командной строке выполняем код:
CModule::IncludeModule("imbot"); var_dump(\Bitrix\ImBot\Bot\TicketGate::register()); |
В результате вы должны будете увидеть id нового бота.
3.Теперь нужно подготовить файл /my_ticket_place/rest.php, который принимает данные из чата и создаёт тикет.
Здесь нужно, как минимум, установить секретную строку такую же, как вы установили для бота.
if ($_REQUEST['hash'] != md5($_REQUEST['timestamp'].'VERY SECRET STRING')) // ваша секретная строка, должна совпадать с тем, что отправляет бот |
В нашем случае установки работают в разных кодировках: cp1251 и utf8, идёт перекодировка. Уберите "$APPLICATION->ConvertCharset", если не требуется. Остальные параметры: язык, код сайта, категория и пр. делаются в зависимости от ваших потребностей.
4. Далее необходимо отправить ответ из тикета в чат. Для этого добавляем обработчик в /bitrix/php_interface/init.php
AddEventHandler('support', 'OnBeforeTicketUpdate', "OnBeforeTicketUpdate"); function OnBeforeTicketUpdate($arFields) { if ($arFields['ID'] && $arFields['MESSAGE'] && $arFields['HIDDEN'] != 'Y') { $uid = $GLOBALS['USER']->GetId(); if (CTicket::IsSupportTeam($uid) || CTicket::IsAdmin($uid)) // сообщение от сотрудника поддержки { $arTicket = CTicket::GetList($by = 'id', $order = 'asc', array('ID' => $arFields['ID']), $is_filtered, $CHECK_RIGHTS = "N", $get_extra_names = "N")->Fetch(); if ($arTicket['SOURCE_SID'] == 'openline') { $arUser = CUser::GetById($uid)->Fetch(); $FROM_USER_ID = preg_match('#([0-9]+)@#', $arUser['XML_ID'], $regs) ? $regs[1] : 0; $postFields = array( 'SESSION_ID' => str_replace('imol|', '', $arTicket['CREATED_MODULE_NAME']), 'MESSAGE' => $GLOBALS['APPLICATION']->ConvertCharset($arFields['MESSAGE'], 'cp1251', 'utf8'), 'FROM_USER_ID' => $FROM_USER_ID, ); $httpClient = new \Bitrix\Main\Web\HttpClient(array( "socketTimeout" => 20, "streamTimeout" => 60, "disableSslVerification" => true )); $httpClient->setHeader('User-Agent', 'Bitrix Ticket Chat Reply'); $postFields['action'] = 'TicketReply'; $postFields['timestamp'] = time(); $postFields['hash'] = md5($postFields['timestamp'].'MY CHAT SECRET STRING'); $result = $httpClient->post("https://my_openlines_place/openlines_rest.php", $postFields); try { $result = str_replace("\xEF\xBB\xBF", '', $result); $ar = \Bitrix\Main\Web\Json::decode($result); if ($ar['status'] != 'success') return false; } catch (\Bitrix\Main\ArgumentException $e) { AddMessage2Log($result); echo $result; return false; } } } } return $arFields; } |
Здесь ставим соответственно свою секретную строку и путь к скрипту, который принимает ответы из тикета в чат.
$postFields['hash'] = md5($postFields['timestamp'].'MY CHAT SECRET STRING'); $result = $httpClient->post("https://my_openlines_place/openlines_rest.php", $postFields); |
5. Теперь нужно на той установке, где живут открытые линии, создать скрипт openlines_rest.php, о котором говорилось в п.4.
Он довольно простой, поэтому опубликую код прям здесь:
<? define("NO_AGENT_STATISTIC","Y"); define("NO_AGENT_CHECK", true); define("DisableEventsCheck", true); define("NOT_CHECK_PERMISSIONS", true); require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); if (!CModule::IncludeModule("im")) die('{"status":"error","message":"system error '.__LINE__.'"}'); if (!CModule::IncludeModule("imopenlines")) die('{"status":"error","message":"system error '.__LINE__.'"}'); if (abs(time() - $_REQUEST['timestamp']) > 300) die('{"status":"error","message":"system error '.__LINE__.'"}'); if ($_REQUEST['hash'] != md5($_REQUEST['timestamp'].'DONT SAY THIS TO ANYONE!')) die('{"status":"error","message":"system error '.__LINE__.'"}'); if (!$arSession = \Bitrix\ImOpenlines\Model\SessionTable::getList(Array( 'select' => Array('ID', 'CHAT_ID', 'START_ID', 'END_ID', 'CONFIG_ID'), 'filter' => Array('ID' => $_REQUEST['SESSION_ID']) ))->fetch()) die('{"status":"error","message":"system error '.__LINE__.'"}'); $arFields = array( "MESSAGE_TYPE" => IM_MESSAGE_CHAT, "TO_CHAT_ID" => $arSession['CHAT_ID'], "FROM_USER_ID" => $_REQUEST['FROM_USER_ID'], "MESSAGE" => $_REQUEST['MESSAGE'], "URL_PREVIEW" => "Y", "SKIP_USER_CHECK" => "Y", ); define('TICKET_TRACKBACK', 'defined'); if ($id = CIMMessenger::Add($arFields)) echo '{"status":"success","message":"id '.$id.'"}'; else die('{"status":"error","message":"system error '.__LINE__.'"}'); ?> |
Опять же не забываем установить свой секрет:
if ($_REQUEST['hash'] != md5($_REQUEST['timestamp'].'DONT SAY THIS TO ANYONE!')) |
6. И последний шаг: связать пользователей двух разных установок. В предложенном мной методе используется нехитрая связь через внешний код. На установке, где живут тикеты, у пользователя должен быть указан внешний код вида
<ID с установки открытых линий>@openlines |
Заключение
Надеюсь, мои наброски помогут кому-то внедрить открытые линии в своей компании. Фактически, подобное решение может использоваться для интеграции открытых линий с любой системой, будь то задачи, живая лента, электронная почта, даже 1С.
Можно взять этот способ за основу, но писать нужно будет свой.