К содержанию
sapportlydocs
Панель

Как это работает

Кто пишет посетителю, куда девается сообщение и чем отличаются приём входящих, ответ и панель.

Три роли

Роль 1

Посетитель

Клиент на сайте или в вашем продукте. Пишет через виджет Sapportly или через ваш интерфейс — тогда входящее кладёте вы.

Роль 2

Ваш сервер

API-ключ и Sapportly TypeScript SDK (@sapportly/sdk, не @supportly/sdk). Приём входящих пишет сообщение, ответ — исходящее в ленту канала. Доставка во внешний канал (почта, мессенджер, CRM) — ваша, если это не виджет.

Роль 3

Оператор

Человек из команды в app.sapportly.pro. Сессия JWT, не API-ключ. Кнопка «Ответить» во входящих.

Источник и тред

Ключ вида namespace:slug (custom:shop) — источник для реестра и аналитики. Один магазин = один источник. Диалог с человеком — custom:shop:{uuid}: его собирает приём входящих из identity.external_id (UUID v5) или из thread_id. Не создавайте custom:user-123 — аналитика по каналам тогда разъедется.

Исключение — виджет: в панели нужен чат 1:1, поэтому посетитель живёт в widget:{uuid}, а реестр виджета один — widget:web. Подробнее про каналы.

Что происходит после приёма входящих

  1. Ваш сервер вызывает POST /v1/ingest/messages (виджет — POST /v1/widget/messages).
  2. Шлюз проверяет ключ и кладёт событие в очередь. Ответ сразу 202, message_id ещё null — запись асинхронная.
  3. Запись в хранилище пишет строку в Postgres. Живой канал пушит кадр message.delivered в открытые сокеты: панель и ваш SDK.
  4. Параллельно AI может готовить черновик. Кадры ai.draft уходят и в панель, и интегратору (частичные — partial: true). Это не строка истории. Если в панели включён автоответ, в ленту пишется обычное исходящее агента — тот же кадр, что у оператора.

Как ответить

Исходящее в ленту — не приём входящих. Тот же ключ канала. SDK ставит idempotency_key, если вы его не передали.

reply.tsTypeScript
await client.conversations.reply(threadChannel, {
  body: "Заказ отправлен, трек 123",
});

Свой inbox.reply приходит по сокету с echo: true — повторно во внешний канал его слать не нужно. Ответ оператора из панели echo не несёт: если канал custom, доставку человеку делаете вы.

Три способа получать события

КаналКогдаКак
WebSocketНужен живой канал (бот, своя админка)SapportlyInbox, право ws:connect. Гайд
ВебхукиМожно подождать сотни мсHMAC на ваш URL, проверка подписи
REST historyРеконнект, аудитclient.conversations.messages(channel)

Один message_id может прийти и по WS, и по вебхуку. В SDK есть MessageDeduper — SapportlyInbox включает его по умолчанию.

От сообщения до результата

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

Вложения идут тем же безопасным маршрутом: изображение отображается как изображение, а неподдерживаемый формат — как документ. Файл сначала загружается по короткоживущей ссылке, проходит проверки, и только после этого прикрепляется к сообщению. При включённом E2EE содержимое читают только участники диалога; ключи не попадают в аналитику и вебхуки.

Страница полезна?

/docs/how-it-works
Как работает Sapportly — приём, ответ, панель · Sapportly Docs