Garantir un traitement unique avec les Webhooks

Bonjour à tous, je fais face à un problème de fiabilité plus avancé dans n8n concernant les workflows déclenchés par webhook.

J’ai un workflow :
Webhook → Traitement → Base de données

Le service externe réessaie parfois le même événement webhook (par exemple, en cas de timeout), donc n8n reçoit des requêtes en doublon avec le même payload.
En ce moment, cela provoque :
• Des enregistrements en doublon dans la base de données
• Des actions en doublon en aval (e-mails, appels API, etc.)

Payload d’exemple :
{
“event_id”: “abc123”,
“user_id”: 42,
“action”: “created”
}

Si le même event_id est envoyé deux fois, il est traité deux fois.

Ce que j’ai essayé
• Des vérifications basiques dans un nœud Function
• Des upserts en base de données
• L’ajout de délais

Mais aucune de ces approches ne garantit pleinement un traitement exactement une fois.

Le défi

Je veux m’assurer que :
• Chaque événement est traité une seule fois
• Une gestion sûre des retries
• Aucun effet secondaire en doublon

Décrivez le problème/l’erreur/la question

Quel est le message d’erreur (le cas échéant) ?

Veuillez partager votre workflow

(Sélectionnez les nœuds sur votre canvas et utilisez les raccourcis clavier CMD+C/CTRL+C et CMD+V/CTRL+V pour copier et coller le workflow.)

Partagez la sortie renvoyée par le dernier nœud

Informations sur votre configuration n8n

  • Version d’n8n :
  • Base de données (par défaut : SQLite) :
  • Paramètre n8n EXECUTIONS_PROCESS (par défaut : own, main) :
  • Exécution d’n8n via (Docker, npm, n8n cloud, application de bureau) :
  • Système d’exploitation :

Salut @Keira_Becky Tu fais face à un problème d’idempotence, et la seule solution fiable est de suivre les événements traités - il n’y a pas de “exactly-once” intégré dans n8n.

Utilise l’event_id comme clé unique et laisse ta base de données l’enforcer.

Essaie ceci :

  1. Stocke event_id dans la DB avec une contrainte UNIQUE

CREATE TABLE events (
event_id TEXT PRIMARY KEY,
payload JSONB
);

  1. Insère avant le traitement

INSERT INTO events (event_id, payload)
VALUES ({{$json.event_id}}, {{$json}})
ON CONFLICT (event_id) DO NOTHING;

Donc si l’insertion réussit → traite l’événement
Si elle entre en conflit → saute (déjà traité)

Merci @Niffzy

J’ai résolu le problème en insérant avant le traitement