Как это устроено

Один агент, все каналы

Как веб-виджет, Telegram и WhatsApp попадают к одному и тому же агенту с одной и той же памятью — разрешение идентичности, общая логика и то, что остаётся спецификой канала.

Клиент спрашивает что-то на вашем сайте, а через две недели возвращается уже в WhatsApp. Одни это отношения или два незнакомца — решает то, как разрешается идентичность, а вовсе не интерфейс чата.

Общая картина

Каналы — это точки входа, а не изолированные мирки. Каждый из них ведёт к одним и тем же трём вещам:

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

Разрешение идентичности

Каждый канал сообщает внешний идентификатор — id конечного пользователя из токена виджета, id пользователя Telegram, номер WhatsApp. Разрешение идёт по паре (tenant, external_user_id): поиск, а при первой встрече — создание.

Две детали, которые стоит знать:

  • Первый контакт подвержен гонке, и она обработана. Два сообщения, пришедшие одновременно, оба не нашли бы пользователя и оба попытались бы его создать. Спор решает уникальное ограничение, а проигравший перечитывает запись вместо того, чтобы упасть с ошибкой. Поэтому пачка одновременных первых сообщений даёт одного пользователя, а не ошибку.
  • Пространство находится или создаётся. У каждого пользователя есть пространство по умолчанию, а явно запрошенное пространство обязано принадлежать именно ему — иначе запрос отклоняется. Именно эта проверка не даёт подделанному запросу прочитать чужие разговоры.

Связывать одного человека между каналами — решение тенанта, а не догадка платформы. Мы не сливаем посетителя сайта с номером WhatsApp на том основании, что они похожи: именно такие выводы приводят к утечке истории одного клиента к другому. Там, где вы можете опознать одного и того же человека (авторизованный пользователь, ссылка с id конечного пользователя), передавайте один и тот же идентификатор — и история пойдёт за ним. Там, где не можете, они останутся разными.

Что адаптер объединяет, а что нет

Telegram и WhatsApp выглядят по-разному, но делают одно и то же. Слой адаптера держит всё, что не должно расходиться:

Общее в адаптереСвоё у каждого канала
Разрешение идентичности и поиск пространстваОтрисовка сообщений и вызовы отправки
Чтение и запись текущей сессииInline-клавиатуры и формы Telegram
Команды — новая, список, переключение, история, переименование, удаление, геопозиция, помощьСписки и интерактивные ответы WhatsApp
Воспроизведение и форматирование историиОбработка вложений, специфичная для платформы
Подсказка о медленном ответе
Выполнение хода

Правило простое: семантика разговора живёт в одном месте. Если бы переключение сессий работало в WhatsApp хоть немного иначе, чем в Telegram, эта разница оставалась бы невидимой ровно до того момента, когда на неё наткнётся клиент.

Практическое следствие: это интеграции для личных чатов. В личном чате Telegram id чата и id отправителя совпадают, поэтому адресат отправки и ключ идентичности схлопываются в одно значение — вот почему адаптер может считать «кто это» и «куда отвечать» одним и тем же понятием.

Долгие ответы

Некоторые ответы невозможно получить внутри хода. Агент может запланировать работу и позволить ответу прийти позже — прямо в тот канал, откуда пришёл запрос: пузырём в веб-виджете, сообщением в Telegram или WhatsApp. См. Отложенные касания.

Что это даёт на практике

  • Один клиент, одна история — откуда бы он ни писал.
  • Добавление канала не разветвляет логику разговора.
  • Поиск и память ведут себя везде одинаково, потому что привязаны к пространству, а не к каналу.

Настройка каналов описана в Telegram и WhatsApp и Встраивание веб-виджета.