Aller au contenu

Bonnes pratiques pour les webhooks

Vérifiez la signature, mettez l’événement en file (ligne en base, file d’attente, tâche en arrière-plan) et renvoyez 2xx immédiatement. SpacePost attend 15 secondes au maximum, et un gestionnaire lent se traduit par des nouvelles tentatives et des doublons.

La distribution se fait au moins une fois. Stockez le webhook-id de chaque distribution traitée (une contrainte d’unicité suffit) et ignorez les répétitions.

const inserted = await db.insert(processedWebhooks).values({ id: webhookId }).onConflictDoNothing().returning();
if (inserted.length === 0) return new Response("duplicate", { status: 200 });

Utilisez le corps brut, rejetez les horodatages vieux de plus de 5 minutes, comparez les signatures en temps constant (le SDK et les bibliothèques le font). Voir Vérifier les signatures.

Les événements peuvent arriver dans le désordre, surtout après des nouvelles tentatives. Comparez le created_at du payload avec ce que vous avez stocké, et n’appliquez que les changements qui font avancer l’état. Le last_event de SpacePost suit la même règle.

Événement Action typique
email.bounced Marquez l’adresse comme invalide dans votre base ; cessez d’y envoyer.
email.complained Désabonnez immédiatement l’utilisateur des e-mails non essentiels.
email.delivery_delayed En général rien ; alertez s’il s’agit d’un e-mail urgent (réinitialisation de mot de passe).
email.failed Journalisez data.failed.reason, alertez, réessayez éventuellement après correction.
email.suppressed Un destinataire figurait dans votre liste de suppression ; affichez-le dans votre interface d’administration.

Abonnez-vous uniquement aux événements que vous traitez. Moins d’événements, c’est moins de trafic et moins d’échecs.

  • Servez-le en HTTPS avec un certificat valide.
  • Ne journalisez pas les secrets ni les payloads complets contenant des données personnelles.
  • Utilisez un chemin dédié sans autre comportement et renvoyez un corps générique.
  • Conservez le signing_secret dans un gestionnaire de secrets, pas dans le contrôle de version.

Surveillez le journal des distributions du tableau de bord ou alertez sur les échecs répétés : si votre endpoint est indisponible pendant plus de 27 heures environ, toutes les nouvelles tentatives sont épuisées, et vous devrez alors rejouer manuellement.