Skip to content

Comments

fix: unread count for DMs when user has mentions-only preference#38836

Open
NagajyothiChukka wants to merge 4 commits intoRocketChat:developfrom
NagajyothiChukka:fix/unread-count-zero
Open

fix: unread count for DMs when user has mentions-only preference#38836
NagajyothiChukka wants to merge 4 commits intoRocketChat:developfrom
NagajyothiChukka:fix/unread-count-zero

Conversation

@NagajyothiChukka
Copy link

@NagajyothiChukka NagajyothiChukka commented Feb 20, 2026

Summary

This PR fixes Issue #23977 where users with the "Mentions Only" notification preference would not see unread badges for Direct Messages.

Details

Modified notifyUsersOnMessage.ts to explicitly check for the Direct Message room type (room.t === 'd'). This ensures that even if a user's global preference is set to 'Mentions Only', DMs will still trigger an unread count increment in the database.

Impact

  • Fixes the unread count in the REST API (/api/v1/subscriptions.get).
  • Ensures Mobile and Desktop apps (which rely on the server database) show the correct notification badge.
  • Maintains data consistency after a page refresh.

Related Issue

Closes #23977

Summary by CodeRabbit

  • Bug Fixes
    • Unread counts for direct messages now increment correctly even without mentions and when "unread all messages" is disabled.
    • Per-conversation unread and notification behavior for direct messages updated so DM subscriptions are marked unread and notify more reliably.
    • Notification popup behavior adjusted to prevent unintended automatic opening.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Feb 20, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Feb 20, 2026

⚠️ No Changeset found

Latest commit: f615f02

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

No actionable comments were generated in the recent review. 🎉

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2113796 and f615f02.

📒 Files selected for processing (1)
  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer

Walkthrough

Broadened unread/notification update logic for direct-message rooms: direct messages (room.t === 'd') are now included in per-subscription unread-count and notification calculations; a previously active open: true flag in the notification payload was commented out.

Changes

Cohort / File(s) Summary
Unread & Notification Logic
apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
Include room.t === 'd' in unread-increment and shouldIncUnread checks so DMs participate in unread counting and notification decisions; changed notification payload by commenting out open: true.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I hopped through lines of code tonight,
Counted dms by soft moonlight.
Where zeros lingered, numbers bloom —
A tiny fix, a quieter room. 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: fixing unread count for direct messages when users have mentions-only notification preference, which directly addresses the PR's core objective.
Linked Issues check ✅ Passed The code changes directly address issue #23977 by ensuring DM unread counts are incremented and properly tracked in the database, matching the expected behavior of returning accurate unread counts via the API.
Out of Scope Changes check ✅ Passed All changes are scoped to the notifyUsersOnMessage.ts file and focused on fixing DM unread counting logic, with no unrelated modifications present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts (1)

128-142: ⚠️ Potential issue | 🟠 Major

shouldIncUnread is inconsistent with the DB increment — real-time unread badge remains 0 for DMs.

Line 118 now correctly increments the DB unread count for DMs when !toAll && !toHere && !unreadAllMessages, but the real-time WebSocket notification path at line 130 still uses:

const shouldIncUnread = hasUserMention || toAll || toHere || unreadAllMessages;

For a DM with no mentions and Unread_Count_DM = 'user_mentions_only', every term is false, so shouldIncUnread = false. The notifyOnSubscriptionChanged payload is broadcast without unread: sub.unread + 1, so clients relying on the WebSocket stream (mobile, desktop) will still display unread count = 0 in real-time. The correct value only appears after a full page refresh that re-reads the DB.

This contradicts the stated PR goal of fixing badges on mobile and desktop apps.

🐛 Proposed fix
- const shouldIncUnread = hasUserMention || toAll || toHere || unreadAllMessages;
+ const shouldIncUnread = hasUserMention || toAll || toHere || unreadAllMessages || room.t === 'd';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts` around lines 128 -
142, The real-time increment boolean shouldIncUnread used inside subs.forEach
does not match the DB increment logic, causing DMs to show 0 until refresh;
update shouldIncUnread (used before calling notifyOnSubscriptionChanged) to use
the exact same condition/expression you used when updating the DB (the boolean
that caused the DB unread increment), or extract that DB condition into a shared
variable (e.g., shouldIncUnreadDb) and reuse it here so
notifyOnSubscriptionChanged receives unread: sub.unread + 1 whenever the DB was
incremented (ensure you still include hasUserMention, toAll, toHere,
unreadAllMessages and the DM-specific case from the DB update logic when
computing the boolean).
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1710997 and f9499dd.

📒 Files selected for processing (1)
  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
🧠 Learnings (4)
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.

Applied to files:

  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.

Applied to files:

  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
📚 Learning: 2025-11-19T18:20:37.116Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37419
File: apps/meteor/server/services/media-call/service.ts:141-141
Timestamp: 2025-11-19T18:20:37.116Z
Learning: In apps/meteor/server/services/media-call/service.ts, the sendHistoryMessage method should use call.caller.id or call.createdBy?.id as the message author, not call.transferredBy?.id. Even for transferred calls, the message should appear in the DM between the two users who are calling each other, not sent by the person who transferred the call.

Applied to files:

  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🔇 Additional comments (1)
apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts (1)

118-120: DB-side fix is logically sound.

The new || room.t === 'd' condition correctly fires incUnreadForRoomIdExcludingUserIds for all non-mentioned, non-sender subscribers in a DM when Unread_Count_DM is not all_messages. No double-counting occurs because:

  • Mentioned users are already excluded via [...userIds, message.u._id]
  • @all/@here cases are guarded by !toAll && !toHere
  • When unreadAllMessages is also true, the || evaluates once, still calling the increment exactly once
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts`:
- Around line 128-142: The real-time increment boolean shouldIncUnread used
inside subs.forEach does not match the DB increment logic, causing DMs to show 0
until refresh; update shouldIncUnread (used before calling
notifyOnSubscriptionChanged) to use the exact same condition/expression you used
when updating the DB (the boolean that caused the DB unread increment), or
extract that DB condition into a shared variable (e.g., shouldIncUnreadDb) and
reuse it here so notifyOnSubscriptionChanged receives unread: sub.unread + 1
whenever the DB was incremented (ensure you still include hasUserMention, toAll,
toHere, unreadAllMessages and the DM-specific case from the DB update logic when
computing the boolean).

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/RocketChat/Rocket.Chat/issues/comments/3932939917","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\nNo actionable comments were generated in the recent review. 🎉\n\n<details>\n<summary>📜 Recent review details</summary>\n\n**Configuration used**: Organization UI\n\n**Review profile**: CHILL\n\n**Plan**: Pro\n\n<details>\n<summary>📥 Commits</summary>\n\nReviewing files that changed from the base of the PR and between f9499dd881f9e82aa78efbe01d8485f250c33c9d and e716668a51030c5cb92bdf3e42993e71f5724c9f.\n\n</details>\n\n<details>\n<summary>📒 Files selected for processing (1)</summary>\n\n* `apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts`\n\n</details>\n\n<details>\n<summary>🚧 Files skipped from review as they are similar to previous changes (1)</summary>\n\n* apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts\n\n</details>\n\n<details>\n<summary>⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)</summary>\n\n* GitHub Check: cubic · AI code reviewer\n\n</details>\n\n</details>\n\n---\n\n\n<!-- walkthrough_start -->\n\n## Walkthrough\n\nUpdated unread-increment logic so direct-message rooms (`room.t === 'd'`) are treated like `unreadAllMessages` for non-mention cases; subscriptions for DMs now increment unread counts when no `@all/@here` mentions and no mention-targeted conditions apply.\n\n## Changes\n\n|Cohort / File(s)|Summary|\n|---|---|\n|**Unread Count Logic** <br> `apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts`|Expanded unread-increment checks to include direct-message rooms (`room.t === 'd'`) alongside `unreadAllMessages`; updated per-subscription `shouldIncUnread` evaluation to consider DMs for unread increments.|\n\n## Estimated code review effort\n\n🎯 1 (Trivial) | ⏱️ ~3 minutes\n\n## Poem\n\n> 🐰 I nibble through lines with a curious cheer,  \n> Direct chats now count when new messages appear,  \n> No more zeros in the unread view,  \n> Hops of logic make the numbers true,  \n> 🎉📬\n\n<!-- walkthrough_end -->\n\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 4 | ❌ 1</summary>\n\n### ❌ Failed checks (1 warning)\n\n|     Check name     | Status     | Explanation                                                                          | Resolution                                                                         |\n| :----------------: | :--------- | :----------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------- |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |\n\n<details>\n<summary>✅ Passed checks (4 passed)</summary>\n\n|         Check name         | Status   | Explanation                                                                                                                                                                                                                                  |\n| :------------------------: | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n|      Description Check     | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled.                                                                                                                                                                                  |\n|         Title check        | ✅ Passed | The title 'fix: unread count for DMs when user has mentions-only preference' is clear and specific, directly reflecting the main change—fixing unread count behavior for direct messages with mentions-only notification preferences.        |\n|     Linked Issues check    | ✅ Passed | The code changes directly address the objective in issue `#23977` by updating notifyUsersOnMessage.ts to include direct message rooms (room.t === 'd') in unread count incrementation, ensuring correct unread counts are returned by the API. |\n| Out of Scope Changes check | ✅ Passed | All changes are focused on fixing unread count logic for direct messages; no unrelated modifications to user mentions, group mentions, or notification payload structure beyond the intended scope.                                          |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=RocketChat/Rocket.Chat&utm_content=38836)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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 -->\n\n<!-- internal state end -->"},"request":{"retryCount":3,"retries":3,"retryAfter":16}}}

@KevLehman KevLehman added the contrib: valid A valid contribution where maintainers will review based on priority label Feb 20, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts (2)

104-109: ⚠️ Potential issue | 🟡 Minor

onlyRead not updated to match the new DM increment logic

The subs query's onlyRead evaluates to true for DMs when Unread_Count_DM !== 'all_messages' (i.e., when unreadAllMessages === false). This limits which subscriptions are included in subs for real-time notifyOnSubscriptionChanged dispatch. While the DB increment at line 119 fires correctly for all DMs, subscriptions in non-"read" state (e.g., open=false — users who have never opened the DM) may be excluded from the real-time path and won't receive a live unread-count update.

For consistency with the new DM behavior, onlyRead should also be false for DM rooms:

🔧 Proposed fix
- onlyRead: !toAll && !toHere && !unreadAllMessages,
+ onlyRead: !toAll && !toHere && !unreadAllMessages && room.t !== 'd',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts` around lines 104 -
109, The subs query uses onlyRead: !toAll && !toHere && !unreadAllMessages which
remains true for DMs when Unread_Count_DM !== 'all_messages' and therefore
excludes subscriptions that should get real-time updates; update the call to
Subscriptions.findByRoomIdAndNotAlertOrOpenExcludingUserIds (the subs query) to
force onlyRead = false for direct-message rooms by including a room type check
(e.g., room.t !== 'd') so the final expression becomes onlyRead: !toAll &&
!toHere && !unreadAllMessages && room.t !== 'd', ensuring DM subscriptions are
included for real-time notifyOnSubscriptionChanged dispatch.

104-109: ⚠️ Potential issue | 🟡 Minor

onlyRead not updated to match the new DM increment path

For a DM room where Unread_Count_DM !== 'all_messages', unreadAllMessages is false, so onlyRead evaluates to true. This limits the subs array to subscriptions already in a "read" state. For the typical case (recipient has read all previous messages, alert=false), this is fine — the real-time notification still fires. However, subscriptions where open=false (e.g., a brand-new DM inbox that was never opened) satisfy "NOT open" but may be excluded by onlyRead=true, meaning their real-time update is silently dropped even though the DB unread count is correctly incremented at line 119.

🔧 Proposed fix
- onlyRead: !toAll && !toHere && !unreadAllMessages,
+ onlyRead: !toAll && !toHere && !unreadAllMessages && room.t !== 'd',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts` around lines 104 -
109, The subscriptions query uses onlyRead derived from unreadAllMessages but
doesn't account for the DM increment path; update the onlyRead argument passed
to Subscriptions.findByRoomIdAndNotAlertOrOpenExcludingUserIds so that when
handling a direct message room (room.t === 'd') where the DM unread increment
path is used (i.e., Unread_Count_DM !== 'all_messages'), onlyRead is forced to
false; in practice change the onlyRead expression (currently !toAll && !toHere
&& !unreadAllMessages) to also check room.t and the DM-unread condition and set
onlyRead = false for that DM case so subscriptions with open=false are included.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9499dd and 2113796.

📒 Files selected for processing (1)
  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
🧠 Learnings (3)
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.

Applied to files:

  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.

Applied to files:

  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
🔇 Additional comments (1)
apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts (1)

118-120: Verify DM unread increment bypass is intentional

The room.t === 'd' guards at lines 118 and 130 cause all DM messages to increment the unread counter regardless of the Unread_Count_DM setting. When Unread_Count_DM='user_mentions_only', plain (non-mentioned) users will still receive unread increments.

This pattern is consistent with the existing getUserMentions/getGroupMentions helpers (lines 43–53), which already return 1 for DMs regardless of the setting. However, those helpers apply only to mentioned users (lines 99–100), whereas lines 118 and 130 extend the bypass to all users in a DM via the plain message path. Confirm whether treating DM messages as always unread-eligible—overriding the admin-configured setting—is the intended product behavior.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts`:
- Around line 118-120: The DM branch currently forces general unread increments
by calling Subscriptions.incUnreadForRoomIdExcludingUserIds when room.t === 'd',
which bypasses the Unread_Count_DM setting; update the condition (the if that
uses toAll, toHere, unreadAllMessages and room.t) to consult the Unread_Count_DM
value (e.g., unreadCount or however the setting is read in this module) and only
treat DMs as auto-incrementing when the setting is not 'mentions_only' (i.e.,
change the room.t === 'd' check to something like room.t === 'd' && unreadCount
!== 'mentions_only'), ensuring Subscriptions.incUnreadForRoomIdExcludingUserIds
is only called when the configured policy allows it.

---

Outside diff comments:
In `@apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts`:
- Around line 104-109: The subs query uses onlyRead: !toAll && !toHere &&
!unreadAllMessages which remains true for DMs when Unread_Count_DM !==
'all_messages' and therefore excludes subscriptions that should get real-time
updates; update the call to
Subscriptions.findByRoomIdAndNotAlertOrOpenExcludingUserIds (the subs query) to
force onlyRead = false for direct-message rooms by including a room type check
(e.g., room.t !== 'd') so the final expression becomes onlyRead: !toAll &&
!toHere && !unreadAllMessages && room.t !== 'd', ensuring DM subscriptions are
included for real-time notifyOnSubscriptionChanged dispatch.
- Around line 104-109: The subscriptions query uses onlyRead derived from
unreadAllMessages but doesn't account for the DM increment path; update the
onlyRead argument passed to
Subscriptions.findByRoomIdAndNotAlertOrOpenExcludingUserIds so that when
handling a direct message room (room.t === 'd') where the DM unread increment
path is used (i.e., Unread_Count_DM !== 'all_messages'), onlyRead is forced to
false; in practice change the onlyRead expression (currently !toAll && !toHere
&& !unreadAllMessages) to also check room.t and the DM-unread condition and set
onlyRead = false for that DM case so subscriptions with open=false are included.

Comment on lines +118 to 120
if (!toAll && !toHere && (unreadAllMessages || room.t === 'd')) {
await Subscriptions.incUnreadForRoomIdExcludingUserIds(room._id, [...userIds, message.u._id], 1);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

rg -n "Unread_Count_DM" --type ts -C 3

Repository: RocketChat/Rocket.Chat

Length of output: 1034


🏁 Script executed:

cat -n apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts | head -150

Repository: RocketChat/Rocket.Chat

Length of output: 6772


🏁 Script executed:

# Search for Unread_Count_DM in all file types to understand its definition
rg "Unread_Count_DM" -C 5

Repository: RocketChat/Rocket.Chat

Length of output: 50378


🏁 Script executed:

# Get the full setting definition for Unread_Count_DM
sed -n '146,160p' apps/meteor/server/settings/general.ts

Repository: RocketChat/Rocket.Chat

Length of output: 380


🏁 Script executed:

# Also check what values are allowed for the setting
rg -A 20 "this.add\('Unread_Count_DM'" apps/meteor/server/settings/general.ts

Repository: RocketChat/Rocket.Chat

Length of output: 483


🏁 Script executed:

# Look for any comments or recent changes around the lines in question
sed -n '85,135p' apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts

Repository: RocketChat/Rocket.Chat

Length of output: 2186


🏁 Script executed:

# Get the exact function context around lines 50-58 to see the precedent
sed -n '48,59p' apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts

Repository: RocketChat/Rocket.Chat

Length of output: 820


🏁 Script executed:

# Verify the values parameter for Unread_Count_DM is complete
rg -A 15 "'mentions_only'" apps/meteor/server/settings/general.ts | head -20

Repository: RocketChat/Rocket.Chat

Length of output: 422


Unread_Count_DM setting is effectively bypassed for general unread increments on DM rooms

The room.t === 'd' guard at lines 118-120 and 130 unconditionally increments unread counts for all DM messages, overriding the Unread_Count_DM setting when configured to mentions_only. This creates an inconsistency: while user and group mention increments correctly treat DMs as a special case (lines 50-58 always return 1 for DMs), the general unread increment ignores the setting entirely for DM rooms.

This may be intentional per historical DM notification behavior, but since Unread_Count_DM remains configurable with two distinct options, confirm with the product team whether the setting should be fully ignored for the unread increment path in DMs, or whether a narrower condition (e.g., only bypass when unreadCount !== 'mentions_only') is intended.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts` around lines 118 -
120, The DM branch currently forces general unread increments by calling
Subscriptions.incUnreadForRoomIdExcludingUserIds when room.t === 'd', which
bypasses the Unread_Count_DM setting; update the condition (the if that uses
toAll, toHere, unreadAllMessages and room.t) to consult the Unread_Count_DM
value (e.g., unreadCount or however the setting is read in this module) and only
treat DMs as auto-incrementing when the setting is not 'mentions_only' (i.e.,
change the room.t === 'd' check to something like room.t === 'd' && unreadCount
!== 'mentions_only'), ensuring Subscriptions.incUnreadForRoomIdExcludingUserIds
is only called when the configured policy allows it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contrib: valid A valid contribution where maintainers will review based on priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Private message unread count 0 for normal user

2 participants