Chatbot WebSocket API (Live-Chat)
WebSocket API
Verwende die WebSocket API für Echtzeit-Live-Chat: sofortige Nachrichtenübermittlung, Tippanzeigen, Anwesenheit, automatische Übersetzung und Sitzungslebenszyklus. Derselbe Socket versorgt Besucher-Widgets und das Agenten-Dashboard, sodass du eine benutzerdefinierte Agenten-Konsole erstellen oder den Live-Chat über dein eigenes Backend steuern kannst.
Endpoint
wss://webchatagent.com/api/livechat
Der gesamte Datenverkehr ist JSON. Du sendest client:*-Events; der Server sendet livechat:*-Events zurück. Jede Nachricht enthält ein type-Feld.
Verbindungsrollen
Beim Beitreten deklarierst du eine Rolle mit dem as-Feld:
| Rolle | Beschreibung |
|---|---|
user | Ein Website-Besucher in einem Chat. |
admin | Ein menschlicher Agent, der Live-Chat-Sitzungen verwaltet. |
widget | Das eingebettete Chat-Widget im Überwachungsmodus (vor einer Übernahme). |
Die Rolle bestimmt, was du empfängst: admin-Clients erhalten den vollständigen Nachrichtenverlauf und reine Admin-Events; user-Clients erhalten nur neue Live-Events (Besucher laden ihren eigenen Verlauf über den REST-Verlauf-Endpunkt, nicht über den Socket).
Schnellübersicht zum Ablauf
- Öffne den Socket und sende
client:joinmit deinerchatbotId,sessionIdundas. - Der Server antwortet mit
{ "type": "livechat:status", "ok": true }, um den Beitritt zu bestätigen. Admins erhalten anschließend den Nachrichtenverlauf und einen aktuellenlivechat:status-Snapshot. - Sende
client:message, um zu posten; empfangelivechat:messagefür jede neue Nachricht. - Sende
client:typing/ empfangelivechat:typingfür Tippanzeigen. - Beende mit
client:end, oder empfangelivechat:ended, wenn die Gegenseite schließt.
Client-Events (du sendest)
client:join
Das erste Event nach dem Verbinden. Tritt dem Sitzungsraum bei (und für Admins dem Chatbot-Raum).
{
"type": "client:join",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"as": "user",
"lang": "en",
"translateEnabled": true,
"retranslateBacklog": false
}
| Feld | Typ | Pflichtfeld | Beschreibung |
|---|---|---|---|
chatbotId | string | Ja | Die UUID deines Chatbots. Für einen Admin, der alle Bots überwacht, tritt der spezielle Wert "all" ohne spezifischen Raum bei. |
sessionId | string | Ja | Die Chat-Sitzungs-ID. |
as | string | Ja | user, admin oder widget. |
lang | string | Nein | Bevorzugter Sprachcode (z. B. en, de, fr). Legt das Übersetzungsziel fest. |
translateEnabled | boolean | Nein | Automatische Übersetzung für diese Sitzung aktivieren (Standard: aktiviert). |
retranslateBacklog | boolean | Nein | Vorhandene Verlaufsnachrichten beim Beitritt erneut in lang übersetzen (Admin). |
client:message
Veröffentliche eine Nachricht in der Sitzung. Der Server speichert sie dauerhaft, übersetzt sie, falls aktiviert, und sendet livechat:message an alle.
{
"type": "client:message",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"sender": "user",
"content": "I need help with my order",
"lang": "en"
}
| Feld | Typ | Pflichtfeld | Beschreibung |
|---|---|---|---|
chatbotId | string | Ja | Die UUID deines Chatbots. |
sessionId | string | Ja | Die Chat-Sitzungs-ID. |
sender | string | Ja | user oder admin. |
content | string | Ja | Der Nachrichtentext. Ein leerer oder fehlender content wird verworfen. |
lang | string | Nein | Sprachhinweis der Nachricht für die Übersetzung. |
Die erste admin-Nachricht in einer Sitzung mit dem Status waiting öffnet diese (Status → open) und fügt automatisch einen Systemhinweis "Agent beigetreten" ein.
client:typing
Sende eine Tippanzeige an alle Teilnehmer in der Sitzung.
{
"type": "client:typing",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"sender": "user",
"isTyping": true
}
client:meta
Sitzungsmetadaten (aktuelle Seite) aktualisieren, damit Agenten sehen, wo sich der Besucher befindet.
{
"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
Der Admin übernimmt proaktiv eine KI-Sitzung (setzt sie auf open / human). Nur für Admins.
{
"type": "client:agent_takeover",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID"
}
client:end
Die Sitzung beenden.
{
"type": "client:end",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"reason": "resolved"
}
client:widget_open / client:widget_close
Wird vom Widget gesendet, um eine aktive Sitzung für die Admin-Sichtbarkeit zu registrieren oder abzumelden (dies befüllt livechat:widget_sessions).
{
"type": "client:widget_open",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"pageUrl": "https://example.com",
"pageTitle": "Home",
"browserLanguage": "en-US"
}
Server-Events (du empfängst)
livechat:status
Zwei Formen: eine einfache Beitrittsbestätigung { "type": "livechat:status", "ok": true } und ein Snapshot des Sitzungsstatus (unten).
{
"type": "livechat:status",
"chatbotId": "YOUR_CHATBOT_ID",
"sessionId": "SESSION_ID",
"status": "open",
"mode": "human",
"userName": "John",
"userEmail": "john@example.com",
"userLanguage": "en"
}
| Feld | Typ | Beschreibung |
|---|---|---|
status | string | waiting (noch kein Agent), open (Agent verbunden) oder closed. |
mode | string | bot oder human. |
userName | string | null | Besuchername, falls über Leads erfasst. |
userEmail | string | null | Besucher-E-Mail, falls erfasst. |
userLanguage | string | null | Erkannte Besuchersprache. |
livechat:message
Eine neue Nachricht (oder Verlaufsnachricht).
{
"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
}
| Feld | Typ | Beschreibung |
|---|---|---|
id | number | Nachrichten-ID (entspricht der id im REST-Verlauf). |
sender | string | user, admin oder system. |
content | string | Nachrichtentext. Für admin-Clients mit aktivierter Übersetzung ist dies bereits in die Admin-Sprache übersetzt. |
country | string | null | Ländercode des Absenders, falls erkannt. |
createdAt | string | ISO-8601-Zeitstempel. |
file | object | null | Metadaten der angehängten Datei (uploadId, name, mimeType, size, url, isImage), wenn die Nachricht ein Upload ist. |
audience | string | null | "admin" auf der für den Admin bestimmten Kopie einer Nachricht. Die an den Benutzer gerichtete Kopie lässt dies weg. |
historical | boolean | true für Verlaufsnachrichten, die beim Beitritt wiedergegeben werden. |
Systemnachrichten: Wenn
sendergleichsystemist, istcontentein Token, das dein Client lokalisieren und nicht wörtlich anzeigen sollte:__agent_joined__,__livechat_ended__oder__livechat_timeout__.
livechat:typing
Tippanzeige eines anderen Teilnehmers: { type, chatbotId, sessionId, sender, isTyping }.
livechat:presence
Online/Offline-Status des Besuchers in einer Sitzung: { type, chatbotId, sessionId, online } (boolean).
livechat:meta
Aktualisierte Sitzungsmetadaten (aktuelle Seite, Titel, Referrer), nur für Admins.
livechat:ended
Die Sitzung wurde geschlossen.
{
"type": "livechat:ended",
"sessionId": "SESSION_ID",
"reason": "admin_closed"
}
reason ist einer der Werte admin_closed, already_closed oder timeout.
Reine Admin-Events
| Event | Payload | Zweck |
|---|---|---|
livechat:active_count | { chatbotId, count } | Aktive Sitzungen (wartend + offen). |
livechat:waiting_count | { chatbotId, count } | Wartende Sitzungen (Badge für unbeantwortete Chats). |
livechat:new_request | { chatbotId, sessionId, status, mode, ... } | Ein neuer Live-Chat benötigt einen Agenten. |
livechat:widget_sessions | { chatbotId, chatbotName, sessions } | Aktuelle Liste der aktiven Widget-Sitzungen. |
livechat:notification | { chatbotId, sessionId, content, sender } | Neue Nachricht, während der Agent sich an anderer Stelle im Dashboard befindet. |
Automatische Übersetzung
Der Socket kann automatisch zwischen den Sprachen von Besucher und Agent übersetzen:
- Tritt mit
translateEnabled: truebei und setzelangauf deine Sprache. - Nachrichten der Gegenseite kommen bereits in deine
langübersetzt an. Jede Partei behält ihren Originaltext; die übersetzte Kopie wird an die andere Seite zugestellt. - Die Übersetzung läuft über Gemini, sodass ein Agent mit einem Besucher in jeder Sprache chatten kann, ohne manuell zu übersetzen.
Beispiel: Benutzerdefinierter Live-Chat-Client
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
}));
}
