[BUG] Chatwoot integration duplicates messages when a device re-delivers the same key.id — getExistingSourceIds exists but is never called on the live path
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 76/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Tranquilla
- Stack tecnologico
- postgresql, typescript
Direzione di ricerca
Inizia leggendo ChatwootService.createMessage e confronta il suo percorso live con ChatwootImport.getExistingSourceIds e importHistoryMessages. Segui come vengono passati source_id e conversationId, quindi verifica che gli arrivi ripetuti di WAID:<key.id> vengano ignorati, mentre gli errori di ricerca consentano comunque alla consegna di continuare. Conferma che i chiamanti esistenti gestiscano il risultato null come descritto.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
📋 Bug Description
When a sender's device re-delivers the same WhatsApp message (identical key.id, new timestamp — e.g. a buggy device or an unofficial client stuck in a loop resending an auto-reply), the Chatwoot integration creates a new Chatwoot message on every arrival. There is no idempotency check on the live path.
Real-world impact (production, v2.3.7): one guest's device looped an away-message roughly once a minute. In ~25h we accumulated 837 copies of a single message in one Chatwoot conversation (and a second looping key.id later reached 539 copies). The conversation became unusable for the support team. WhatsApp mobile shows the message once (native dedup by key.id); Chatwoot shows every copy.
The interesting part: the codebase already contains exactly the right check — ChatwootImport.getExistingSourceIds(sourceIds, conversationId) queries Chatwoot's messages.source_id for WAID:<key.id> — but it is only called from the history import path (importHistoryMessages). The live path (ChatwootService.createMessage) posts to Chatwoot with source_id: WAID:<key.id> without consulting anything.
🔄 Steps to Reproduce
- Evolution API v2.3.7 (baileys channel) + Chatwoot integration enabled.
- From a sender device, deliver the same message twice with the same
key.id(a looping unofficial client does this naturally; the events arrive withstatus: DELIVERY_ACK,source: 'unknown'and a freshmessageTimestampeach time). - Watch the Chatwoot conversation.
✅ Expected Behavior
Second and subsequent arrivals of an already-imported key.id for the same conversation should be ignored (the same way importHistoryMessages already filters via getExistingSourceIds), or at least be configurable to be ignored.
❌ Actual Behavior
Every arrival creates a new Chatwoot message with the same source_id (WAID:<key.id>). messages.source_id in Chatwoot has a non-unique index, so nothing stops the duplicates downstream either.
💡 Suggested Fix
Call the existing check in the live path. We are running this in production (patched into createMessage) and it fully stopped the flood without affecting legitimate traffic:
// at the top of ChatwootService.createMessage(...), sourceId = "WAID:" + key.id
if (sourceId) {
try {
const existing = await chatwootImport.getExistingSourceIds([sourceId], conversationId);
if (existing.has(sourceId)) {
this.logger.warn(`[dedup] repeated message ignored source_id=${sourceId} conversation_id=${conversationId}`);
return null; // callers already handle the null ("message not sent") path
}
} catch (e) {
this.logger.warn(`[dedup] check unavailable: ${e}`); // fail open
}
}
Notes:
getExistingSourceIdsalready accepts the optionalconversationIdargument, so the lookup is cheap (indexed onsource_id).- Failing open on lookup errors keeps message delivery safe if the Chatwoot DB connection blips.
- Verified in production: 14 duplicate arrivals blocked in the first minutes across 2 looping
key.ids, zero legitimate messages affected.
🌍 Environment
- Evolution API: v2.3.7 (image
evoapicloud/evolution-api:v2.3.7) - Connection type: baileys
- Chatwoot: v4.16.1, integration via
CHATWOOT_ENABLED=true - DB: PostgreSQL (shared instance for Evolution + Chatwoot import connection)
- OS: Linux (Docker)
- Lingua principale
- TypeScript
- Stelle
- 9.6k
- Fork
- 7.3k
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di evolution-foundation/evolution-api
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 88/100
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
evolution-foundation/evolution-api#2700 · 1 commento ·
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 76/100
Tutte le issue di evolution-foundation/evolution-api
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
copse-dev/agent-pane#2953 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
[Bug]: Matrix progress drafts fail with "Matrix runtime not initialized" during tool activity Apertabug clawsweeper:linked-pr-open clawsweeper:needs-live-repro clawsweeper:no-new-fix-pr impact:message-loss issue-rating: 🐚 platinum hermit P2 regression
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
-
calcite-components needs triage refactor
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
Esri/calcite-design-system#15203 ·