Realtime-события по WebSocket
Какие WebSocket-каналы и события доступны при прямом подключении к AISAR Reverb, и как они соотносятся с вебхуками.
Помимо вебхуков (см. гайд «Вебхуки»), AISAR транслирует часть событий в реальном времени через Pusher-совместимый WebSocket-сервер (Reverb). Это полезно для собственных фронтендов, которым нужна мгновенная реакция на изменения (typing-индикаторы, счётчики, обновления диалогов) без опроса REST API.
Каналы
| Канал | Формат | Назначение |
|---|---|---|
| Компания | private-company.{companyId} | События диалогов/сообщений/контактов/сделок для всей команды |
| Пользователь | private-user.{userId} | Персональные события: счётчики, уведомления |
| Канал (мессенджер) | private-channel.{channelId} | Статус канала, синхронизация контактов/групп |
| Диалог | private-conversation.{conversationId} | Индикаторы набора текста и присутствия контакта |
Активные события
Сообщения (канал: company)
Транслируются: message.created, message.updated, message.deleted, message.read, message.status.updated, message.reaction.updated. Тело события:
{
"conversation_id": 750,
"thread_id": 750,
"message": { "...MessageResource..." }
}Диалоги (канал: company)
Транслируются: conversation.created, conversation.updated, conversation.closed, conversation.reopened, conversation.assigned, conversation.unassigned.
{ "conversation_id": 750 }{
"conversation_id": 750,
"action": "added",
"participant": { "id": 1, "member_type": "user", "member_id": 5, "role": "agent" }
}Счётчики (канал: user)
chat.counters.updated обновляет бейджи фильтров диалогов. Срабатывает при любом счётчик-влияющем событии (message.created/deleted/read, conversation.created/updated/closed/reopened/assigned/unassigned) — пересчитывается персонально для каждого пользователя компании.
{
"counters": {
"all": 42,
"awaiting": 5,
"unread": 8,
"assigned": 15,
"unassigned": 2,
"archived": 18
}
}Уведомления (канал: user)
notification.created — новое персональное уведомление пользователя.
Каналы обмена сообщениями (канал: channel)
channel.realtime.update — единое событие с маршрутизацией по payload.type: channel_status (смена статуса канала), contacts_synced/contacts_updated, groups_synced/group_updated/group_participants_updated, history_sync_progress.
Сделки и AI-агенты (канал: company)
deal.updated — изменение сделки. ai-pending-action.updated — изменение статуса действия AI-агента, ожидающего подтверждения оператора (action: "created" | "approved" | "rejected"), payload { event_id, conversation_id, action }.
Broadcast-only события (не доставляются как вебхук)
Некоторые события транслируются только через WebSocket, без соответствующего исходящего HTTP-вебхука: contact.outbound_eligibility_updated (право контакта на исходящие/WhatsApp-звонки, payload {contact_id, channel_id} либо вариант с contact_account_id + call{...}) и nudges.updated (in-app nudge-баннер, payload {company_id}). Если вашей интеграции нужны именно эти сигналы — подписывайтесь на них через WebSocket, вебхук не сработает.
Надёжность
- Broadcast-события, порождённые внутри транзакции БД, отправляются только после её коммита — вы никогда не увидите событие о сущности, которая затем откатилась.
- Доставка синхронная (не через очередь) — задержка минимальна, но события не буферизуются на время дисконнекта.
- Расчёт счётчика
unreadзависит от настройки компанииshared_read_receipts: приtrue— максимумlast_read_atпо всем пользователям, приfalse— индивидуальныйlast_read_atкаждого пользователя.
AISAR подключается к Reverb по Pusher-совместимому протоколу (wsHost: api.aisar.app, TLS-порт 443, authEndpoint: https://api.aisar.app/broadcasting/auth). Подписка на приватные каналы (private-*) требует токен-авторизации на /broadcasting/auth и проходит per-channel ACL — пользователь одной компании не может подписаться на канал другой. За реквизитами подключения (app key и т.п.) обратитесь в поддержку AISAR.