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:

RolleBeschreibung
userEin Website-Besucher in einem Chat.
adminEin menschlicher Agent, der Live-Chat-Sitzungen verwaltet.
widgetDas 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

  1. Öffne den Socket und sende client:join mit deiner chatbotId, sessionId und as.
  2. Der Server antwortet mit { "type": "livechat:status", "ok": true }, um den Beitritt zu bestätigen. Admins erhalten anschließend den Nachrichtenverlauf und einen aktuellen livechat:status-Snapshot.
  3. Sende client:message, um zu posten; empfange livechat:message für jede neue Nachricht.
  4. Sende client:typing / empfange livechat:typing für Tippanzeigen.
  5. Beende mit client:end, oder empfange livechat: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
}
FeldTypPflichtfeldBeschreibung
chatbotIdstringJaDie UUID deines Chatbots. Für einen Admin, der alle Bots überwacht, tritt der spezielle Wert "all" ohne spezifischen Raum bei.
sessionIdstringJaDie Chat-Sitzungs-ID.
asstringJauser, admin oder widget.
langstringNeinBevorzugter Sprachcode (z. B. en, de, fr). Legt das Übersetzungsziel fest.
translateEnabledbooleanNeinAutomatische Übersetzung für diese Sitzung aktivieren (Standard: aktiviert).
retranslateBacklogbooleanNeinVorhandene 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"
}
FeldTypPflichtfeldBeschreibung
chatbotIdstringJaDie UUID deines Chatbots.
sessionIdstringJaDie Chat-Sitzungs-ID.
senderstringJauser oder admin.
contentstringJaDer Nachrichtentext. Ein leerer oder fehlender content wird verworfen.
langstringNeinSprachhinweis 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"
}
FeldTypBeschreibung
statusstringwaiting (noch kein Agent), open (Agent verbunden) oder closed.
modestringbot oder human.
userNamestring | nullBesuchername, falls über Leads erfasst.
userEmailstring | nullBesucher-E-Mail, falls erfasst.
userLanguagestring | nullErkannte 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
}
FeldTypBeschreibung
idnumberNachrichten-ID (entspricht der id im REST-Verlauf).
senderstringuser, admin oder system.
contentstringNachrichtentext. Für admin-Clients mit aktivierter Übersetzung ist dies bereits in die Admin-Sprache übersetzt.
countrystring | nullLändercode des Absenders, falls erkannt.
createdAtstringISO-8601-Zeitstempel.
fileobject | nullMetadaten der angehängten Datei (uploadId, name, mimeType, size, url, isImage), wenn die Nachricht ein Upload ist.
audiencestring | null"admin" auf der für den Admin bestimmten Kopie einer Nachricht. Die an den Benutzer gerichtete Kopie lässt dies weg.
historicalbooleantrue für Verlaufsnachrichten, die beim Beitritt wiedergegeben werden.

Systemnachrichten: Wenn sender gleich system ist, ist content ein 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

EventPayloadZweck
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: true bei und setze lang auf 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
  }));
}