Интеграция WhatsApp и других мессенджеров в облачный Битрикс24 — технические моменты


В предыдущем посте мы писали о том, каким образом интегрировали WhatsApp в Битрикс24. Как и обещали, в данном посте речь пойдет о технической стороне вопроса.

Изучая возможность интеграции  WhatsApp  в Битрикс24 посредством агрегаторов мессенджеров, мы обнаружили, что идеальным способом такой интеграции являлся бы механизм открытых линий. Открытые линии – действительно мощный и удобный механизм. Сообщения в них приходят через коннекторы (каналы коммуникации), которые и реализуют взаимодействие Битрикса с внешними системами.1

Рис.1 Коннекторы открытых линий в Битрикс24

К сожалению, документации по данной теме недостаточно, и нам не удалось найти возможность создания и работы с собственными коннекторами открытых линий в текущем REST-API Битрикс. Наиболее близкой альтернативой является использование чат-ботов. REST-API Битрикс24 прекрасно с ними работает, поэтому мы решили реализовать общение с внешним агрегатором мессенджеров через закрытые чаты и чат бота.

Создаем новое приложение Битрикс24. В требуемых scopes выбираем messageservice, crm, imbot, im, imopenlines, user, disk. Точка входа в приложении реализует маршрутизацию запросов к нему. Первым делом создаем интерфейс, отображающий настройки приложения, и обеспечивающий их сохранение.

2

Рис2. Часть интерфейса формы настроек приложения.

Тут необходимо учитывать, что если Вы пишете приложение под Маркетплейс Битрикс24 – необходимо подумать об использовании приложения различными доменами, и хранении настроек индивидуально для каждого домена. В нашем случае было организовано хранение настроек в серилизованных записях БД. При каждом обращении к приложению, определялся домен, опрашивающий приложение и для него загружались собственные настройки.

Следующим шагом стала регистрация чат-бота в Битрикс. На самом деле, во многих случаях это будет первым шагом, но в нашем случае чат не может работать функционально, пока не сделаны настройки приложения (не получен токен от агрегатора мессенджеров). Поэтому мы устанавливаем чат-бота только после внесения верных настроек.

BX24.callMethod(
'imbot.register',
{
'CODE':bot['code'],
'TYPE':bot['type'],
'EVENT_MESSAGE_ADD':BX24APP.PATH,
'EVENT_WELCOME_MESSAGE':BX24APP.PATH,
'EVENT_BOT_DELETE':BX24APP.PATH,
'PROPERTIES' :{
'NAME':bot['name'],
'LAST_NAME' :'',
'COLOR' :'AQUA',
'PERSONAL_PHOTO':bot['avatar'],
},
},
function(result)
{

}
);

Интересным моментом здесь является то, что аватар бота должен быть передан в виде картинке, закодированной в формате base64. Делается это в PHP с помощью вот такого не хитрого кода:

base64_encode(file_get_contents($url));

На выходе получится длинная строка с закодированными данными. Ее и указываем в PERSONAL_PHOTO. События бота – маршрутизируем на точку входа нашего приложения.

После этого, в контактах мессенджера Битрикс24 появится новый чат бот. Чат бот будет привязан к Вашему приложению. Когда кто-либо пишет чат-боту сообщение, информация об этом будет передаваться Вашему приложению по событию ONIMBOTMESSAGEADD. Здесь наша задача – посмотреть из какого чата это сообщение пришло, и передать его внешней системе. Для получения сообщений из внешней системы – указываем в ней в качестве вебхука — точку входа нашего приложения, с обязательным указанием домена, чтобы понимать какому именно порталу пришло сообщение.

Таким образом у нас теперь приложение перехватывает и входящие и исходящие сообщения. Осталось отобразить их пользователям. Для этого мы создали дополнительную таблицу в БД где храним информацию о диалогах чат-бота. При поступлении нового входящего сообщения мы проверяем его по этой таблице, и если это новый диалог – создаем в Битриксе закрытый чат с помощью команды ‘im.chat.add’. Чтобы «пометить» чат, и иметь возможность быстро определять что это чат для внешней системы – используйте поля ENTITY_TYPE и ENTITY_ID. Например в ENTITY_TYPE пишите «EXT_SYSTEM» а в ENTITY_ID «ид диалога во внешней системе». Тогда легко можно обойтись без лишних запросов к БД.

В чат приглашаем специального пользователя, участвующего во всех диалогах (нужно для того, чтобы диалоги не оказались «брошенными», если из них выйдет пользователь), чат бота, и пользователя который будет общаться в этом диалоге.

3

Далее общение происходит в рамках чата, чат-бот перехватывает сообщения пользователя и передает их в приложение, которое передает их в агрегатор. Агрегатор отправляет сообщение в WhatsApp или в другой мессенджер клиенту. При поступлении ответа – передает его назад приложению, а приложение доводит его до пользователя через чат-бота. Каждому клиенту соответсвует свой диалог.

Важным вопросом в любом приложении для Битрикс24 является вопрос хранения авторизации. Мы в нашем случае решили его так: При установке приложения сохраняем авторизацию пользователя, установившего приложение в базе данных. Обычно это кто-то обладающий высоким уровнем доступа. В авторизации хранится текущий токен и токен для обновления авторизации. Текущий токен живет очень не долго. Если запрос к REST-API Битрикс24 возвращает ошибку ‘expired_token’ или ‘invalid_token’ — обновляем токен с помощью токена для обновления авторизации:

$auth=array();

$url="https://";
$url.=$this->DOMAIN."/oauth/token/?grant_type=refresh_token";
$url.="&client_id=".$this->CLIENT_ID;
$url.="&client_secret=".$this->CLIENT_SECRET;

if($this->CONFIG['AUTH']['REFRESH_TOKEN']) $url.="&refresh_token=".
$this->CONFIG['AUTH']['REFRESH_TOKEN'];

if($this->CONFIG['AUTH']['refresh_token']) $url.="&refresh_token=".
$this->CONFIG['AUTH']['refresh_token'];

Как видите, данный код принудительно вызывает страницу OAuth авторизации и передает ей код для обновления авторизации. Страница возвращает новые параметры авторизации. Их сохраняем и повторяем запрос с новыми параметрами авторизации.

Остается один нюанс – код для обновления авторизации тоже имеет срок жизни. Он составляет что-то около месяца. То есть, если Ваше приложение за месяц не сделает ни одного запроса в RET-API авторизация будет безвозвратно потеряна. Для решения этой проблемы – мы используем принудительное периодическое обновление авторизации раз в 10 дней (по cron).

Следующий интересный момент. Когда вы работаете с curl через https – необходимо задумываться о способе шифрования. Дело в том, что разные сервера (например сервер агрегатора мессенджеров) могут использовать разный набор доступных шифрований. При этом этот набор может не совпадать с вашим набором. В таком случае curl будет выдавать ошибку и работать не будет. Провести анализ доступных шифрований на удаленном сервере можно с помощью вот такого сервиса:

https://www.ssllabs.com/ssltest/analyze.html?d=имя_сервера

Соответсвенно, в вашем curl вы должны использовать шифрование из списка доступных на удаленном сервере. В PHP задавать способ шифрования можно с помощью:
curl_setopt_array(CURLOPT_SSL_CIPHER_LIST=>’способ шифрования’);

, ,

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *