feat(chatwoot-adapter): retry failed inbound relays instead of dropping them (#609)#30
Merged
Merged
Conversation
…ng them (#609) Inbound relay was at-most-once: a failed Chatwoot POST was logged and the message dropped. When Chatwoot is transiently unreachable this silently loses customer messages. Make inbound at-least-once via a durable, storage-backed retry queue drained on a timer. - inbound.ts: on a relay failure, enqueue the message (media over a size cap is stripped so an oversized value can't be rejected and lose the message) rather than only logging. markSeen stays before the relay (dedups WA re-deliveries + makes backfill skip the live message); the pending-queue entry is the not-yet-relayed signal. - retry.ts: drainRetries re-posts each queued message under its per-chat lock, streaming one entry at a time so a large media backlog is never fully resident in memory; a message that keeps failing is dead-lettered after 5 attempts. - mapping-store.ts: retry-queue persistence (individual retry:* keys, one file each; count/list-keys without loading blobs; overflow drops the oldest, set-before-delete). - index.ts: 30s .unref() drain timer with a single-flight guard, cleared on disable/unload and skipped while config is invalid; healthCheck surfaces the pending backlog + dead-letters and reads unhealthy when the queue saturates. At-least-once means a message that reached Chatwoot but whose response was lost may rarely re-post as a duplicate; posts carry source_id as a dedup handle. chatwoot-adapter 0.5.0; no core change (minOpenWAVersion stays 0.8.7).
4094673 to
9f3a31c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes inbound WhatsApp → Chatwoot relay resilient to transient Chatwoot outages. A failed relay was previously logged and dropped (at-most-once); it is now retried from a durable, storage-backed queue until it succeeds or is dead-lettered (#609).
Problem
When the Chatwoot API is briefly unreachable — a deploy, a restart, a network blip — inbound customer messages were silently lost: the failed POST was logged and the message discarded.
Changes
ctx.storagequeue instead of being dropped, and re-posted on a 30-second timer until it succeeds. A message that keeps failing is dead-lettered after 5 attempts..unref()'d and cleared on disable/unload.markSeenstays before the relay — it dedups WhatsApp re-deliveries and lets history backfill skip the live message; the pending-queue entry is the "not yet relayed" signal, independent of that marker.Trade-off
At-least-once means a message that actually reached Chatwoot but whose response was lost may, on rare occasions, re-post as a duplicate. Posts carry
source_id(the WhatsApp message id) as a dedup handle.Compatibility
Version
0.5.0. No core change (minOpenWAVersionstays 0.8.7). Existing behavior is unchanged for outbound replies, own-send relay, and handover.