fix(baileys): correct JID filter in markMessageAsRead for all user types#2418
Open
easedu wants to merge 1 commit intoEvolutionAPI:mainfrom
Open
fix(baileys): correct JID filter in markMessageAsRead for all user types#2418easedu wants to merge 1 commit intoEvolutionAPI:mainfrom
easedu wants to merge 1 commit intoEvolutionAPI:mainfrom
Conversation
The condition used isPnUser() which only matches @pn.whatsapp.net JIDs, silently excluding normal users (@s.whatsapp.net) and LID users (@lid). Messages were never actually marked as read for these JID types. Replace allowlist approach (isJidGroup || isPnUser) with denylist (!isJidBroadcast && !isJidNewsletter) to correctly include all valid user and group JIDs while excluding only broadcast and newsletter JIDs. Fixes EvolutionAPI#2277
Contributor
Reviewer's guide (collapsed on small PRs)Reviewer's GuideAdjusts the JID filter in Baileys Sequence diagram for updated markMessageAsRead JID filteringsequenceDiagram
actor User
participant App
participant BaileysStartupService
participant BaileysSocket
User->>App: Trigger markMessageAsRead
App->>BaileysStartupService: markMessageAsRead(data)
loop for each read in data.readMessages
BaileysStartupService->>BaileysStartupService: isJidBroadcast(read.remoteJid)
alt remoteJid is broadcast
BaileysStartupService-->>BaileysStartupService: Skip read (no key added)
else remoteJid is not broadcast
BaileysStartupService->>BaileysStartupService: isJidNewsletter(read.remoteJid)
alt remoteJid is newsletter
BaileysStartupService-->>BaileysStartupService: Skip read (no key added)
else remoteJid is not newsletter
BaileysStartupService-->>BaileysStartupService: Push message key to keys
end
end
end
BaileysStartupService->>BaileysSocket: sendReadReceipt(keys)
BaileysSocket-->>BaileysStartupService: Read receipts acknowledged
BaileysStartupService-->>App: markMessageAsRead completed
App-->>User: Messages appear as read
Class diagram for BaileysStartupService markMessageAsRead JID filteringclassDiagram
class BaileysStartupService {
+markMessageAsRead(data)
-buildReadKeys(data) keys
}
class JidPredicates {
+isJidBroadcast(jid)
+isJidNewsletter(jid)
}
class ReadMessage {
+remoteJid
+fromMe
+id
}
class ReadData {
+readMessages ReadMessage[]
}
BaileysStartupService --> ReadData : uses
ReadData --> ReadMessage : contains
BaileysStartupService ..> JidPredicates : filters JIDs with
JidPredicates <.. ReadMessage : evaluates remoteJid
Flow diagram for new JID denylist in markMessageAsReadflowchart TD
A[Start processing readMessages] --> B[Take next read from data.readMessages]
B --> C{Any read left?}
C -->|No| Z[End]
C -->|Yes| D["Evaluate isJidBroadcast(read.remoteJid)"]
D --> E{is broadcast?}
E -->|Yes| B
E -->|No| F["Evaluate isJidNewsletter(read.remoteJid)"]
F --> G{is newsletter?}
G -->|Yes| B
G -->|No| H["Push {remoteJid, fromMe, id} into keys"]
H --> B
File-Level Changes
Assessment against linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Contributor
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- Since the logic change from an allowlist to a denylist is subtle and driven by Baileys JID-type behavior, consider adding a brief inline comment explaining why only broadcast and newsletter JIDs are excluded to help future maintainers avoid reintroducing overly restrictive filters.
- If
read.remoteJidcan ever be null/undefined or malformed from upstream data, it may be worth guarding or asserting before passing it intoisJidBroadcast/isJidNewsletterto avoid unexpected runtime issues.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Since the logic change from an allowlist to a denylist is subtle and driven by Baileys JID-type behavior, consider adding a brief inline comment explaining why only broadcast and newsletter JIDs are excluded to help future maintainers avoid reintroducing overly restrictive filters.
- If `read.remoteJid` can ever be null/undefined or malformed from upstream data, it may be worth guarding or asserting before passing it into `isJidBroadcast`/`isJidNewsletter` to avoid unexpected runtime issues.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
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.
📋 Description
markMessageAsReadsilently fails for most users due to an incorrect JID filter condition.The current code uses an allowlist approach:
isPnUser()only matches@pn.whatsapp.netJIDs, which excludes:@s.whatsapp.net) — the vast majority of contacts@lid) — linked device identifiersMessages were never actually marked as read for these JID types.
Root cause: When Baileys upgraded to v7,
isJidUser()(which matched both@s.whatsapp.netand@pn.whatsapp.net) was removed. The replacement withisPnUser()was incorrect as it only covers one of the two user JID formats.Solution: Replace the allowlist with a denylist that excludes only JID types that genuinely cannot receive read receipts:
A denylist is more resilient to future Baileys changes — new JID types will work by default instead of being silently excluded.
🔗 Related Issue
Closes #2277
🧪 Type of Change
🧪 Testing
Verified that
isJidBroadcastandisJidNewslettercorrectly exclude only@broadcastand@newsletterJIDs, while allowing@s.whatsapp.net,@pn.whatsapp.net,@lid, and group JIDs to pass through.📸 Screenshots (if applicable)
N/A — backend logic change only.
✅ Checklist
📝 Additional Notes
Both
isJidBroadcastandisJidNewsletterwere already imported in the file (used elsewhere in the codebase), so no new dependencies were added.Summary by Sourcery
Bug Fixes: