Aller au contenu

Webhooks

RolChat transmet les événements à vos systèmes sous forme de requêtes HTTP POST signées. Cette page décrit les webhooks de plugin ; les webhooks envoyés par une règle d’Automatisation diffèrent par les nouvelles tentatives, le délai d’attente et la rotation du secret, voir Webhooks d’automatisation. Les mêmes règles s’appliquent dans l’autre sens, lorsque votre système, un plugin ou un fournisseur envoie des données à RolChat. Vérifiez chaque envoi dans l’ordre ci-dessous avant d’agir.

POST /your/endpoint HTTP/1.1
Content-Type: application/json
User-Agent: RolChat-Webhook/1.0
X-RolChat-Timestamp: 1713615825
X-RolChat-Signature: sha256=a1b2c3…
X-RolChat-Nonce: nonce_01HKQN9…
X-RolChat-Event-Id: evt_01HKQN9…
{ "id": "evt_01HKQN9…", "type": "conversation.created", "occurred_at": "…", "data": { … } }
En-tête Signification
X-RolChat-Timestamp Secondes Unix au moment de l’envoi. Fait partie du message signé.
X-RolChat-Signature sha256=<hex>. Le préfixe indique l’algorithme afin qu’il puisse évoluer plus tard.
X-RolChat-Nonce Un ULID propre à cette requête HTTP. Une nouvelle tentative reçoit un nouveau nonce.
X-RolChat-Event-Id L’identifiant propre de l’événement. Identique d’une tentative à l’autre ; utilisez-le pour dédoublonner.

Les envois sortants ne visent que des endpoints HTTPS. Une URL HTTP est refusée lors de la création de l’abonnement.

Le message signé se compose de l’horodatage, d’un point littéral et du corps brut de la requête, octet par octet :

canonical = "<timestamp>.<body>"
signature = hex( HMAC-SHA256( secret, canonical ) )

Signez les octets reçus, pas une copie resérialisée du JSON analysé. Un changement d’espaces ou d’ordre des clés invalide la signature. SHA-256 est le seul algorithme accepté.

Effectuez ces cinq contrôles dans l’ordre. Des exemples en Python, Node.js, Go, Ruby et PHP figurent sur la page Exemples de vérification.

  1. Fraîcheur. Rejetez si |now − X-RolChat-Timestamp| > 300 secondes (400). Cinq minutes tolèrent le décalage d’horloge et rendent une requête interceptée inutilisable au-delà. Synchronisez votre serveur avec NTP.
  2. Signature. Calculez la valeur attendue et comparez-la avec une comparaison à temps constant (hmac.compare_digest, crypto.timingSafeEqual, hash_equals). Rejetez avec 401 en cas de non-correspondance. Une simple comparaison de chaînes laisse fuiter des informations de temps et n’est pas acceptable.
  3. Nonce. Stockez X-RolChat-Nonce avec une durée de vie de 10 minutes au moyen d’une écriture atomique conditionnelle (SET NX EX 600). S’il existe déjà, rejetez avec 409 : la requête est un rejeu. Si votre stockage de nonces est indisponible, échouez de manière sûre avec 503 pour que RolChat réessaie ; ne basculez jamais sur « accepter ».
  4. Analysez le corps seulement maintenant.
  5. Dédoublonnez par identifiant d’événement. Les nouvelles tentatives portent un nouveau nonce mais le même X-RolChat-Event-Id. Si vous avez traité cet identifiant au cours des sept derniers jours, répondez 200 sans le traiter de nouveau.

Répondez 2xx dès que l’envoi est accepté en toute sécurité ; effectuez le traitement de manière asynchrone. RolChat attend une réponse pendant 15 secondes.

  • Un secret de webhook se compose de 64 octets aléatoires encodés en base64url (environ 86 caractères). Il est généré lors de la création de l’abonnement ou du plugin et affiché une seule fois.
  • Conservez-le dans votre propre coffre-fort ou votre environnement ; RolChat n’en garde qu’une copie chiffrée.
  • Un renouvellement est recommandé après 90 jours ; le produit affiche un rappel mais ne désactive jamais un abonnement faute de renouvellement.
  • Le renouvellement utilise une période de chevauchement : après POST /api/v1/plugins/{id}/webhook-secret/rotate, l’ancien et le nouveau secret sont tous deux valides pendant sept jours, les nouveaux envois sont signés avec le nouveau, et l’ancien est supprimé à la fin de la période. Rien ne casse au moment du renouvellement.
  • Si un secret fuite, POST /api/v1/plugins/{id}/webhook-secret/revoke l’invalide immédiatement, en émet un nouveau, envoie un e-mail aux administrateurs du compte et crée une entrée d’audit.

Une réponse autre que 2xx ou un échec réseau programme une nouvelle tentative :

Tentative Délai après la précédente
1 immédiatement
2 15 secondes
3 1 minute
4 5 minutes
5 30 minutes
6 2 heures
7 8 heures
8 24 heures

Les réponses 408, 429, 5xx et les erreurs réseau donnent lieu à de nouvelles tentatives. Les réponses 400, 401, 403, 404 et 410, non : l’envoi part directement dans la file des lettres mortes, car réessayer une signature rejetée ou un endpoint inexistant ne sert à rien. Après huit tentatives infructueuses, l’envoi est lui aussi placé dans les lettres mortes.

Les lettres mortes sont conservées 30 jours et visibles dans Paramètres → Plugins → {plugin} → Journal des webhooks → DLQ, où un administrateur peut en rejouer une (POST /api/v1/plugins/{id}/webhook-dlq/{entry_id}/replay).

  • Corps sortant : 1 MB par défaut (configurable par plugin). Corps entrant vers RolChat : 5 MB. Au-delà, 413.
  • Un plugin peut déclarer allowed_source_ips ; RolChat applique cette liste d’IP autorisées avant la vérification.
  • Vous pouvez filtrer sur l’agent utilisateur RolChat-Webhook/1.0 comme contrôle de cohérence supplémentaire. Ce n’est pas un mécanisme de sécurité.

Les fournisseurs envoient leurs données à RolChat sur /api/v1/webhooks/{category}/{adapter} avec leurs propres schémas de signature (Twilio, Telnyx, Bandwidth, Meta pour WhatsApp, Stripe). Chaque adaptateur vérifie la signature de son fournisseur, normalise la charge utile et la republie sur le bus d’événements interne avec une signature RolChat. Votre propre système peut envoyer des données à RolChat avec les mêmes en-têtes X-RolChat-* décrits ci-dessus, signés avec le secret du plugin auquel appartient l’endpoint.

L’action Envoyer une requête HTTP du module Automatisation a ses propres règles d’envoi :

  • Un secret par compte. Affichez-le ou renouvelez-le sur l’écran Automatisation (Propriétaire et Admin). Le renouvellement prend effet immédiatement : il n’y a pas de période de chevauchement, l’ancien secret cesse aussitôt d’être valide ; mettez donc d’abord à jour votre récepteur ou acceptez une courte interruption.
  • Délai d’attente : RolChat attend 10 secondes une réponse.
  • Nouvelles tentatives : 6 tentatives au maximum au total. La pause avant la tentative 2 est de 30 secondes, puis d’environ 2 minutes, 8 minutes, 32 minutes et 2 heures 8 minutes, chacune variant jusqu’à 20 %. Une pause isolée ne dépasse jamais 6 heures.
  • Ce qui est retenté : erreurs réseau, délais dépassés, 5xx, 408, 425 et 429. Les autres réponses 4xx, une adresse bloquée ou un corps trop volumineux ne sont pas retentés : l’envoi va directement dans la file des échecs définitifs, comme après la dernière tentative échouée.
  • En-têtes : X-RolChat-Signature, X-RolChat-Signature-V2, X-RolChat-Timestamp, X-RolChat-Delivery-Id, X-RolChat-Attempt.

POST /api/v1/webhooks/test-signature envoie un événement signé fictif à l’endpoint du plugin appelant, pour que vous puissiez vérifier votre implémentation de bout en bout avant l’arrivée du trafic réel.

  • Vérifier à partir du JSON analysé puis réencodé au lieu des octets bruts.
  • Utiliser == pour comparer les signatures.
  • Dédoublonner par nonce (chaque nouvelle tentative en a un nouveau) au lieu de l’identifiant d’événement.
  • Une horloge décalée de plus de cinq minutes.
  • Effectuer un traitement lent avant de répondre, dépasser le délai de 15 secondes et recevoir de nouveau le même événement.