Aperçu
Recevez les événements TicketWave sous forme de requêtes HTTP signées dans votre propre application.
Webhooks
Un webhook est une requête HTTP que TicketWave vous envoie. Chaque fois qu’il se passe quelque chose sur votre serveur — un ticket s’ouvre, un membre est mis sur liste noire — TicketWave envoie un POST avec un corps JSON vers une URL qui vous appartient.
C’est la différence avec les Log Channels : les log channels écrivent un embed dans Discord pour que des humains le lisent, tandis que les webhooks transmettent l’événement brut à votre code.
Les webhooks sont une fonctionnalité premium. Sans premium, il est impossible de créer des endpoints et aucun événement n’est livré.
Créer un endpoint
Ouvrir la page des endpoints
Tableau de bord du serveur → Webhooks → Endpoints.
Ajouter un endpoint
Cliquez sur Add Endpoint et remplissez deux champs :
| Field | Description |
|---|---|
| Endpoint URL | L’URL https:// qui reçoit les requêtes |
| Event Types | Les événements que cet endpoint doit recevoir |
Un endpoint ne reçoit que les types que vous cochez. Il n’est pas possible d’en sélectionner aucun — choisissez-en au moins un.
Copier le secret de signature
TicketWave génère un secret de signature (whsec_…) dès que l’endpoint est créé. Ouvrez la liste des endpoints, affichez-le avec l’icône en forme d’œil, puis copiez-le dans la configuration de votre application.
Traitez ce secret comme un mot de passe. Toute personne qui le possède peut forger des requêtes qui passent votre vérification de signature. Conservez-le dans une variable d’environnement, jamais dans votre dépôt.
Envoyer un événement de test
Utilisez le bouton Send test event (l’avion en papier) sur la ligne de l’endpoint. Il envoie une vraie requête, entièrement signée, avec "test": true dans la charge utile, afin que vous puissiez vérifier que votre récepteur fonctionne avant qu’un vrai ticket en dépende.
Le résultat apparaît dans l’historique Webhooks comme n’importe quelle autre livraison.
Exigences de l’endpoint
| Requirement | Detail |
|---|---|
| Scheme | https:// uniquement — http:// est refusé |
| Host | Doit être résolvable publiquement. Les adresses privées, loopback, link-local et CGNAT sont refusées |
| Response | Tout statut 2xx est considéré comme un succès |
| Timeout | Vous avez 10 secondes pour répondre |
| Redirects | Non suivies. Un 3xx est considéré comme un échec |
| Limit | Jusqu’à 5 endpoints par serveur |
La vérification de l’hôte a lieu à la fois lorsque vous enregistrez l’endpoint et avant chaque livraison, donc un domaine qui commence plus tard à résoudre vers une adresse interne cesse de recevoir des livraisons.
La requête
Chaque livraison est un POST avec un corps JSON.
En-têtes
| Header | Example | Meaning |
|---|---|---|
Content-Type | application/json | Toujours du JSON |
User-Agent | TicketWave-Webhooks/1.0.5 | La version du bot qui l’a envoyée |
X-TicketWave-Event | ticket.created | Le type d’événement |
X-TicketWave-Delivery | wh_3f2a… | Identifiant unique de cette livraison |
X-TicketWave-Timestamp | 1786224191 | Secondes Unix, partie de la signature |
X-TicketWave-Signature | sha256=9f86d0… | HMAC de la requête |
Corps
Chaque charge utile utilise la même enveloppe. Seul data change selon le type d’événement :
{
"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"
}
}Consultez la Event Reference pour l’objet data de chaque type.
Vérifier la signature
Toute personne qui découvre l’URL de votre endpoint peut lui envoyer une requête POST. La signature vous permet de distinguer une vraie livraison TicketWave d’une requête falsifiée.
Vérifiez toujours. Un endpoint non vérifié qui crée ou ferme des éléments dans votre système est une porte ouverte.
Comment la signature est construite
TicketWave concatène l’horodatage et le corps brut de la requête avec un point, puis exécute HMAC-SHA256 sur le résultat à l’aide du secret de votre endpoint :
signed_payload = X-TicketWave-Timestamp + "." + raw_request_body
signature = HMAC_SHA256(signed_payload, your_endpoint_secret)L’en-tête contient ce condensat encodé en hexadécimal et préfixé : sha256=<digest>.
Ce que votre récepteur doit faire
Lire le corps brut. Vérifiez les octets exacts que vous avez reçus. Si votre framework analyse d’abord le JSON et que vous le re-sérialisez, l’ordre des clés ou les espaces peuvent changer et le condensat ne correspondra plus.
Recalculer le HMAC sur timestamp + "." + rawBody avec votre secret.
Comparer en temps constant (crypto.timingSafeEqual dans Node). Un simple === fuit des informations de timing.
Vérifier que l’horodatage est récent — une tolérance de cinq minutes est un bon défaut. L’horodatage fait partie de la charge utile signée, donc un attaquant ne peut pas rejouer une ancienne requête avec un horodatage récent.
Une implémentation complète se trouve sur la page Example Server.
Tentatives de reprise
Une livraison qui échoue est automatiquement retentée.
| Attempts | 3 (la première tentative plus 2 reprises) |
| Backoff | 1 seconde, puis 5 secondes |
| Retried on | Erreurs réseau, timeouts, 408, 429 et tout 5xx |
| Not retried on | Tous les autres 4xx — cela signifie que votre endpoint a rejeté la requête volontairement |
À cause des reprises, votre endpoint peut recevoir deux fois le même événement. Utilisez X-TicketWave-Delivery comme clé d’idempotence : mémorisez les identifiants déjà traités et ignorez les doublons.
Les livraisons ne sont pas ordonnées. Si deux tickets sont créés au même moment, les requêtes peuvent arriver dans n’importe quel ordre — utilisez le champ timestamp dans le corps si l’ordre est important pour vous.
Historique des livraisons
La page Webhooks du tableau de bord liste chaque livraison avec son statut, son code de réponse, sa durée et son nombre de tentatives. Ouvrez une ligne pour voir la charge utile exacte envoyée et la réponse renvoyée par votre serveur.
Les livraisons échouées peuvent être renvoyées depuis la page de détail avec Retry Webhook. Cela renvoie à nouveau la charge utile d’origine vers le même endpoint et enregistre une nouvelle livraison.
L’historique est conservé pendant 30 jours, puis nettoyé automatiquement.
Dépannage
| Problem | Fix |
|---|---|
| L’endpoint ne peut pas être enregistré | L’URL doit être en https:// et résoudre vers une adresse publique |
| Tout apparaît comme échoué sans code de réponse | La requête ne vous est jamais parvenue — timeout, échec DNS ou connexion refusée |
| La signature ne correspond jamais | Vous hachez le corps analysé au lieu des octets bruts, ou vous avez oublié le préfixe timestamp + "." |
| Les livraisons s’arrêtent au bout d’un moment | Vérifiez si votre hôte a commencé à renvoyer des 4xx — ceux-ci ne sont pas retentés |
| Un événement n’arrive jamais | L’endpoint n’est pas abonné à ce type, ou le serveur a perdu le premium |
| Événements en double | Attendu lors des reprises — dédupliquez sur X-TicketWave-Delivery |
Prochaines étapes
- Event Reference (Chaque événement et sa charge utile)
- Example Server (Un récepteur Express exécutable)
- Log Channels (Les mêmes événements, mais publiés dans Discord)
How is this guide?
