Prévenir un autre système
Un événement se produit chez vous et un autre logiciel doit le savoir : une facture est payée, un emprunt est en retard. Vous n’écrivez ni la boucle d’envoi, ni la signature, ni les réessais.
Un abonnement
from kewos.webhooks import register_subscription
register_subscription( engine, url="https://exemple.test/hook", events=("loan.overdue",), # () = tous les événements secret=secret, # partagé avec le receveur)Puis, quand ça arrive :
dispatcher.dispatch_event(event_name="loan.overdue", payload={"loan_id": 19, "days_late": 3})Le noyau parcourt les abonnements actifs dont la liste d’événements correspond, signe le corps avec le secret de chacun, et poste.
Ce qui arrive chez le receveur
Exécuté contre un vrai serveur HTTP :
POST /hook{"event":"loan.overdue","payload":{"days_late":3,"loan_id":19}}
X-Kewos-Event: loan.overdueX-Kewos-Signature: fde0817d51fd55e21c613193...X-Kewos-Delivery-Id: 9e01348d23e44f27b6b12f38...-
X-Kewos-Eventévite au receveur d’ouvrir le corps pour router. -
X-Kewos-Signatureest un HMAC SHA-256 du corps, sous le secret de l’abonnement. Le receveur le recalcule et compare :from kewos.webhooks import verify_signatureverify_signature(corps, signature=signature, secret=secret) # Trueverify_signature(corps, signature=signature, secret="autre") # FalseLa comparaison est à temps constant. Le noyau n’a qu’une implémentation HMAC, utilisée pour signer et pour vérifier : un désaccord entre les deux côtés est impossible.
-
X-Kewos-Delivery-Idest frappé une fois par envoi et partagé par tous les receveurs du même événement. Il sert deux fois : corréler un éventail d’envois côté exploitation, et dédupliquer un réessai côté receveur (même identifiant = même tentative).
Ce qui se passe quand ça rate
Le receveur est en panne, lent, ou répond 500. Trois mécanismes, aucun à écrire :
- Une ligne par tentative dans
kws_webhook_delivery: statut, nombre d’essais, prochaine date de réessai. Un envoi n’est jamais un événement perdu dans un journal. - Un rattrapage espacé : 1 min, 5 min, 30 min, 2 h, 12 h, 24 h. Un service qui redémarre récupère son événement ; un service mort ne noie pas le vôtre sous les tentatives.
- Une désactivation automatique au-delà du seuil d’échecs, avec un événement émis pour que l’application prévienne l’administrateur du tenant. Un abonnement mort qu’on continue d’appeler indéfiniment est une fuite de ressources, et un silence.
Et un rejeu : renvoyer une livraison enregistrée, resignée à la volée, depuis l’interface. C’est la réponse à « je n’ai rien reçu » qui ne demande pas de rejouer l’opération métier.