Files
angel 72b6879f4b v1.7.0: refactor max_bot to flat structure, add VCF+UserModel+NLP history context, portal pages and proxy fixes
- Refactored max_bot from nested packages to flat module structure
- Q2: Extended BotUser model (patronymic, email, org, address, vcf_raw, contact_hash, phone_verified, email_verified, last_interaction, total_conversations, total_tickets)
- Q2: VCF parser (FN, N, TEL, EMAIL, ORG, ADR), upsert on re-contact, NLP history context (_get_user_history_context -> YandexGPT)
- Q1: Broadcast preview modal with 10s confirmation timer
- Q3: CSS var(--white)->var(--bg-card), var(--text)->var(--text-primary)
- Q4: bot_settings showNotification(), editable max_bot_id
- Q5: Webhook secret passthrough via X-Max-Bot-Api-Secret
- Masking sensitive keys, dialog_cleared handler, migrate via _add_column_if_not_exists()
- Rate limit (asyncio.sleep 0.5 per 10), dead code removed, conv.intent context in contact.py
- Portal pages: bot_consent, bot_kb (edit), bot_settings, bot_test, bot_tickets, portal_settings
- Tests: 21/21 passing, added test_yandex_gpt.py, test_email_sender.py
- Deploy: deploy_full.sh, schema.sql, seed_knowledge_base.sql
2026-05-29 02:30:30 +03:00

529 lines
31 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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. Интерфейс чата
Для того, чтобы подключить чат к веб-сайту, необходимо в код веб-сайта вставить следующий фрагмент кода:
Копировать в буфер обмена
<script src="<URL точки подключения>" async></script>
URL точки подключения можно получить или при создании интеграции (в стандартной обработке управления системой взаимодействия) или с помощью метода НавигационнаяСсылкаТочкиПодключения() объекта типа ИнтеграцияСистемыВзаимодействия.
После загрузки интерфейса чата, в глобальном контексте сайта становится доступен объект CollaborationSystemWebChat1CE (типа CollaborationSystemWebChat1CEClass). Через этот объект возможно взаимодействие с чатом.
Объект CollaborationSystemWebChat1CE предоставляет следующие методы:
open()
Описание:
Разворачивает окно чата.
Возвращаемое значение:
void.
close()
Описание:
Сворачивает окно чата.
Возвращаемое значение:
void.
setContactInfo(<contactInfo>)
Описание:
Устанавливает контактные данные пользователя.
Параметры:
contactInfo­обязательный
Тип: Object.
Объект, содержащий значения полей контактных данных пользователя. Объект содержит следующие свойства:
● name ‑ тип String ‑ содержит имя пользователя.
● fullName тип String ‑ содержит полное имя пользователя.
● email ‑ тип String ‑ содержит адрес электронной почты пользователя.
● phone ‑ тип String ‑ содержит номер телефона пользователя.
Возвращаемое значение:
void.
getContactInfo()
Описание:
Возвращает поданные пользователем в форме представления контактные данные.
Возвращаемое значение:
Promise<Object>. Результатом выполнения обещания является значение типа Object, которое содержит следующие свойства:
● name ‑ тип String ‑ содержит имя пользователя.
● fullName тип String ‑ содержит полное имя пользователя.
● email ‑ тип String ‑ содержит адрес электронной почты пользователя.
● phone ‑ тип String ‑ содержит номер телефона пользователя.
setMatchingKeyToken(<matchingKeyToken>)
Описание:
Устанавливает токен с ключом сопоставления пользователя системы взаимодействия и пользователя на сайте.
Параметры:
matchingKeyToken­обязательный
Тип: String.
Токен, содержащий ключ сопоставления пользователя системы взаимодействия и пользователя на сайте. Токен может быть подписан (JWS) с использованием созданного в параметрах интеграции ключа подписи signKey или не подписан (JWT). Данный ключ сопоставления будет доступен через свойство ИдентификаторПользователяВнешнейСистемы типа ПользовательСистемыВзаимодействия.
Возвращаемое значение:
void.
logout()
Описание:
Осуществляет завершение сеанса для текущего в чате пользователя.
Возвращаемое значение:
Promise<void>. Результатом выполнения обещания является значение типа void.
isVideoconferenceEnabled()
Описание:
Возвращает информацию о доступности видеозвонков.
Возвращаемое значение:
Promise<Boolean>. Результатом выполнения обещания является значение типа Boolean:
● true ‑ видеозвонки доступны.
● false ‑ видеозвонки не доступны.
startVideoconference()
Описание:
Начинает видеозвонок пользователя сайта пользователю системы «1С:Предприятие».
Возвращаемое значение:
Promise<Boolean>. Результатом выполнения обещания является значение типа Boolean:
● true ‑ видеозвонок начался.
● false ‑ видеозвонок был отменен.
sendMessage(<message>)
Описание:
Отправляет текст сообщения.
Параметры:
Message­обязательный
Тип: Object.
Сообщение, которое необходимо отправить в чат. Объект имеет следующие свойства:
● text тип String -текст сообщения.
● textFormat- тип String тип сообщения: text/plain или text/html.
Возвращаемое значение:
void.
addListener(<eventType>, <eventListener>)
Описание:
Добавляет обработчик события <event>.
Параметры:
eventType­обязательный
Тип: String. Имя события чата (описано далее).
eventListener­обязательный
Тип: Function. Содержит ссылку на метод обработчика события.
Возвращаемое значение:
void.
removeListener(<eventType>, <eventListener>)
Описание:
Удаляет обработчик события <event>.
Параметры:
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.