fix(engine): return the real id for forwarded messages on whatsapp-web.js so delivery status advances#341
Closed
rmyndharis wants to merge 1 commit into
Closed
fix(engine): return the real id for forwarded messages on whatsapp-web.js so delivery status advances#341rmyndharis wants to merge 1 commit into
rmyndharis wants to merge 1 commit into
Conversation
…b.js so delivery status advances The whatsapp-web.js engine returned a synthetic fwd_<id> for a forwarded message because the library's forward() yields no id, and the delivery-ack matcher keys on the stored id — so a forward never advanced past SENT and webhook/n8n consumers could not correlate it (Baileys already returns the real id). The adapter now reads the sent copy back from the destination chat and returns its real id. Recovery is best-effort: the forward already succeeded, so any error reading it back never fails the operation, and when the copy cannot be identified an empty id is returned so the row's waMessageId is left unset (no ack can mis-match it) — never a synthetic or cross-matching source id.
Merged
rmyndharis
added a commit
that referenced
this pull request
Jun 19, 2026
* fix(webhook): deliver session lifecycle events and key webhook hardening (#335) * fix(security): pin outbound webhook and media fetches to validated IP (#338) * fix(plugins): persist plugin enable/config and restore (#339) * fix(message): persist bulk-sent messages, sanitize SSRF (#340) * fix(engine): return the real id for forwarded messages (#341) * fix(security): harden outbound requests, IPv6 SSRF (#344) * fix(security): secret-file perms, key pepper, allowedIps (#345) * fix(storage): bound tar imports, contain storage keys (#346) * fix(session): reconcile late acks, serialize reactions (#348) * fix(contract): webhook timeout, bounded shutdown, 501 (#350) * feat(session): force-kill a stuck session (#352) * merge #343 * merge #351 * chore(release): v0.4.3 — CHANGELOG, version bump (package.json/dashboard/swagger), README + docs
Owner
Author
|
Shipped in v0.4.3 (integrated via the release PR #354 and tagged |
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.
Problem
Forwarding a message on the whatsapp-web.js engine returned a synthetic
fwd_<id>— the underlying library'sMessage.forward()resolves tovoid, so the adapter fabricated an id. The delivery-ack matcher keys strictly on the storedwaMessageId, and the real ack carries the sent copy's real id, so it never matched: forwarded messages were stuck atSENTforever and webhook / n8n consumers (keyed on the returned message id) could never correlate the ack. Baileys already returns the real id, so this was also a cross-engine contract drift.Fix
After
forward(), the adapter reads the sent copy back from the destination chat (the most recent outgoing message) and returns its realid._serialized, so the ack matches and the status advances — aligning whatsapp-web.js with Baileys.Hardened per review:
message.serviceleaves the row'swaMessageIdunset (NULL). A null id matches no ack and collides with nothing — unlike a syntheticfwd_id (un-correlatable) or the source id (which would sharewaMessageIdwith the source message's own row and let a single ack mis-drive both).Known limitation
Recovery selects the most-recent outgoing message by timestamp, so two near-simultaneous forwards/sends to the same destination chat could mis-identify the copy. This is documented inline and is a clear net improvement over the previous always-broken behaviour (it is correct in the dominant single-forward case); a content/source-id match could tighten it later.
Compatibility
MessageResultshape unchanged; non-breaking. SemVer: patch.Tests
fwd_<id>).