Chatbot WebSocket API (Live Chat)
WebSocket API
Используйте WebSocket API для живого чата в реальном времени: мгновенная доставка сообщений, индикаторы набора текста, статус присутствия, автоперевод и управление жизненным циклом сессии. Один и тот же сокет обслуживает виджеты посетителей и панель агента, поэтому вы можете создать собственную консоль оператора или управлять живым чатом из своего бэкенда.
Эндпоинт
wss://webchatagent.com/api/livechat
Весь трафик передается в формате JSON. Вы отправляете события client:*, а сервер возвращает события livechat:*. Каждое сообщение содержит поле type.
Роли подключения
При подключении вы указываете роль в поле as:
| Роль | Описание |
|---|---|
user | Посетитель сайта в чате. |
admin | Оператор человек, управляющий сессиями живого чата. |
widget | Встроенный виджет чата в режиме мониторинга (до перехвата диалога). |
Роль определяет, какие данные вы получаете: клиенты admin получают полную историю сообщений и события только для администраторов, а клиенты user получают только новые текущие события (посетители загружают свою историю через REST эндпоинт истории, а не через сокет).
Краткая схема работы
- Откройте сокет и отправьте
client:join, указав вашиchatbotId,sessionIdиas. - Сервер ответит сообщением
{ "type": "livechat:status", "ok": true }для подтверждения входа. Затем администраторы получат историю сообщений и текущий снимокlivechat:status. - Отправляйте
client:messageдля публикации и получайтеlivechat:messageдля каждого нового сообщения. - Отправляйте
client:typingи получайтеlivechat:typingдля индикации набора текста. - Завершите диалог с помощью
client:endили получитеlivechat:ended, когда другая сторона закроет чат.
Клиентские события (вы отправляете)
client:join
Первое событие после подключения. Выполняет вход в комнату сессии (а для администраторов также в комнату чат-бота).
{
"type": "client:join",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"as": "user",
"lang": "en",
"translateEnabled": true,
"retranslateBacklog": false
}
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
chatbotId | string | Да | UUID вашего чат-бота. Для администратора, отслеживающего всех ботов, специальное значение "all" выполняет подключение без привязки к конкретной комнате. |
sessionId | string | Да | ID сессии чата. |
as | string | Да | user, admin или widget. |
lang | string | Нет | Предпочитаемый код языка (например, en, de, fr). Задает целевой язык перевода. |
translateEnabled | boolean | Нет | Включить автоперевод для этой сессии (по умолчанию: включен). |
retranslateBacklog | boolean | Нет | Повторно переводить существующие сообщения из истории на язык lang при входе (для admin). |
client:message
Отправка сообщения в сессию. Сервер сохраняет его, переводит при включенной функции и рассылает событие livechat:message.
{
"type": "client:message",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"sender": "user",
"content": "I need help with my order",
"lang": "en"
}
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
chatbotId | string | Да | UUID вашего чат-бота. |
sessionId | string | Да | ID сессии чата. |
sender | string | Да | user или admin. |
content | string | Да | Текст сообщения. Пустой или отсутствующий content игнорируется. |
lang | string | Нет | Подсказка языка сообщения для перевода. |
Первое сообщение от admin в сессии со статусом waiting открывает ее (статус → open) и автоматически добавляет системное уведомление о подключении оператора.
client:typing
Рассылка индикатора набора текста всем участникам сессии.
{
"type": "client:typing",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"sender": "user",
"isTyping": true
}
client:meta
Обновление метаданных сессии (текущая страница), чтобы операторы видели, где находится посетитель.
{
"type": "client:meta",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"pageUrl": "https://example.com/pricing",
"pageTitle": "Pricing - Example",
"referrer": "https://google.com",
"browserLanguage": "en-US"
}
client:agent_takeover
Оператор превентивно перехватывает сессию у AI (переводит ее в open / human). Доступно только для роли admin.
{
"type": "client:agent_takeover",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID"
}
client:end
Завершение сессии.
{
"type": "client:end",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"reason": "resolved"
}
client:widget_open / client:widget_close
Отправляется виджетом для регистрации или отмены регистрации активной сессии для отображения у администратора (именно это заполняет livechat:widget_sessions).
{
"type": "client:widget_open",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"pageUrl": "https://example.com",
"pageTitle": "Home",
"browserLanguage": "en-US"
}
Серверные события (вы получаете)
livechat:status
Две формы: простое подтверждение входа { "type": "livechat:status", "ok": true } и снимок статуса сессии (ниже).
{
"type": "livechat:status",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"status": "open",
"mode": "human",
"userName": "John",
"userEmail": "john@example.com",
"userLanguage": "en"
}
| Поле | Тип | Описание |
|---|---|---|
status | string | waiting (оператор еще не подключился), open (оператор подключен) или closed. |
mode | string | bot или human. |
userName | string | null | Имя посетителя, если оно получено через раздел Лиды. |
userEmail | string | null | Эл. почта посетителя, если она получена. |
userLanguage | string | null | Определенный язык посетителя. |
livechat:message
Новое сообщение (или сообщение из истории).
{
"type": "livechat:message",
"id": 1024,
"sessionId": "SESSION_ID",
"sender": "admin",
"content": "Hello! How can I help you today?",
"country": "DE",
"createdAt": "2025-01-15T10:30:00Z",
"file": null,
"audience": "admin",
"historical": false
}
| Поле | Тип | Описание |
|---|---|---|
id | number | ID сообщения (соответствует id в истории REST). |
sender | string | user, admin или system. |
content | string | Текст сообщения. Для клиентов admin с включенным переводом текст уже переведен на язык оператора. |
country | string | null | Код страны отправителя, если определен. |
createdAt | string | Временная метка ISO 8601. |
file | object | null | Метаданные прикрепленного файла (uploadId, name, mimeType, size, url, isImage), если сообщение содержит загрузку. |
audience | string | null | Значение "admin" для копии сообщения, предназначенной оператору. В копии для пользователя это поле опущено. |
historical | boolean | Значение true для сообщений из истории, воспроизводимых при подключении. |
Системные сообщения: когда
senderимеет значениеsystem, полеcontentсодержит токен, который ваш клиент должен локализовать, а не отображать буквально:__agent_joined__,__livechat_ended__или__livechat_timeout__.
livechat:typing
Индикатор набора текста от другого участника: { type, chatbotId, sessionId, sender, isTyping }.
livechat:presence
Статус онлайн/оффлайн посетителя в сессии: { type, chatbotId, sessionId, online } (boolean).
livechat:meta
Обновленные метаданные сессии (текущая страница, заголовок, реферер), только для администратора.
livechat:ended
Сессия была закрыта.
{
"type": "livechat:ended",
"sessionId": "SESSION_ID",
"reason": "admin_closed"
}
Поле reason принимает одно из значений: admin_closed, already_closed или timeout.
События только для администраторов
| Событие | Полезная нагрузка | Назначение |
|---|---|---|
livechat:active_count | { chatbotId, count } | Активные сессии (ожидание + открытые). |
livechat:waiting_count | { chatbotId, count } | Сессии в ожидании (бейдж для чатов без ответа). |
livechat:new_request | { chatbotId, sessionId, status, mode, ... } | Для нового живого чата требуется оператор. |
livechat:widget_sessions | { chatbotId, chatbotName, sessions } | Текущий список активных сессий виджета. |
livechat:notification | { chatbotId, sessionId, content, sender } | Новое сообщение, пока оператор находится в другой части панели управления. |
Автоперевод
Сокет может автоматически переводить сообщения между языками посетителя и оператора:
- Подключитесь с параметром
translateEnabled: trueи укажите вlangваш язык. - Сообщения от собеседника приходят уже переведенными на ваш
lang. Каждая сторона сохраняет исходный текст, а переведенная копия доставляется другому участнику. - Перевод выполняется с помощью Gemini, благодаря чему оператор может общаться с посетителем на любом языке без ручного перевода.
Пример: собственный клиент живого чата
const ws = new WebSocket('wss://webchatagent.com/api/livechat');
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'client:join',
chatbotId: 'YOUR_CHATBOT_ID',
sessionId: 'SESSION_ID',
as: 'user',
lang: 'en'
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case 'livechat:status':
// Join ack ({ ok: true }) or a session snapshot ({ status, mode, ... })
if (data.ok) console.log('Joined');
else console.log(`Status: ${data.status}, mode: ${data.mode}`);
break;
case 'livechat:message':
if (data.sender === 'system') {
// Localize tokens like __agent_joined__ / __livechat_ended__
console.log('[system]', data.content);
} else {
console.log(`${data.sender}: ${data.content}`);
}
break;
case 'livechat:typing':
console.log(`${data.sender} is typing: ${data.isTyping}`);
break;
case 'livechat:ended':
console.log(`Session ended: ${data.reason}`);
ws.close();
break;
}
};
function sendMessage(text) {
ws.send(JSON.stringify({
type: 'client:message',
chatbotId: 'YOUR_CHATBOT_ID',
sessionId: 'SESSION_ID',
sender: 'user',
content: text,
lang: 'en'
}));
}
function sendTyping(isTyping) {
ws.send(JSON.stringify({
type: 'client:typing',
chatbotId: 'YOUR_CHATBOT_ID',
sessionId: 'SESSION_ID',
sender: 'user',
isTyping
}));
}
