29.5.4. Использование webhook 29.5.4.1. Схема использования webhook Как было сказано ранее, при использовании вебхуков, интеграция работает только в одну сторону: сообщения передаются со стороны внешней системы в систему взаимодействия и, затем, в прикладное решение. Пользователь, который будет олицетворять систему, которая отправляет сообщения в прикладное решение, будет называться пользователем интеграции. Для того, чтобы внешняя система могла пользоваться вебхуком, ей необходимо сообщить адрес точки подключения, который можно получить с помощью метода ИнтеграцияСистемыВзаимодействия.НавигационнаяСсылкаТочкиПодключения(). Этот адрес следует использовать при настройки системы, которая будет отправлять сообщения. После того, как сообщение от внешней системы попадает в точку подключения, выполняются следующие действия: ● Тело сообщения разбирается. ● Создается пользователь интеграции, если он еще не создан. В качестве имени пользователя интеграции выступает: ● Имя пользователя, переданное в сообщении createUser. ● Имя экземпляра интеграции, если в сообщении внешней системы не указан пользователь (автор сообщения). ● Создается обсуждение системы взаимодействия, если оно еще не создано. ● В качестве участников обсуждения выступают: ● Пользователь интеграции. ● Пользователи, заданные при настройке интеграции как участники по умолчанию. ● Если необходимо, чтобы сообщения попадали в заранее созданное обсуждение с выбранным составом участников, то следует: ● Предварительно создать обсуждение с помощью встроенного языка. ● Передать идентификатор созданного обсуждения внешней системе, чтобы эта система использовала этот идентификатор в своих сообщениях. Строковое представление идентификатора обсуждения можно получить с помощью функции Строка(), параметром которой выступает объект типа ОбсуждениеСистемыВзаимодействия.Идентификатор. ● В обсуждение добавляется сообщение, автором которого является пользователь интеграции и содержимое определено сообщением внешней системы. 29.5.4.2. Поддерживаемые команды 29.5.4.2.1. Общая информация В качестве команды выступает POST-запроса внешней системы. Этот запрос должен удовлетворять следующим требованиям: ● Тело запроса формируется в кодировке UTF-8 без BOM. ● Тело запроса представляет собой JSON-документ. ● Тело запроса, в общем, имеет следующий вид: Копировать в буфер обмена { "command" : { "param1": value1, … "paramN": valueN } } Если в команде допускается текст в формате HTML, то в этом случае поддерживаются следующие возможности оформления: ● Поддерживаемые элементы: a, b, big, font, i, li, ol, s, small, span, strike, strong, u, ul. ● Атрибут элемента style: background-color, color, font-family, font-size, font-style, font-weight, text-decoration. Результат выполнения команды отражается кодом возврата: ● 200 OK ‑ команда выполнена успешно. ● 404 No active integration ‑ интеграция не найдена или не активна. ● 409 Conflict ‑ при вызове команды create… для уже существующего объекта. ● 500 <Текст ошибки> ‑ при обработке команды произошла ошибка. Далее в разделе будет описаны форматы команд. 29.5.4.2.2. createConversation Описание: Создает новое обсуждение. Синтаксис: Копировать в буфер обмена { "createConversation": { "extConversationId": "1", "title": "Заголовок обсуждения", "extUserId": "1", "members": [ "1" ] } } Параметры: ● extConversationId ‑ внешний идентификатор создаваемого обсуждения. ● title ‑ заголовок создаваемого обсуждения (в виде строки). ● extUserId ‑ внешний идентификатор пользователя, от имени которого создается обсуждение. Если не задан, то будет создан пользователь системы взаимодействия с именем, совпадающим с именем интеграции, и он будет добавлен в обсуждение. В этом случае во всех запросах, относящихся к этому обсуждению, не должны быть указаны параметры extUserId, members, addMembers, removeMembers. Необязательный параметр. ● members ‑ массив внешних идентификаторов пользователей, которые являются участниками обсуждения со стороны внешней системы. Необязательный параметр. 29.5.4.2.3. createMessage Описание: Создает новое сообщение в обсуждении. Синтаксис: Копировать в буфер обмена { "createMessage": { "extId": "1", "text": "Тест сообщения", "textFormat": "text/plain", "extUserId": "1", "extConversationId": "1" } } Параметры: ● extId ‑ внешний идентификатор создаваемого сообщения. ● text ‑ текст сообщения. ● textFormat ‑ формат текста сообщения. Возможные значения: text/plain, text/html. Необязательный параметр. Значение по умолчанию ‑ text/plain. ● extUserId ‑ внешний идентификатор пользователя-автора сообщения. Если не задан, то будет создан пользователь системы взаимодействия с именем, совпадающим с именем интеграции, и он будет добавлен в обсуждение. В этом случае во всех запросах, относящихся к этому обсуждению, не должны быть указаны параметры extUserId, members, addMembers, removeMembers. Необязательный параметр. ● extConversationId ‑ внешний идентификатор обсуждения, в котором создается сообщение. 29.5.4.2.4. createUser Описание: Создает пользователя интеграции в системе взаимодействия. Синтаксис: Копировать в буфер обмена { "createUser" : { "extUserId": , "name": , "fullName": , "picture": } } Параметры: ● extUserId ‑ внешний идентификатор внешнего пользователя. ● name ‑ короткое имя внешнего пользователя (в виде строки). ● fullName ‑ полное имя внешнего пользователя (в виде строки). Может быть пустой строкой. ● picture ‑ картинка пользователя в виде строки в формате base64. Необязательный параметр. 29.5.4.2.5. updateConversation Описание: Изменяет параметры обсуждения. Позволяет изменить заголовок обсуждения, а также добавить или удалить пользователей обсуждения. Синтаксис: Копировать в буфер обмена { "updateConversation": { "extConversationId": "1", "title": "Новый заголовок обсуждения", "extUserId": "5", "addMembers": [ "5" ], "removeMembers": [ "1" ] } } Параметры: ● extConversationId ‑ внешний идентификатор изменяемого обсуждения. ● title ‑ заголовок обсуждения. Необязательный параметр. ● extUserId ‑ внешний идентификатор пользователя, от имени которого изменяется обсуждение. Если не задан, то будет создан пользователь системы взаимодействия с именем, совпадающим с именем интеграции, и он будет добавлен в обсуждение. В этом случае во всех запросах, относящихся к этому обсуждению, не должны быть указаны параметры extUserId, members, addMembers, removeMembers. Необязательный пользователь. ● addMembers ‑ массив внешних идентификаторов пользователей, которые будут добавлены к участникам обсуждения. Необязательный параметр. ● removeMembers ‑ массив внешних идентификаторов пользователей, которые будут удалены из участников обсуждения. Необязательный параметр. 29.5.4.2.6. updateMessage Описание: Изменяет существующее сообщение. Синтаксис: Копировать в буфер обмена { "updateMessage": { "extId": "1", "text": "Тест сообщения", "textFormat": "text/plain", "extUserId": "1", "extConversationId": "1" } } Параметры: ● extId ‑ внешний идентификатор изменяемого сообщения. ● text ‑ текст сообщения. ● textFormat ‑ формат текста сообщения. Возможные значения: text/plain, text/html. Необязательный параметр. Значение по умолчанию ‑ text/plain. ● extUserId ‑ внешний идентификатор пользователя-автора сообщения. Если не задан, то будет создан пользователь системы взаимодействия с именем, совпадающим с именем интеграции, и он будет добавлен в обсуждение. В этом случае во всех запросах, относящихся к этому обсуждению, не должны быть указаны параметры extUserId, members, addMembers, removeMembers. Необязательный параметр. ● extConversationId ‑ внешний идентификатор обсуждения, в котором изменяется сообщение. 29.5.4.2.7. updateUser Описание: Обновляет параметры пользователя интеграции в системе взаимодействия. Синтаксис: Копировать в буфер обмена { "updateUser" : { "extUserId": , "name": , "fullName": , "picture": } } Параметры: ● extUserId ‑ внешний идентификатор внешнего пользователя. ● name ‑ новое короткое имя внешнего пользователя (в виде строки). Необязательный параметр. ● fullName ‑ новое полное имя внешнего пользователя (в виде строки). Необязательный параметр. ● picture ‑ новая картинка пользователя в виде строки в формате base64. Необязательный параметр. 29.5.5. Чат на сайте 29.5.5.1. Общая информация Данный способ интеграции предназначен для решения следующей задачи: необходимо обеспечить возможность для пользователя некоторого сайта общаться с компанией, которая использует этот сайт для выполнения своей деятельности. На сайте может быть интернет-магазин, витрина с примерами продукции и т. д. Для того, чтобы реализовать такую интеграцию, необходимо выполнить следующие действия: 1. Доработать реализацию сайта (как клиентскую, так и серверную части) так, чтобы на этом сайте пользователь смог начать разговор в чате. При необходимости, код сайта может использовать программный интерфейс чата для выполнения некоторых действий. 2. Создать нужный тип интеграции в системе «1С:Предприятие». 3. Реализовать на встроенном языке системы «1С:Предприятие» требуемое взаимодействие с чатом, если необходимо. Если чат используется только в режиме мессенджера (т. е. только для интерактивного обмена текстовыми сообщениями) ‑ никаких дополнительных действий выполнять не требуется. 29.5.5.2. Интерфейс чата Для того, чтобы подключить чат к веб-сайту, необходимо в код веб-сайта вставить следующий фрагмент кода: Копировать в буфер обмена URL точки подключения можно получить или при создании интеграции (в стандартной обработке управления системой взаимодействия) или с помощью метода НавигационнаяСсылкаТочкиПодключения() объекта типа ИнтеграцияСистемыВзаимодействия. После загрузки интерфейса чата, в глобальном контексте сайта становится доступен объект CollaborationSystemWebChat1CE (типа CollaborationSystemWebChat1CEClass). Через этот объект возможно взаимодействие с чатом. Объект CollaborationSystemWebChat1CE предоставляет следующие методы: open() Описание: Разворачивает окно чата. Возвращаемое значение: void. close() Описание: Сворачивает окно чата. Возвращаемое значение: void. setContactInfo() Описание: Устанавливает контактные данные пользователя. Параметры: contactInfo­обязательный Тип: Object. Объект, содержащий значения полей контактных данных пользователя. Объект содержит следующие свойства: ● name ‑ тип String ‑ содержит имя пользователя. ● fullName ‑ тип String ‑ содержит полное имя пользователя. ● email ‑ тип String ‑ содержит адрес электронной почты пользователя. ● phone ‑ тип String ‑ содержит номер телефона пользователя. Возвращаемое значение: void. getContactInfo() Описание: Возвращает поданные пользователем в форме представления контактные данные. Возвращаемое значение: Promise. Результатом выполнения обещания является значение типа Object, которое содержит следующие свойства: ● name ‑ тип String ‑ содержит имя пользователя. ● fullName ‑ тип String ‑ содержит полное имя пользователя. ● email ‑ тип String ‑ содержит адрес электронной почты пользователя. ● phone ‑ тип String ‑ содержит номер телефона пользователя. setMatchingKeyToken() Описание: Устанавливает токен с ключом сопоставления пользователя системы взаимодействия и пользователя на сайте. Параметры: matchingKeyToken­обязательный Тип: String. Токен, содержащий ключ сопоставления пользователя системы взаимодействия и пользователя на сайте. Токен может быть подписан (JWS) с использованием созданного в параметрах интеграции ключа подписи signKey или не подписан (JWT). Данный ключ сопоставления будет доступен через свойство ИдентификаторПользователяВнешнейСистемы типа ПользовательСистемыВзаимодействия. Возвращаемое значение: void. logout() Описание: Осуществляет завершение сеанса для текущего в чате пользователя. Возвращаемое значение: Promise. Результатом выполнения обещания является значение типа void. isVideoconferenceEnabled() Описание: Возвращает информацию о доступности видеозвонков. Возвращаемое значение: Promise. Результатом выполнения обещания является значение типа Boolean: ● true ‑ видеозвонки доступны. ● false ‑ видеозвонки не доступны. startVideoconference() Описание: Начинает видеозвонок пользователя сайта пользователю системы «1С:Предприятие». Возвращаемое значение: Promise. Результатом выполнения обещания является значение типа Boolean: ● true ‑ видеозвонок начался. ● false ‑ видеозвонок был отменен. sendMessage() Описание: Отправляет текст сообщения. Параметры: Message­обязательный Тип: Object. Сообщение, которое необходимо отправить в чат. Объект имеет следующие свойства: ● text ‑ тип String -текст сообщения. ● textFormat- тип String ‑ тип сообщения: text/plain или text/html. Возвращаемое значение: void. addListener(, ) Описание: Добавляет обработчик события . Параметры: eventType­обязательный Тип: String. Имя события чата (описано далее). eventListener­обязательный Тип: Function. Содержит ссылку на метод обработчика события. Возвращаемое значение: void. removeListener(, ) Описание: Удаляет обработчик события . Параметры: eventType­обязательный Тип: String. Имя события чата (описано далее). eventListener­обязательный Тип: Function. Содержит ссылку на метод обработчика события. Возвращаемое значение: void. Объект CollaborationSystemWebChat1CE предоставляет возможность обрабатывать следующие события чата: Событие Описание close Вызывается при закрытии (сворачивании) чата. initialized Вызывается после полной инициализации чата (когда чат полностью готов к работе). open Вызывается при открытии (разворачивании) чата. videoconferenceend Вызывается при окончании видеозвонка. videoconferencestart Вызывается при начале видеозвонка. Отдельно остановимся на процессе сопоставления пользователей сайта и системы взаимодействия. Как уже было отмечено ранее, работа системы взаимодействия всегда выполняется от лица какого-либо пользователя. Из этого следует, что любой пользователь, который подключается к системе взаимодействия, должен иметь свое цифровое олицетворение в системе взаимодействия. Однако, пользователь сайта, на котором развернут чат, и пользователь системы взаимодействия (в общем случае) ничего не знают друг о друге. При выполнении интеграции можно будет использовать один из следующих механизмов интеграции: ● Не выполнять явного соответствия. В этом случае пользователь сайта какое-то время будет «узнаваться» чатом (через механизм хранения данных веб-браузером), но при входе с другого компьютера или через продолжительный промежуток времени будет создан новый пользователь системы взаимодействия. Для такого использования ничего делать не требуется. ● Сопоставлять пользователей. В этом случае необходима доработка не только клиентской части сайта, но и его серверной части. В кратком изложении схема сопоставления выглядит следующим образом: программное обеспечение сайта сообщает серверу взаимодействия уникальный идентификатор пользователя, который сейчас работает на сайте. Сервер взаимодействия по этому идентификатору находит «своего» пользователя и передает сайту сообщения обсуждения с этим пользователем. Теперь рассмотрим эту схему более подробно. Сайт, на котором развернут чат, должен сообщить системе взаимодействия некоторую информацию, по которой можно однозначно определить, какой пользователь сайта входит в чат. Для этого сайт должен сформировать токен в формате JWT или JWS (JSON Web Signature). Т. к. JWS ‑ это (фактически) подписанный токен JWT. Таким образом, вначале необходимо сформировать сам токен, полезная нагрузка которого должна содержать следующие претензии: ● sub ‑ в этой претензии должен располагаться уникальный идентификатор пользователя сайта (строковое представление). Это значение в дальнейшем будет в системе «1С:Предприятие» с помощью свойства ПользовательСистемыВзаимодействия.ИдентификаторПользователяВнешнейСистемы. ● iat ‑ в этой претензии размещается время создания JWT по времени сервера сайта, в который интегрируется чат. JWT должен формироваться на стороне серверной части сайта. Теперь этот токен необходимо передать в чат системы взаимодействия, который передаст эту информацию далее, на сервер взаимодействия. Для такой передачи следует использовать метод чата setMatchingKeyToken(). Сервер взаимодействия извлекает из токена полезную нагрузку и сопоставляет пользователя сайта с пользователем системы взаимодействия. Затем сервер взаимодействия «отдает» сайту содержимое обсуждения для указанного пользователя. Если в процессе работы сайта пользователь сайта меняется (например, текущий пользователь вышел из личного кабинета, а другой пользователь авторизовался), то сайт должен повторить процедуру формирования токена для нового пользователя и повторно выполнить установку ключа сопоставления. После этого содержимое чата обновится. Описанная выше схема работает в том случае, когда в настройках интеграции не указан параметр signKey. У рассмотренного метода есть неприятная особенность, связанная с безопасностью интеграции (и данных пользователей). Если предположить, что клиентская часть сайта является ненадежным элементом, то злоумышленник может указать произвольный идентификатор пользователя сайта в претензии JWT и получить доступ к чужим данным. Чтобы избежать этого, в настройках интеграции следует указать параметр signKey. В этом случае сервер взаимодействия будет ожидать в параметрах метода setMatchingKeyToken() не JWT, а JWS-токен. Также необходимо доработать серверную часть сайта таким образом, чтобы после формирования необходимого JWT, сервер сайта подписывал этот токен (формировал JWS) с помощью ключа, указанного в параметре интеграции signKey. Этот ключ необходимо вручную указать в серверном коде сайта. Формирование JWS должно выполняться с помощью библиотек работы с токенами языка программирования, который используется для разработки серверной части сайта. В результате указанных доработок клиентская часть не сможет изменить полезную нагрузку JWT без нарушения подписи. Вся остальная схема остается той же: JWS передается в чат с помощью метода setMatchingKeyToken(), чат передает токен на сервер взаимодействия. Только теперь, прежде чем начать поиск пользователя по информации из полезной нагрузки токена, сервер взаимодействия проверит подпись токена. И дальнейшая работа будет возможна только в том случае, если переданный токен не был изменен. Смотри также: ● JSON Web Signature, веб-подпись JSON: https://datatracker.ietf.org/doc/html/rfc7515.