Übersicht
Empfange TicketWave-Events als signierte HTTP-Anfragen in Deiner eigenen Anwendung.
Webhooks
Ein Webhook ist eine HTTP-Anfrage, die TicketWave an Dich sendet. Immer wenn in Deinem Server etwas passiert — ein Ticket geöffnet wird, ein Mitglied auf die Blacklist gesetzt wird — sendet TicketWave per POST einen JSON-Body an eine URL, die Dir gehört.
Das ist der Unterschied zu Log Channels: Log Channels schreiben ein Embed in Discord, damit Menschen es lesen können, Webhooks geben das rohe Event direkt an Deinen Code weiter.
Webhooks sind ein Premium-Feature. Ohne Premium können keine Endpunkte erstellt werden und es werden keine Events zugestellt.
Einen Endpunkt erstellen
Die Endpunkt-Seite öffnen
Server-Dashboard → Webhooks → Endpoints.
Einen Endpunkt hinzufügen
Klicke auf Add Endpoint und fülle zwei Felder aus:
| Feld | Beschreibung |
|---|---|
| Endpoint URL | Die https://-URL, die die Anfragen empfängt |
| Event Types | Welche Events dieser Endpunkt empfangen soll |
Ein Endpunkt empfängt nur die Typen, die Du auswählst. Nichts auszuwählen ist nicht erlaubt — wähle mindestens einen aus.
Das Signatur-Secret kopieren
TicketWave erzeugt in dem Moment, in dem der Endpunkt erstellt wird, ein Signatur-Secret (whsec_…). Öffne die Endpunktliste, blende es mit dem Augen-Symbol ein und kopiere es in die Konfiguration Deiner Anwendung.
Behandle das Secret wie ein Passwort. Wer es hat, kann Anfragen fälschen, die Deine Signaturprüfung bestehen. Bewahre es in einer Umgebungsvariable auf, niemals in Deinem Repository.
Ein Test-Event senden
Nutze den Button Send test event (das Papierflugzeug) in der Endpunktzeile. Er liefert eine echte, vollständig signierte Anfrage mit "test": true im Payload, damit Du prüfen kannst, ob Dein Empfänger funktioniert, bevor ein echtes Ticket davon abhängt.
Das Ergebnis erscheint im Webhooks-Verlauf wie jede andere Zustellung auch.
Anforderungen an den Endpunkt
| Anforderung | Detail |
|---|---|
| Scheme | Nur https:// — http:// wird abgelehnt |
| Host | Muss öffentlich auflösbar sein. Private, Loopback-, Link-Local- und CGNAT-Adressen werden abgelehnt |
| Response | Jeder 2xx-Status zählt als Erfolg |
| Timeout | Du hast 10 Sekunden zum Antworten |
| Redirects | Werden nicht verfolgt. Ein 3xx zählt als Fehler |
| Limit | Bis zu 5 Endpunkte pro Server |
Die Host-Prüfung passiert sowohl beim Speichern des Endpunkts als auch vor jeder einzelnen Zustellung, sodass eine Domain, die später auf eine interne Adresse auflöst, nicht mehr zugestellt wird.
Die Anfrage
Jede Zustellung ist ein POST mit einem JSON-Body.
Header
| Header | Beispiel | Bedeutung |
|---|---|---|
Content-Type | application/json | Immer JSON |
User-Agent | TicketWave-Webhooks/1.0.5 | Die Bot-Version, die sie gesendet hat |
X-TicketWave-Event | ticket.created | Der Event-Typ |
X-TicketWave-Delivery | wh_3f2a… | Eindeutige ID für diese Zustellung |
X-TicketWave-Timestamp | 1786224191 | Unix-Sekunden, Teil der Signatur |
X-TicketWave-Signature | sha256=9f86d0… | HMAC der Anfrage |
Body
Jeder Payload verwendet denselben Envelope. Nur data unterscheidet sich je nach Event-Typ:
{
"event": "ticket.created",
"timestamp": "2026-08-26T08:23:11.000Z",
"guild_id": "123456789012345678",
"data": {
"ticket_id": "ticket-1042",
"ticket_num_id": 1042,
"channel_id": "998877665544332211",
"category": "🤖 Support",
"user": { "id": "987654321098765432", "username": "Luna" },
"created_at": "2026-08-26T08:23:11.000Z"
}
}Sieh Dir die Event Reference für das data-Objekt jedes Typs an.
Die Signatur verifizieren
Wer Deine Endpunkt-URL herausfindet, kann eine POST-Anfrage dorthin senden. Die Signatur ist der Weg, mit dem Du eine echte TicketWave-Zustellung von einer gefälschten unterscheidest.
Immer verifizieren. Ein nicht verifizierter Endpunkt, der in Deinem System Dinge erstellt oder schließt, ist eine offene Tür.
Wie die Signatur aufgebaut wird
TicketWave verbindet den Timestamp und den rohen Request-Body mit einem Punkt und führt darauf HMAC-SHA256 mit Deinem Endpunkt-Secret aus:
signed_payload = X-TicketWave-Timestamp + "." + raw_request_body
signature = HMAC_SHA256(signed_payload, your_endpoint_secret)Der Header enthält diesen Digest hex-kodiert und mit Präfix: sha256=<digest>.
Was Dein Empfänger tun muss
Lies den rohen Body. Verifiziere gegen die exakten Bytes, die Du erhalten hast. Wenn Dein Framework zuerst JSON parst und Du es danach erneut serialisierst, können sich Reihenfolge der Keys oder Leerzeichen ändern und der Digest stimmt nicht mehr.
Berechne das HMAC neu über timestamp + "." + rawBody mit Deinem Secret.
Vergleiche in konstanter Zeit (crypto.timingSafeEqual in Node). Ein einfaches === verrät Timing-Informationen.
Prüfe, ob der Timestamp aktuell ist — fünf Minuten Toleranz sind ein guter Standard. Der Timestamp steckt im signierten Payload, also kann ein Angreifer keine alte Anfrage mit einem frischen Timestamp erneut senden.
Eine vollständige Implementierung findest Du auf der Seite Example Server.
Retries
Eine fehlgeschlagene Zustellung wird automatisch erneut versucht.
| Attempts | 3 (der erste Versuch plus 2 Retries) |
| Backoff | 1 Sekunde, dann 5 Sekunden |
| Retried on | Netzwerkfehler, Timeouts, 408, 429 und alle 5xx |
| Not retried on | Alle anderen 4xx — das bedeutet, dass Dein Endpunkt die Anfrage absichtlich abgelehnt hat |
Durch Retries kann Dein Endpunkt dasselbe Event zweimal erhalten. Verwende X-TicketWave-Delivery als Idempotency-Key: Merke Dir die IDs, die Du bereits verarbeitet hast, und ignoriere Wiederholungen.
Zustellungen sind nicht sortiert. Wenn zwei Tickets im selben Moment erstellt werden, können die Anfragen in beliebiger Reihenfolge ankommen — verwende das timestamp-Feld im Body, wenn Dir die Reihenfolge wichtig ist.
Zustellungsverlauf
Auf der Webhooks-Seite im Dashboard werden alle Zustellungen mit Status, Response-Code, Dauer und Anzahl der Versuche aufgelistet. Öffne eine Zeile, um den genauen Request-Payload zu sehen, der gesendet wurde, und die Antwort, die Dein Server zurückgegeben hat.
Fehlgeschlagene Zustellungen können auf der Detailseite mit Retry Webhook erneut gesendet werden. Dabei wird derselbe ursprüngliche Payload noch einmal an denselben Endpunkt gesendet und als neue Zustellung protokolliert.
Der Verlauf wird 30 Tage lang aufbewahrt und danach automatisch bereinigt.
Fehlerbehebung
| Problem | Lösung |
|---|---|
| Der Endpunkt kann nicht gespeichert werden | Die URL muss https:// verwenden und auf eine öffentliche Adresse auflösen |
| Alles wird als fehlgeschlagen angezeigt, ohne Response-Code | Die Anfrage hat Dich nie erreicht — Timeout, DNS-Fehler oder Verbindung abgelehnt |
| Die Signatur stimmt nie | Du hashst den geparsten Body statt der rohen Bytes oder hast das Präfix timestamp + "." vergessen |
| Zustellungen hören nach einer Weile auf | Prüfe, ob Dein Host angefangen hat, 4xx zurückzugeben — diese werden nicht erneut versucht |
| Ein Event kommt nie an | Der Endpunkt ist für diesen Typ nicht abonniert oder der Server hat Premium verloren |
| Doppelte Events | Bei Retries erwartet — dedupliziere anhand von X-TicketWave-Delivery |
Nächste Schritte
- Event Reference (Jedes Event und sein Payload)
- Example Server (Ein lauffähiger Express-Empfänger)
- Log Channels (Dieselben Events, aber in Discord gepostet)
How is this guide?
