Dieser Abschnitt beschreibt, wie Chat-(JSBOX-)WebSocket-Kanäle in der Mailoo-API funktionieren, welche Ereignisse sie übertragen und was Sie auf dem öffentlichen API-Host in Produktion konfigurieren müssen (Proxy, TLS, Skalierung).
Übersicht zur Chat-Integration (REST, Schlüssel, BFF): chat-widget{.interpreted-text role="doc"} und chat-widget-nextjs-example{.interpreted-text role="doc"}.
::: {.contents local=""} :::
Wo der WebSocket lebt
Der WebSocket hört nicht auf einem separaten Port. Derselbe Node.js-Prozess, der HTTP (Hono) bedient, erstellt einen http.Server und hängt bei upgrade Clients an ws (WebSocketServer mit noServer: true) an. Pfade sind fest im Servercode:
- Eigentümer (Dashboard) ---
/api/v1/chat/ws - Besucher (Widget) ---
/api/v1/chat/visitor-ws
In Produktion verbinden sich Clients mit dem gleichen Host und Schema wie die REST-API, z. B. wss://api.example.com/api/v1/chat/ws?.... Sie benötigen keinen separaten „WebSocket-Port" --- HTTPS/WSS auf dem veröffentlichten API-Service (üblicherweise 443 hinter einem Load Balancer) reicht aus.
Zwei Kanäle und Authentifizierung
Eigentümer (Dashboard): /api/v1/chat/ws
Abfrageparameter: integrationId, token.
token--- Keycloak-Zugriffs-JWT (gleich wieAuthorization: Bearerfür REST). In der Entwicklung kann ein konfigurierter Bypass einen Dev-Token akzeptieren (wie in der App).- Nach dem
upgradeüberprüft die API den Benutzer und dass die Integration existiert, vom Typ JSBOX ist und diesem Benutzer gehört. - Bei Erfolg registriert sich der Client im In-Memory-Hub nach
integrationIdund erhält{"type":"connected","integrationId":"..."}.
Besucher: /api/v1/chat/visitor-ws
Abfrageparameter: projectUid, integrationId, sessionPublicId.
- Kein API-Schlüssel: Vertrauen basiert auf einer bestehenden Chat-Session in der DB (erstellt durch die erste Webhook-Nachricht) mit übereinstimmender
publicId,integrationIdundproject.uid. - Bei Erfolg --- Hub-Registrierung für
integrationId+sessionPublicId, Antwort{"type":"connected","sessionPublicId":"..."}.
Hub und Ereignisse
Implementiert als In-Memory-Modul (Verbindungs-Maps pro Integration und pro Session). Wenn eine neue Chat-Nachricht erscheint (eingehend vom Besucher oder ausgehende Eigentümerantwort), sendet der Server JSON wie:
{
"type": "chat.message",
"payload": {
"messageId": "...",
"integrationId": "...",
"sessionPublicId": "...",
"messageType": "INBOUND|OUTBOUND",
"content": "...",
"senderEmail": "...",
"senderName": null,
"createdAt": "..."
}
}
Clients verwenden dies, um die UI zu aktualisieren, ohne vollständiges REST-Polling. Wenn WebSocket nicht verfügbar ist, kann die App auf Polling zurückgreifen (wie in der Chat-Konsole oder im Widget).
Produktions-Checkliste (öffentliche Mailoo-API)
Checkliste für Teams, die die Mailoo-API im Internet veröffentlichen. Ein separater „WebSocket-Port" wird nicht publiziert: Sie benötigen einen korrekten Reverse Proxy, TLS und ein klares Skalierungs-Modell.
-
Gleicher Origin wie REST
Das Browser-Widget und das Dashboard erstellen URLs wie
wss://<API_HOST>/api/v1/chat/.... Stellen Sie sicher, dassAPI_PUBLIC_URL/ öffentliches DNS auf denselben Host zeigen, auf dem dieser Prozess läuft (oder einen stabilen Load Balancer davor). -
TLS und ``wss:``
Auf einer HTTPS-Site muss das Widget WSS verwenden. Der Proxy benötigt gültige Zertifikate; der Pfad zur API entspricht normalem HTTPS.
-
Proxy: Upgrade-Unterstützung
Für
/api/v1/chat/wsund/api/v1/chat/visitor-ws(und allgemein für die API, wenn WS dieselbelocationteilt) benötigen Sie:
-
HTTP/1.1 zum Upstream;
-
Upgrade- undConnection-Header (typisches WebSocket-Muster); -
erhöhte Lese-Timeouts für langlebige Verbindungen (Zehn-Minuten/Stunden), da der Proxy sonst ruhige Sockets trennt.
Beispiel-nginx-Fragment (gleicher Upstream wie REST):
location / { proxy_pass http://api_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 3600s; proxy_send_timeout 3600s; }Stellen Sie sicher, dass Ihr Reverse Proxy (oder Cloud-Load-Balancer) WebSocket-Upgrade-/Connection-Header weiterleitet und lange Lese-/Sende-Timeouts auf der API-Location verwendet.
-
Firewall / Sicherheitsgruppen
Gleiche Regeln wie eine normale HTTPS-API (z. B. eingehend 443 zum Load Balancer). Ausgehend zu DB, Keycloak, S3 --- je nach Ihrer Architektur; WebSocket ändert das nicht.
-
Mehrere API-Replikate (wichtig)
Der aktuelle Chat-Hub lebt nur im Prozessspeicher. Eine Eigentümer-Verbindung auf Replikat A sieht keinen Broadcast, der auf Replikat B durchgeführt wird, wenn ein anderer Pod die Nachricht verarbeitet hat.
Optionen:
-
vorübergehend ein einzelnes API-Replikat für zuverlässige Echtzeit betreiben;
-
oder Sticky Sessions (Client an Pod gebunden) per Cookie/IP auf dem Load Balancer aktivieren --- das hilft nur, wenn Nachrichten-Erstellungs-Webhooks und beide WebSockets auf derselben Instanz landen (unzuverlässig bei mehreren Workern);
-
echte horizontale Echtzeit-Skalierung benötigt einen gemeinsamen Broker (Redis Pub/Sub usw.) --- nicht implementiert in der aktuellen Codebasis.
Dokumentieren Sie die gewählte Strategie in Ihrem Produktions-Runbook.
-
Website-Seite (nicht die API)
Das Next.js-BFF und Umgebungsvariablen wie
MAILOO_CHAT_WS_ORIGIN/ API-Basis müssen auf den öffentlichen API-Host zeigen, der WSS bereitstellt. Das wird auf der Website-App konfiguriert, nicht als separater WebSocket-Veröffentlichungsschritt.
Kurzzusammenfassung
Frage Antwort
Separater WebSocket-Port? Nein --- gleicher Service und Pfad wie REST (über 443 und den Proxy).
Was muss der Proxy unterstützen? Upgrade/WebSocket, lange Timeouts, TLS für wss.
Etwas außer HTTP(S) freizugeben? Nein, wenn die API bereits über HTTPS veröffentlicht ist.
Mehrere API-Pods? In-Memory-Hub: einzelnes Replikat, Sticky Sessions oder ein zukünftiger Event-Bus.
Siehe auch
chat-widget{.interpreted-text role="doc"} --- REST, Schlüssel, CORS, Sessionschat-widget-nextjs-example{.interpreted-text role="doc"} --- Next.js-BFF und WebSocket-Origin-Umgebung- OpenAPI:
https://api.mailoo.app/docs/v1