diff --git a/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js b/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js index d01717912f3b1..de4fc6c0c3b3a 100644 --- a/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js +++ b/apps/meteor/app/lib/server/lib/notifyUsersOnMessage.js @@ -63,14 +63,14 @@ export function getMentions(message) { const incGroupMentions = (rid, roomType, excludeUserId, unreadCount) => { const incUnreadByGroup = ['all_messages', 'group_mentions_only', 'user_and_group_mentions_only'].includes(unreadCount); - const incUnread = roomType === 'd' || incUnreadByGroup ? 1 : 0; + const incUnread = roomType === 'd' || roomType === 'l' || incUnreadByGroup ? 1 : 0; Subscriptions.incGroupMentionsAndUnreadForRoomIdExcludingUserId(rid, excludeUserId, 1, incUnread); }; const incUserMentions = (rid, roomType, uids, unreadCount) => { const incUnreadByUser = ['all_messages', 'user_mentions_only', 'user_and_group_mentions_only'].includes(unreadCount); - const incUnread = roomType === 'd' || incUnreadByUser ? 1 : 0; + const incUnread = roomType === 'd' || roomType === 'l' || incUnreadByUser ? 1 : 0; Subscriptions.incUserMentionsAndUnreadForRoomIdAndUserIds(rid, uids, 1, incUnread); }; @@ -86,6 +86,26 @@ const getUserIdsFromHighlights = (rid, message) => { .map(({ u: { _id: uid } }) => uid); }; +/* + * {IRoom['t']} roomType - The type of the room + * @returns {string} - The setting value for unread count + */ +const getUnreadSettingCount = (roomType) => { + let unreadSetting = 'Unread_Count'; + switch (roomType) { + case 'd': { + unreadSetting = 'Unread_Count_DM'; + break; + } + case 'l': { + unreadSetting = 'Unread_Count_Omni'; + break; + } + } + + return settings.get(unreadSetting); +}; + export async function updateUsersSubscriptions(message, room) { // Don't increase unread counter on thread messages if (room != null && !message.tmid) { @@ -93,8 +113,7 @@ export async function updateUsersSubscriptions(message, room) { const userIds = new Set(mentionIds); - const unreadSetting = room.t === 'd' ? 'Unread_Count_DM' : 'Unread_Count'; - const unreadCount = settings.get(unreadSetting); + const unreadCount = getUnreadSettingCount(room.t); getUserIdsFromHighlights(room._id, message).forEach((uid) => userIds.add(uid)); diff --git a/apps/meteor/app/lib/server/startup/settings.ts b/apps/meteor/app/lib/server/startup/settings.ts index 2a3b25cd97718..4e45541acdce8 100644 --- a/apps/meteor/app/lib/server/startup/settings.ts +++ b/apps/meteor/app/lib/server/startup/settings.ts @@ -945,6 +945,20 @@ settingsRegistry.addGroup('General', function () { ], public: true, }); + this.add('Unread_Count_Omni', 'all_messages', { + type: 'select', + values: [ + { + key: 'all_messages', + i18nLabel: 'All_messages', + }, + { + key: 'mentions_only', + i18nLabel: 'Mentions_only', + }, + ], + public: true, + }); this.add('DeepLink_Url', 'https://go.rocket.chat', { type: 'string', diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index 8869a623bcb5c..05976a07c0779 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -4926,6 +4926,7 @@ "Unread": "Unread", "Unread_Count": "Unread Count", "Unread_Count_DM": "Unread Count for Direct Messages", + "Unread_Count_Omni": "Unread Count for Omnichannel Chats", "Unread_Messages": "Unread Messages", "Unread_on_top": "Unread on top", "Unread_Rooms": "Unread Rooms", diff --git a/apps/meteor/tests/data/livechat/department.ts b/apps/meteor/tests/data/livechat/department.ts index 48b9acb7ebfe9..9de438d02469a 100644 --- a/apps/meteor/tests/data/livechat/department.ts +++ b/apps/meteor/tests/data/livechat/department.ts @@ -57,7 +57,10 @@ new Promise((resolve, reject) => { }); }); -export const createDepartmentWithAnOnlineAgent = async (): Promise<{department: ILivechatDepartment, agent: IUser}> => { +export const createDepartmentWithAnOnlineAgent = async (): Promise<{department: ILivechatDepartment, agent: { + credentials: { 'X-Auth-Token': string; 'X-User-Id': string; }; + user: IUser; +}}> => { const agent: IUser = await createUser(); const createdUserCredentials = await login(agent.username, password); await createAgent(agent.username); @@ -69,7 +72,10 @@ export const createDepartmentWithAnOnlineAgent = async (): Promise<{department: return { department, - agent, + agent: { + credentials: createdUserCredentials, + user: agent, + } }; }; diff --git a/apps/meteor/tests/data/subscriptions.ts b/apps/meteor/tests/data/subscriptions.ts new file mode 100644 index 0000000000000..04e0f48c98e4d --- /dev/null +++ b/apps/meteor/tests/data/subscriptions.ts @@ -0,0 +1,15 @@ +import type { ISubscription } from "@rocket.chat/core-typings"; +import { api, credentials, request } from "./api-data"; + +export const getSubscriptionForRoom = async (roomId: string, overrideCredential?: { 'X-Auth-Token': string; 'X-User-Id': string; }): Promise => { + const response = await request + .get(api('subscriptions.getOne')) + .set(overrideCredential || credentials) + .query({ roomId }) + .expect('Content-Type', 'application/json') + .expect(200); + + const { subscription } = response.body; + + return subscription; +} diff --git a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts index 7072a6a668a35..db77192a4eeac 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts @@ -25,6 +25,7 @@ import { createDepartmentWithAnOnlineAgent } from '../../../data/livechat/depart import { sleep } from '../../../data/livechat/utils'; import { IS_EE } from '../../../e2e/config/constants'; import { createCustomField } from '../../../data/livechat/custom-fields'; +import { getSubscriptionForRoom } from '../../../data/subscriptions'; describe('LIVECHAT - rooms', function () { this.retries(0); @@ -1446,4 +1447,62 @@ describe('LIVECHAT - rooms', function () { expect(response.body.filters.find((f: IOmnichannelRoom['source']) => f.type === 'api')).to.not.be.undefined; }); }); + + describe('it should mark room as unread when a new message arrives and the config is activated', () => { + let room: IOmnichannelRoom; + let visitor: ILivechatVisitor; + let totalMessagesSent = 0; + let departmentWithAgent: Awaited>; + + before(async () => { + await updateSetting('Livechat_Routing_Method', 'Auto_Selection'); + await updateSetting('Unread_Count_Omni', 'all_messages'); + }); + + it('it should prepare the required data for further tests', async () => { + departmentWithAgent = await createDepartmentWithAnOnlineAgent(); + visitor = await createVisitor(departmentWithAgent.department._id); + room = await createLivechatRoom(visitor.token); + + await sendMessage(room._id, 'message 1', visitor.token); + await sendMessage(room._id, 'message 2', visitor.token); + + // 1st message is for the room creation, so we need to add 1 to the total messages sent + totalMessagesSent = 3; + }); + + it("room's subscription should have correct unread count", async () => { + const { unread } = await getSubscriptionForRoom(room._id, departmentWithAgent.agent.credentials); + expect(unread).to.equal(totalMessagesSent); + }); + }); + + describe('it should NOT mark room as unread when a new message arrives and the config is deactivated', () => { + let room: IOmnichannelRoom; + let visitor: ILivechatVisitor; + let totalMessagesSent = 0; + let departmentWithAgent: Awaited>; + + before(async () => { + await updateSetting('Livechat_Routing_Method', 'Auto_Selection'); + await updateSetting('Unread_Count_Omni', 'mentions_only'); + }); + + it('it should prepare the required data for further tests', async () => { + departmentWithAgent = await createDepartmentWithAnOnlineAgent(); + visitor = await createVisitor(departmentWithAgent.department._id); + room = await createLivechatRoom(visitor.token); + + await sendMessage(room._id, 'message 1', visitor.token); + await sendMessage(room._id, 'message 2', visitor.token); + + // 1st message is for the room creation, so we need to add 1 to the total messages sent + totalMessagesSent = 1; + }); + + it("room's subscription should have correct unread count", async () => { + const { unread } = await getSubscriptionForRoom(room._id, departmentWithAgent.agent.credentials); + expect(unread).to.equal(totalMessagesSent); + }); + }); });