sendSeen returns success but does not reliably clear unread state #1
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Our production uses the patched
whatsapp-web.jspackage in the customwwebjs-apicontainer. The active WWeb version is2.3000.1045821369.Observed behavior
For chat
120363407613652082@g.usin sessionEddy,sendSeen(chatId)returns HTTP 200 and{\"success\":true,\"result\":true}, but the chat can remain unread (unreadCount: 1). A subsequent manualsendSeenor opening the chat may clear it.Our webhook workflow receives a message event and calls
sendSeen; logs report success, but querying the Eddy chat immediately afterwards still reports the new message as unread. This is reproducible with multiple messages, not only one incident.Current implementation
window.WWebJS.sendSeencurrently calls:The function returns
trueafter the internal call completes, without verifying that the unread state changed.Expected behavior
client.sendSeen(chatId)should reliably mark the chat as seen, or return a failure when the read state cannot be applied. The return value should not report success merely because the internal call did not throw.Related upstream reports
Requested investigation
Please test the active WWeb version and determine whether the correct internal call is
sendSeen({ chat, threadId: undefined }),markSeen(chat), or another version-specific action. Please also ensureStream.markUnavailable()is executed in afinallyblock and consider a functional confirmation of the resulting unread state.No changes have been made to this repository as part of this report.
I investigated the current implementation and the related upstream reports.
The active code already uses the newer WhatsApp Web call from upstream PR #5729:
WAWebUpdateUnreadChatAction.sendSeen({ chat, threadId: undefined }).This is also the form currently present on upstream
main, so replacing it withmarkSeen(chat)(PR #5719) is not a complete solution. Community reports on #5719 indicate that it avoids themarkedUnreadexception but can fail to produce blue read receipts.Relevant upstream status:
markedUnreadregression; closed.markSeen(chat)workaround; merged, but reports mention missing blue ticks.chatandthreadId; merged on 2026-01-29 and already present here.TypeErrorhandling should not be copied because it can report success for a real failure.The remaining difference relevant to this issue is that the local helper returns
trueafter the internal promise resolves, without checking whetherunreadCountactually became zero. It also callsStream.markUnavailable()only on the success path. A sensible next patch is therefore to keep the current object-signature, move stream cleanup intofinally, and returntrueonly after a bounded refresh/polling loop confirmsunreadCount === 0; otherwise returnfalseor propagate a real internal error. This should preserve read receipts better than a silentmarkSeenfallback.I have not yet validated this against the live production session, so the postcondition and timing still need testing with WWeb
2.3000.1045821369. Please share whether the refreshed chat model reportsunreadCount === 0after the current internal call, and whether the unread event arrives later; that will distinguish an action failure from an asynchronous/stale-model observation.