DOCS/Webhooks~ 8 MIN LESEN

EVENTS · HMAC · POST

EasyLiveChat ruft Sie an
in dem Moment, in dem etwas passiert.

Webhooks sind der Push-Kanal von EasyLiveChat — statt unsere API regelmäßig abzufragen, geben Sie uns eine URL und wir POSTen jedes relevante Ereignis innerhalb einer Sekunde nach seinem Auftreten dorthin. Jede Anfrage wird mit HMAC-SHA256 signiert, damit Ihr Server beweisen kann, dass sie wirklich von uns stammt.

§ 00Was Webhooks sind

Wenn auf der EasyLiveChat-Seite etwas passiert — ein Kunde schickt eine Nachricht in Ihr Widget, ein Agent schließt ein Gespräch, eine audit-relevante Aktion findet statt — senden wir einen ausgehenden HTTPS-POST an jede registrierte URL. Der Body ist JSON und enthält die vollständige Ereignis-Payload, sodass Ihr Server ohne Polling reagieren kann.

Stellen Sie es sich als Spiegelbild der REST-API vor. Die API ist für Code, den Sie kontrollieren und der in EasyLiveChat hineinreicht. Webhooks sind dafür, dass EasyLiveChat in Ihren Code hineinreicht. Die meisten Integrationen nutzen beides.

Jeder registrierte Endpunkt hat sein eigenes Geheimnis. Wir signieren jeden Request-Body mit HMAC-SHA256 unter Verwendung dieses Geheimnisses und senden den Hex-Digest im Header x-easylivechat-signature. Ihr Server berechnet das HMAC mit demselben Geheimnis nochmals und vergleicht — Übereinstimmung bedeutet, die Anfrage kam wirklich von uns, ein Mismatch bedeutet verwerfen.

§ 01Plan-Verfügbarkeit

Webhook-Endpunkte können in jedem kostenpflichtigen Plan und während der 14-tägigen Testphase erstellt werden. Es gibt keine Abrechnung pro Ereignis — die Fan-out-Verteilung auf mehrere Endpunkte ist enthalten.

Der audit.event-Stream ist nur Enterprise, gegated durch das auditWebhookExport-Entitlement. message.created und conversation.updated feuern in jedem Plan, der API-Zugriff erlaubt.

§ 02Endpunkt konfigurieren

Endpunkt hinzufügen unter https://app.livechattools.com/settings/webhooks. Wir generieren einen zufälligen Endpunkt-spezifischen Schlüssel und zeigen ihn Ihnen genau einmal bei der Erstellung. Behandeln Sie ihn wie ein Passwort — kopieren Sie ihn sofort in den Secret-Store Ihres Servers.

  • URLMuss https:// sein und auf eine öffentliche IP auflösen. Wir lehnen Loopback-, private und Cloud-Metadaten-Adressen sowohl bei der Erstellung als auch bei der Zustellung ab.
  • EreignisseWählen Sie entweder spezifische Ereignisnamen oder abonnieren Sie * (alle Ereignisse). Wildcards sind praktisch zum Prototyping, aber engere Ereignislisten machen Ihren Handler verständlicher.
  • GeheimnisAutomatisch generiert, einmal angezeigt. Wird zum Signieren jeder Zustellung verwendet. Wenn Sie es verlieren, löschen Sie den Endpunkt und erstellen einen neuen — es gibt keinen Wiederherstellungspfad.

Standardmäßig aktiv. Sie können einen Endpunkt jederzeit von derselben Seite aus widerrufen — Zustellungen stoppen sofort.

§ 03Payload-Struktur

Jede Zustellung ist ein POST mit content-type: application/json. Header identifizieren das Ereignis und tragen die Signatur; der Body-Umschlag ist immer { event, deliveredAt, data }:

POST https://your-server.example.com/webhook
content-type: application/json
user-agent: EasyLiveChat-Webhooks/1.0
x-easylivechat-event: message.created
x-easylivechat-signature: sha256=<hex>

{
  "event": "message.created",
  "deliveredAt": "2026-05-27T08:55:25.841Z",
  "data": {
    "conversationId": "cmp...",
    "message": {
      "id": "cmp...",
      "body": "Hi!",
      "senderType": "CUSTOMER",
      "createdAt": "2026-05-27T08:55:25.840Z"
    }
  }
}

event ist derselbe Wert wie der Header x-easylivechat-event. Die Form von data variiert je nach Ereignis — siehe Ereigniskatalog unten.

§ 04Signatur prüfen

Jeder, der Ihre Endpunkt-URL kennt, kann Schrott dorthin POSTen. Die HMAC-Signatur ist, wie Sie unsere Anfragen von gefälschten unterscheiden. Berechnen Sie sie mit Ihrem Geheimnis neu und lehnen Sie die Anfrage bei Mismatch ab.

Lesen Sie die rohen Body-Bytes (NICHT zuerst json.parse — erneutes Serialisieren ordnet die Schlüssel um und bricht den Hash). Entfernen Sie das sha256=-Präfix vom Signatur-Header. Berechnen Sie HMAC-SHA256(rawBody, secret) und vergleichen Sie zeitsicher mit dem empfangenen Hex.

Node.js

import crypto from 'node:crypto';
import express from 'express';

const SECRET = process.env.WEBHOOK_SECRET;
const app = express();
app.use(express.raw({ type: 'application/json' }));

app.post('/webhook', (req, res) => {
  const received = (req.header('x-easylivechat-signature') || '').replace(/^sha256=/, '');
  const expected = crypto.createHmac('sha256', SECRET).update(req.body).digest('hex');
  const ok =
    received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received, 'hex'), Buffer.from(expected, 'hex'));
  if (!ok) return res.status(401).send('bad signature');

  const event = JSON.parse(req.body.toString('utf8'));
  // handle event.event, event.data...
  res.status(200).send('ok');
});

Python (Flask)

import hmac, hashlib, os
from flask import Flask, request, abort

SECRET = os.environ["WEBHOOK_SECRET"].encode()
app = Flask(__name__)

@app.post("/webhook")
def webhook():
    received = request.headers.get("x-easylivechat-signature", "").removeprefix("sha256=")
    expected = hmac.new(SECRET, request.get_data(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(received, expected):
        abort(401)
    event = request.get_json()
    # handle event["event"], event["data"]...
    return "ok", 200

curl (debugging)

# Recompute the signature locally and compare with the header.
echo -n "$RAW_BODY" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET"

timingSafeEqual / hmac.compare_digestverwenden Sie immer einen konstanten Zeitvergleich, damit Angreifer das Geheimnis nicht Byte für Byte abtasten können.

§ 05Ereigniskatalog

Heute feuert die Plattform vier Ereignistypen. Wir fügen mehr hinzu, wenn Features ausgeliefert werden — abonnieren Sie *, wenn Sie Vorwärtskompatibilität wollen.

EreignisFeuert wennDatenform
message.createdEine neue Nachricht landet in einem Gespräch, unabhängig vom Absender (Kunde eingehend, Agent ausgehend, REST-API-Versand).{ conversationId, message }
conversation.updatedDer Status eines Gesprächs (OPEN · SNOOZED · CLOSED) oder dessen assignedAgentId ändert sich.{ conversationId, status?, assignedAgentId? }
audit.eventWann immer eine Audit-Log-Zeile geschrieben wird — Agent-Login, Rollenwechsel, Integration erstellt, Schlüssel widerrufen, etc. (Enterprise-Plan.){ action, entity, entityId, actorId, metadata }
webhook.testSie klicken auf "Test" unter Einstellungen → Webhooks. Signiert und geformt genau wie ein echtes Ereignis.{ tenantId, test: true }

Abonnieren Sie *, um jedes aktuelle und zukünftige Ereignis zu empfangen. Abonnieren Sie bestimmte Namen, wenn Sie einschränken wollen, was Ihr Handler wissen muss.

§ 06Integration testen

Die Schaltfläche "Test" in Einstellungen → Webhooks feuert ein webhook.test-Ereignis an Ihren Endpunkt und meldet den Upstream-HTTP-Status sowie die verstrichene Zeit. Verwenden Sie sie, um Ihren Handler zu validieren, bevor Sie echten Traffic dorthin leiten.

Die Test-Payload nutzt genau dasselbe Body-Envelope, dieselben Header-Namen und dasselbe HMAC-Schema wie Produktionsereignisse — wenn Ihre Verifizierung für webhook.test besteht, besteht sie auch für message.created und alles andere.

§ 07Wiederholungen & Zeitüberschreitungen

Wir geben Ihrem Server 10 Sekunden zum Antworten. Jeder Nicht-2xx-Status oder Netzwerkfehler ist ein Fehlschlag. Fehlgeschlagene Zustellungen werden bis zu 5-mal mit exponentiellem Backoff ab 2 Sekunden wiederholt, sodass ein unzuverlässiger Endpunkt mehrere Chancen bekommt, bevor wir das Ereignis aufgeben.

Wir garantieren KEINE Exactly-Once-Zustellung — bei Netzwerk-Flapping kann dasselbe Ereignis zweimal eintreffen. Machen Sie Ihren Handler idempotent: dedupliziere anhand der inneren data.message.id (oder welche ID auch immer für dieses Ereignis sinnvoll ist).

§ 08Sicherheits-Checkliste

  • Verwenden Sie immer https:// — reine http://-Endpunkte werden bei der Erstellung abgelehnt.
  • Wir blockieren private, Loopback- und Cloud-Metadaten-IPs sowohl bei der Erstellung als auch bei der Zustellung, sodass ein falsch konfigurierter DNS-Eintrag nicht zum Pivoten in Ihr Netzwerk verwendet werden kann.
  • Vergleichen Sie Signaturen mit einem zeitsicheren Gleichheit (Node crypto.timingSafeEqual, Python hmac.compare_digest, Go hmac.Equal).
  • Rotieren Sie, indem Sie den Endpunkt löschen und einen neuen mit derselben URL erstellen. Aktualisieren Sie Ihren Secret-Store atomar.