Le webhook
Plutôt que d’interroger GET /api/message/{messageId} en boucle, laissez Assilya pousser le résultat vers votre serveur : dès qu’un message atteint un état stable, votre URL reçoit un POST signé contenant exactement la même enveloppe JSON que le polling — un seul parseur suffit.
Activer le webhook
Section intitulée « Activer le webhook »Dans les paramètres de l’agent API, section « Webhook » :
- Activez l’interrupteur — un secret de signature (préfixe
whsec_) est généré automatiquement ; copiez-le dans la configuration de votre serveur. - Renseignez votre URL de rappel. Elle doit être en HTTPS — c’est une exigence stricte : sans URL
https://, aucun envoi n’a lieu. - Le bouton « Régénérer » du secret invalide l’ancien immédiatement — mettez votre serveur à jour d’abord.
Les événements
Section intitulée « Les événements »X-Assilya-Event | Déclencheur |
|---|---|
message.answered | Une réponse a été envoyée — automatiquement ou publiée par un humain (boîte de réception ou POST …/answer). |
message.pending | L’IA passe la main (confiance sous le seuil, ou action à effectuer par un humain) : des suggestions attendent une validation humaine. |
message.failed | Le traitement a échoué (error dans le corps). |
Le corps est l’enveloppe décrite dans Le cycle de vie d’un message ; l’événement reprend simplement son champ state.
Les en-têtes reçus
Section intitulée « Les en-têtes reçus »| En-tête | Contenu |
|---|---|
X-Assilya-Event | message.answered, message.pending ou message.failed. |
X-Assilya-Message | L’identifiant du message entrant concerné (le champ id du corps). |
X-Assilya-Timestamp | Horodatage Unix (secondes) — entre dans la signature. |
X-Assilya-Signature | sha256=<hmac> (voir ci-dessous). |
User-Agent | Assilya-Webhook/1.0 |
Content-Type | application/json |
Vérifier la signature
Section intitulée « Vérifier la signature »La signature est un HMAC-SHA256 du texte timestamp.corps (l’horodatage, un point, puis le corps brut de la requête), calculé avec votre secret whsec_ :
signature = HMAC_SHA256(timestamp + "." + corps_brut, webhook_secret)Deux impératifs : recalculez-la depuis le corps brut (avant tout décodage JSON — un ré-encodage changerait les octets), et comparez en temps constant.
En PHP :
$corps = file_get_contents('php://input');$timestamp = $_SERVER['HTTP_X_ASSILYA_TIMESTAMP'] ?? '';$signature = $_SERVER['HTTP_X_ASSILYA_SIGNATURE'] ?? '';
$attendue = 'sha256='.hash_hmac('sha256', $timestamp.'.'.$corps, $webhookSecret);
if (! hash_equals($attendue, $signature)) { http_response_code(401); exit;}En Node.js (Express) :
import crypto from 'node:crypto';
app.post('/webhooks/assilya', express.raw({ type: 'application/json' }), (req, res) => { const timestamp = req.header('X-Assilya-Timestamp') ?? ''; const signature = req.header('X-Assilya-Signature') ?? '';
const attendue = 'sha256=' + crypto .createHmac('sha256', process.env.ASSILYA_WEBHOOK_SECRET) .update(timestamp + '.' + req.body) .digest('hex');
const valide = signature.length === attendue.length && crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(attendue));
if (!valide) return res.status(401).end();
res.status(200).end(); // Traitez ensuite le contenu (déjà persisté) de façon asynchrone.});Refusez aussi les horodatages trop anciens (quelques minutes) pour bloquer le rejeu d’une requête capturée.
Livraison et relances
Section intitulée « Livraison et relances »- La première tentative part immédiatement ; votre serveur dispose de 30 secondes pour répondre.
- Toute réponse
2xxvaut accusé de réception et stoppe les relances. - En cas d’échec (non-2xx ou délai dépassé), l’envoi est retenté à +60 s, +5 min puis +15 min — 4 tentatives en tout.
- Après le quatrième échec, la livraison est abandonnée : prévoyez le repli par polling pour ne rien perdre.
Bonnes pratiques de réception
Section intitulée « Bonnes pratiques de réception »- Accusez réception vite : persistez le payload, répondez
2xx, traitez ensuite. Un traitement lourd dans le handler vous expose au délai de 30 s — et donc à des relances en doublon. - Soyez idempotent : une même notification peut arriver plusieurs fois (relances) ; le champ
idest stable et sert de clé de déduplication. - N’exposez jamais le secret : pas dans les logs, pas côté client.
- Un
message.pendingpeut être suivi d’unmessage.answeredpour le même message une fois la réponse validée — traitez les événements comme des transitions d’état, pas comme des doublons.
