diff --git a/.changeset/silent-dolphins-argue.md b/.changeset/silent-dolphins-argue.md new file mode 100644 index 0000000000000..bbdf3f44b8149 --- /dev/null +++ b/.changeset/silent-dolphins-argue.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Fixes an issue where the `Show Message in Notification` and `Show Channel/Group/Username in Notification` setting was ignored in desktop notifications. Also ensures users are redirected to the correct room on interacting with the notifications. diff --git a/apps/meteor/.mocharc.js b/apps/meteor/.mocharc.js index 78a2a22611a5b..cb5d11f38093b 100644 --- a/apps/meteor/.mocharc.js +++ b/apps/meteor/.mocharc.js @@ -41,5 +41,6 @@ module.exports = { 'tests/unit/server/**/*.spec.ts', 'app/api/server/lib/**/*.spec.ts', 'app/file-upload/server/**/*.spec.ts', + 'app/lib/server/functions/notifications/**/*.spec.ts', ], }; diff --git a/apps/meteor/app/lib/server/functions/notifications/desktop.spec.ts b/apps/meteor/app/lib/server/functions/notifications/desktop.spec.ts new file mode 100644 index 0000000000000..6a2f2e11f4d10 --- /dev/null +++ b/apps/meteor/app/lib/server/functions/notifications/desktop.spec.ts @@ -0,0 +1,231 @@ +import type { IRoom } from '@rocket.chat/core-typings'; +import { UserStatus } from '@rocket.chat/core-typings'; +import { expect } from 'chai'; +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; + +const broadcastStub = sinon.stub(); +const settingsGetStub = sinon.stub(); + +const { buildNotificationDetails } = proxyquire.noCallThru().load('../../../../../server/lib/rooms/buildNotificationDetails.ts', { + '../../../app/settings/server': { settings: { get: settingsGetStub } }, +}); +const { roomCoordinator } = proxyquire.noCallThru().load('../../../../../server/lib/rooms/roomCoordinator.ts', { + '../../../app/settings/server': { settings: { get: settingsGetStub } }, + './buildNotificationDetails': { buildNotificationDetails }, +}); + +['public', 'private', 'voip', 'livechat'].forEach((type) => { + proxyquire.noCallThru().load(`../../../../../server/lib/rooms/roomTypes/${type}.ts`, { + '../../../../app/settings/server': { settings: { get: settingsGetStub } }, + '../roomCoordinator': { roomCoordinator }, + '../buildNotificationDetails': { buildNotificationDetails }, + }); +}); + +proxyquire.noCallThru().load('../../../../../server/lib/rooms/roomTypes/direct.ts', { + '../../../../app/settings/server': { settings: { get: settingsGetStub } }, + '../roomCoordinator': { roomCoordinator }, + '../buildNotificationDetails': { buildNotificationDetails }, + 'meteor/meteor': { Meteor: { userId: () => 'user123' } }, + '@rocket.chat/models': { + Subscription: { + findOneByRoomIdAndUserId: () => ({ name: 'general', fname: 'general' }), + }, + }, +}); + +const { notifyDesktopUser } = proxyquire.noCallThru().load('./desktop', { + '../../../../settings/server': { settings: { get: settingsGetStub } }, + '../../../../metrics/server': { + metrics: { + notificationsSent: { inc: sinon.stub() }, + }, + }, + '@rocket.chat/core-services': { api: { broadcast: broadcastStub } }, + '../../lib/sendNotificationsOnMessage': {}, + '../../../../../server/lib/rooms/roomCoordinator': { roomCoordinator }, +}); + +const fakeUserId = 'user123'; + +const createTestData = (t: IRoom['t'] = 'c', showPushMessage = false, showUserOrRoomName = false, groupDM = false) => { + const sender = { _id: 'sender123', name: 'Alice', username: 'alice' }; + let uids: string[] | undefined; + if (t === 'd') { + uids = groupDM ? ['sender123', 'user123', 'otherUser123'] : ['sender123', 'user123']; + } + + const room: Partial = { + t, + _id: 'room123', + msgs: 0, + _updatedAt: new Date(), + u: sender, + usersCount: uids ? uids.length : 2, + fname: uids?.length === 2 ? sender.name : 'general', + name: uids?.length === 2 ? sender.username : 'general', + uids, + }; + + const message = { + _id: 'msg123', + rid: 'room123', + tmid: null, + u: sender, + msg: 'Fake message here', + }; + + const receiver = { + _id: 'user123', + language: 'en', + username: 'receiver-username', + emails: [{ address: 'receiver@example.com', verified: true }], + active: true, + status: UserStatus.OFFLINE, + statusConnection: 'offline', + }; + + let expectedTitle: string | undefined; + if (showUserOrRoomName) { + switch (t) { + case 'c': + case 'p': + expectedTitle = `#${room.name}`; + break; + case 'l': + case 'v': + expectedTitle = `[Omnichannel] ${room.name}`; + break; + case 'd': + expectedTitle = room.name; + break; + } + } + + let expectedNotificationMessage: string; + + if (!showPushMessage) { + expectedNotificationMessage = 'You have a new message'; + } else if (!showUserOrRoomName) { + // No prefix if showUserOrRoomName is false + expectedNotificationMessage = message.msg; + } else if (t === 'd' && uids && uids.length > 2) { + expectedNotificationMessage = `${sender.username}: ${message.msg}`; + } else { + switch (t) { + case 'c': + case 'p': + expectedNotificationMessage = `${sender.username}: ${message.msg}`; + break; + case 'l': + case 'v': + case 'd': + expectedNotificationMessage = message.msg; + break; + } + } + + return { + room: room as IRoom, + user: sender, + message, + receiver, + expectedTitle, + expectedNotificationMessage, + }; +}; + +describe('notifyDesktopUser privacy settings across all room types', () => { + const roomTypes: Array<{ t: IRoom['t']; isGroupDM?: boolean }> = [ + { t: 'c' }, + { t: 'p' }, + { t: 'l' }, + { t: 'v' }, + { t: 'd', isGroupDM: false }, + { t: 'd', isGroupDM: true }, + ]; + + afterEach(() => { + broadcastStub.resetHistory(); + settingsGetStub.resetHistory(); + }); + + roomTypes.forEach(({ t, isGroupDM = false }) => { + let roomLabel: string; + if (t === 'c') { + roomLabel = 'channel'; + } else if (t === 'p') { + roomLabel = 'private'; + } else if (t === 'l') { + roomLabel = 'livechat'; + } else if (t === 'v') { + roomLabel = 'voip'; + } else if (t === 'd' && isGroupDM) { + roomLabel = 'direct (group DM)'; + } else { + roomLabel = 'direct (1:1 DM)'; + } + + describe(`when room type is "${roomLabel}"`, () => { + [ + { showPushMessage: false, showUserOrRoomName: true }, + { showPushMessage: true, showUserOrRoomName: false }, + { showPushMessage: false, showUserOrRoomName: false }, + { showPushMessage: true, showUserOrRoomName: true }, + ].forEach(({ showPushMessage, showUserOrRoomName }) => { + const label = `Push_show_message=${ + showPushMessage ? 'true' : 'false' + } and Push_show_username_room=${showUserOrRoomName ? 'true' : 'false'}`; + + it(`should handle settings: ${label}`, async () => { + const { room, user, message, receiver, expectedTitle, expectedNotificationMessage } = createTestData( + t, + showPushMessage, + showUserOrRoomName, + isGroupDM, + ); + + settingsGetStub.withArgs('Push_show_message').returns(showPushMessage); + settingsGetStub.withArgs('Push_show_username_room').returns(showUserOrRoomName); + settingsGetStub.withArgs('UI_Use_Real_Name').returns(false); + + const duration = 4000; + const notificationMessage = message.msg; + + await notifyDesktopUser({ + userId: fakeUserId, + user, + room, + message, + duration, + notificationMessage, + receiver, + }); + + expect(broadcastStub.calledOnce).to.be.true; + const [eventName, targetUserId, payload] = broadcastStub.firstCall.args as [string, string, any]; + + expect(eventName).to.equal('notify.desktop'); + expect(targetUserId).to.equal(fakeUserId); + + expect(payload.text).to.equal(expectedNotificationMessage); + + if (showPushMessage) { + expect(payload.payload.message?.msg).to.equal(message.msg); + } else { + expect(!!payload.payload.message?.msg).to.equal(false); + } + + if (showUserOrRoomName) { + expect(payload.title).to.equal(expectedTitle); + expect(payload.payload.name).to.equal(room.name); + } else { + expect(!!payload.title).to.equal(false, `Found title to be ${payload.title} when expected falsy`); + expect(!!payload.payload.name).to.equal(false, `Found name to be ${payload.name} when expected falsy`); + } + }); + }); + }); + }); +}); diff --git a/apps/meteor/app/lib/server/functions/notifications/desktop.ts b/apps/meteor/app/lib/server/functions/notifications/desktop.ts index 1afac17f9f58a..9e1b009c24126 100644 --- a/apps/meteor/app/lib/server/functions/notifications/desktop.ts +++ b/apps/meteor/app/lib/server/functions/notifications/desktop.ts @@ -4,6 +4,7 @@ import type { IMessage, IRoom, IUser, AtLeast } from '@rocket.chat/core-typings' import { roomCoordinator } from '../../../../../server/lib/rooms/roomCoordinator'; import { metrics } from '../../../../metrics/server'; import { settings } from '../../../../settings/server'; +import type { SubscriptionAggregation } from '../../lib/sendNotificationsOnMessage'; /** * Send notification to user @@ -22,6 +23,7 @@ export async function notifyDesktopUser({ room, duration, notificationMessage, + receiver, }: { userId: string; user: AtLeast; @@ -29,10 +31,13 @@ export async function notifyDesktopUser({ room: IRoom; duration?: number; notificationMessage: string; + receiver?: SubscriptionAggregation['receiver'][number]; }): Promise { const { title, text, name } = await roomCoordinator .getRoomDirectives(room.t) - .getNotificationDetails(room, user, notificationMessage, userId); + .getNotificationDetails(room, user, notificationMessage, userId, receiver?.language); + + const showPushMessage = settings.get('Push_show_message'); const payload = { title: title || '', @@ -51,7 +56,7 @@ export async function notifyDesktopUser({ sender: message.u, type: room.t, message: { - msg: 'msg' in message ? message.msg : '', + msg: 'msg' in message && showPushMessage ? message.msg : '', ...('t' in message && { t: message.t, }), diff --git a/apps/meteor/app/lib/server/lib/sendNotificationsOnMessage.ts b/apps/meteor/app/lib/server/lib/sendNotificationsOnMessage.ts index 25330d912aafd..56e30590e8d29 100644 --- a/apps/meteor/app/lib/server/lib/sendNotificationsOnMessage.ts +++ b/apps/meteor/app/lib/server/lib/sendNotificationsOnMessage.ts @@ -24,7 +24,7 @@ import { getEmailData, shouldNotifyEmail } from '../functions/notifications/emai import { messageContainsHighlight } from '../functions/notifications/messageContainsHighlight'; import { getPushData, shouldNotifyMobile } from '../functions/notifications/mobile'; -type SubscriptionAggregation = { +export type SubscriptionAggregation = { receiver: [Pick | null]; } & Pick< ISubscription, @@ -134,6 +134,7 @@ export const sendNotification = async ({ user: sender, message, room, + receiver, }); } diff --git a/apps/meteor/client/hooks/notification/useNotification.ts b/apps/meteor/client/hooks/notification/useNotification.ts index 6caa2b2ecc966..78aec1723765f 100644 --- a/apps/meteor/client/hooks/notification/useNotification.ts +++ b/apps/meteor/client/hooks/notification/useNotification.ts @@ -22,7 +22,7 @@ export const useNotification = () => { return; } - const { rid } = notification.payload; + const { rid, name, _id: msgId } = notification.payload; if (!rid) { return; } @@ -63,56 +63,54 @@ export const useNotification = () => { n.close(); window.focus(); - if (!notification.payload._id || !notification.payload.rid || !notification.payload.name) { - return; - } + const jump = msgId && { jump: msgId }; switch (notification.payload?.type) { case 'd': router.navigate({ pattern: '/direct/:rid/:tab?/:context?', params: { - rid: notification.payload.rid, + rid, ...(notification.payload.tmid && { tab: 'thread', context: notification.payload.tmid, }), }, - search: { ...router.getSearchParameters(), jump: notification.payload._id }, + search: { ...router.getSearchParameters(), ...jump }, }); break; case 'c': return router.navigate({ pattern: '/channel/:name/:tab?/:context?', params: { - name: notification.payload.name, + name: name || rid, ...(notification.payload.tmid && { tab: 'thread', context: notification.payload.tmid, }), }, - search: { ...router.getSearchParameters(), jump: notification.payload._id }, + search: { ...router.getSearchParameters(), ...jump }, }); case 'p': return router.navigate({ pattern: '/group/:name/:tab?/:context?', params: { - name: notification.payload.name, + name: name || rid, ...(notification.payload.tmid && { tab: 'thread', context: notification.payload.tmid, }), }, - search: { ...router.getSearchParameters(), jump: notification.payload._id }, + search: { ...router.getSearchParameters(), ...jump }, }); case 'l': return router.navigate({ pattern: '/live/:id/:tab?/:context?', params: { - id: notification.payload.rid, + id: rid, tab: 'room-info', }, - search: { ...router.getSearchParameters(), jump: notification.payload._id }, + search: { ...router.getSearchParameters(), ...jump }, }); } }; diff --git a/apps/meteor/definition/IRoomTypeConfig.ts b/apps/meteor/definition/IRoomTypeConfig.ts index c1772ad34cf2d..25451f1d45849 100644 --- a/apps/meteor/definition/IRoomTypeConfig.ts +++ b/apps/meteor/definition/IRoomTypeConfig.ts @@ -105,7 +105,8 @@ export interface IRoomTypeServerDirectives { sender: AtLeast, notificationMessage: string, userId: string, - ) => Promise<{ title: string | undefined; text: string; name: string | undefined }>; + language?: string, + ) => Promise<{ title?: string; text: string; name?: string }>; getMsgSender: (message: IMessage) => Promise; includeInRoomSearch: () => boolean; getReadReceiptsExtraData: (message: IMessage) => Partial; diff --git a/apps/meteor/server/lib/rooms/buildNotificationDetails.spec.ts b/apps/meteor/server/lib/rooms/buildNotificationDetails.spec.ts new file mode 100644 index 0000000000000..ec37119b7d2a1 --- /dev/null +++ b/apps/meteor/server/lib/rooms/buildNotificationDetails.spec.ts @@ -0,0 +1,97 @@ +import { expect } from 'chai'; +import proxyquire from 'proxyquire'; +import sinon from 'sinon'; + +const getUserDisplayNameStub = sinon.stub(); +const i18nTranslateStub = sinon.stub(); + +const settingsGetStub = sinon.stub(); + +const { buildNotificationDetails } = proxyquire.noCallThru().load('./buildNotificationDetails.ts', { + '../../../app/settings/server': { + settings: { get: settingsGetStub }, + }, + '@rocket.chat/core-typings': { + getUserDisplayName: getUserDisplayNameStub, + }, + '../i18n': { + i18n: { t: i18nTranslateStub }, + }, +}); + +describe('buildNotificationDetails', () => { + const room = { name: 'general' }; + const sender = { _id: 'id1', name: 'Alice', username: 'alice' }; + + beforeEach(() => { + settingsGetStub.reset(); + getUserDisplayNameStub.reset(); + i18nTranslateStub.reset(); + }); + + const languageFallback = 'You_have_a_new_message'; + + const testCases = [ + { showPushMessage: true, showName: true, expectPrefix: true }, + { showPushMessage: true, showName: false, expectPrefix: false }, + { showPushMessage: false, showName: true, expectPrefix: false }, + { showPushMessage: false, showName: false, expectPrefix: false }, + ]; + + testCases.forEach(({ showPushMessage, showName, expectPrefix }) => { + const label = `Push_show_message=${showPushMessage}, Push_show_username_room=${showName}`; + + it(`should return correct fields when ${label}`, () => { + settingsGetStub.withArgs('Push_show_message').returns(showPushMessage); + settingsGetStub.withArgs('Push_show_username_room').returns(showName); + settingsGetStub.withArgs('UI_Use_Real_Name').returns(false); + settingsGetStub.withArgs('Language').returns('en'); + + const expectedMessage = 'Test message'; + const expectedTitle = 'Some Room Title'; + const senderDisplayName = 'Alice'; + + getUserDisplayNameStub.returns(senderDisplayName); + i18nTranslateStub.withArgs('You_have_a_new_message', { lng: 'en' }).returns(languageFallback); + + const result = buildNotificationDetails({ + expectedNotificationMessage: expectedMessage, + expectedTitle, + room, + sender, + language: undefined, + senderNameExpectedInMessage: true, + }); + + const shouldShowTitle = showName; + const shouldPrefix = showPushMessage && showName && expectPrefix; + + expect(result.title).to.equal(shouldShowTitle ? expectedTitle : undefined); + expect(result.name).to.equal(shouldShowTitle ? room.name : undefined); + + if (!showPushMessage) { + expect(result.text).to.equal(languageFallback); + } else if (shouldPrefix) { + expect(result.text).to.equal(`${senderDisplayName}: ${expectedMessage}`); + } else { + expect(result.text).to.equal(expectedMessage); + } + }); + }); + + it('should respect provided language if supplied', () => { + settingsGetStub.withArgs('Push_show_message').returns(false); + settingsGetStub.withArgs('Push_show_username_room').returns(false); + i18nTranslateStub.withArgs('You_have_a_new_message', { lng: 'fr' }).returns('Vous avez un nouveau message'); + + const result = buildNotificationDetails({ + expectedNotificationMessage: 'ignored', + room, + sender, + language: 'fr', + senderNameExpectedInMessage: false, + }); + + expect(result.text).to.equal('Vous avez un nouveau message'); + }); +}); diff --git a/apps/meteor/server/lib/rooms/buildNotificationDetails.ts b/apps/meteor/server/lib/rooms/buildNotificationDetails.ts new file mode 100644 index 0000000000000..61154b44685ce --- /dev/null +++ b/apps/meteor/server/lib/rooms/buildNotificationDetails.ts @@ -0,0 +1,64 @@ +import { getUserDisplayName } from '@rocket.chat/core-typings'; +import type { AtLeast, IRoom, IUser } from '@rocket.chat/core-typings'; + +import { settings } from '../../../app/settings/server'; +import { i18n } from '../i18n'; + +/** + * Options for building notification details. + */ +export type BuildNotificationDetailsOptions = { + /** The message to display for the notification. */ + expectedNotificationMessage: string; + /** The precomputed title for the notification. */ + expectedTitle?: string; + /** The room object with at least a name property. */ + room: AtLeast; + /** The user sending the notification. */ + sender: AtLeast; + /** Optional language code used for translation (defaults to server setting or 'en'). */ + language?: string; + /** Whether to prefix the message with senderName: (defaults to false). */ + senderNameExpectedInMessage?: boolean; +}; + +/** + * Builds the notification payload fields (title, text, name) based on settings and provided expectations. + * + * @param options - Precomputed values and context for the notification. + * @returns An object containing the notification title, text, and user/room label. + */ +export function buildNotificationDetails({ + expectedNotificationMessage, + expectedTitle, + room, + sender, + language, + senderNameExpectedInMessage = false, +}: BuildNotificationDetailsOptions): { title?: string; text: string; name?: string } { + const showPushMessage = settings.get('Push_show_message'); + const showUserOrRoomName = settings.get('Push_show_username_room'); + + let text: string; + if (showPushMessage) { + if (senderNameExpectedInMessage && showUserOrRoomName) { + const useRealName = settings.get('UI_Use_Real_Name'); + const senderName = getUserDisplayName(sender.name, sender.username, useRealName); + text = `${senderName}: ${expectedNotificationMessage}`; + } else { + text = expectedNotificationMessage; + } + } else { + const lng = language || settings.get('Language') || 'en'; + text = i18n.t('You_have_a_new_message', { lng }); + } + + let title: string | undefined; + let name: string | undefined; + if (showUserOrRoomName) { + name = room.name; + title = expectedTitle; + } + + return { title, text, name }; +} diff --git a/apps/meteor/server/lib/rooms/roomCoordinator.ts b/apps/meteor/server/lib/rooms/roomCoordinator.ts index 0f5ff97bdc213..e23a8c21053c6 100644 --- a/apps/meteor/server/lib/rooms/roomCoordinator.ts +++ b/apps/meteor/server/lib/rooms/roomCoordinator.ts @@ -1,8 +1,7 @@ -import { getUserDisplayName } from '@rocket.chat/core-typings'; import type { IRoom, RoomType, IUser, IMessage, ReadReceipt, ValueOf, AtLeast } from '@rocket.chat/core-typings'; import { Users } from '@rocket.chat/models'; -import { settings } from '../../../app/settings/server'; +import { buildNotificationDetails } from './buildNotificationDetails'; import type { IRoomTypeConfig, IRoomTypeServerDirectives, RoomSettingsEnum, RoomMemberActions } from '../../../definition/IRoomTypeConfig'; import { RoomCoordinator } from '../../../lib/rooms/coordinator'; @@ -41,14 +40,16 @@ class RoomCoordinatorServer extends RoomCoordinator { sender: AtLeast, notificationMessage: string, userId: string, - ): Promise<{ title: string | undefined; text: string; name: string | undefined }> { - const title = `#${await this.roomName(room, userId)}`; - const useRealName = settings.get('UI_Use_Real_Name'); - const senderName = getUserDisplayName(sender.name, sender.username, useRealName); - - const text = `${senderName}: ${notificationMessage}`; - - return { title, text, name: room.name }; + language?: string, + ) { + return buildNotificationDetails({ + expectedNotificationMessage: notificationMessage, + sender, + senderNameExpectedInMessage: true, + language, + expectedTitle: `#${await this.roomName(room, userId)}`, + room, + }); }, getMsgSender(message: IMessage): Promise { return Users.findOneById(message.u._id); diff --git a/apps/meteor/server/lib/rooms/roomTypes/direct.ts b/apps/meteor/server/lib/rooms/roomTypes/direct.ts index 4f28d93040e17..5fafff2a4f104 100644 --- a/apps/meteor/server/lib/rooms/roomTypes/direct.ts +++ b/apps/meteor/server/lib/rooms/roomTypes/direct.ts @@ -1,5 +1,5 @@ import type { AtLeast } from '@rocket.chat/core-typings'; -import { isRoomFederated } from '@rocket.chat/core-typings'; +import { getUserDisplayName, isRoomFederated } from '@rocket.chat/core-typings'; import { Subscriptions } from '@rocket.chat/models'; import { Meteor } from 'meteor/meteor'; @@ -8,6 +8,7 @@ import type { IRoomTypeServerDirectives } from '../../../../definition/IRoomType import { RoomSettingsEnum, RoomMemberActions } from '../../../../definition/IRoomTypeConfig'; import { getDirectMessageRoomType } from '../../../../lib/rooms/roomTypes/direct'; import { Federation } from '../../../services/federation/Federation'; +import { buildNotificationDetails } from '../buildNotificationDetails'; import { roomCoordinator } from '../roomCoordinator'; const DirectMessageRoomType = getDirectMessageRoomType(roomCoordinator); @@ -91,24 +92,19 @@ roomCoordinator.add(DirectMessageRoomType, { return (room?.uids?.length || 0) > 2; }, - async getNotificationDetails(room, sender, notificationMessage, userId) { + async getNotificationDetails(room, sender, notificationMessage, userId, language) { const useRealName = settings.get('UI_Use_Real_Name'); - const displayRoomName = await this.roomName(room, userId); - - if (this.isGroupChat(room)) { - return { - title: displayRoomName, - text: `${(useRealName && sender.name) || sender.username}: ${notificationMessage}`, - name: room.name || displayRoomName, - }; - } - - return { - title: (useRealName && sender.name) || sender.username, - text: notificationMessage, - name: room.name || displayRoomName, - }; + const senderDisplayName = getUserDisplayName(sender.name, sender.username, useRealName); + + return buildNotificationDetails({ + expectedNotificationMessage: notificationMessage, + room, + sender, + expectedTitle: this.isGroupChat(room) ? displayRoomName : senderDisplayName, + language, + senderNameExpectedInMessage: this.isGroupChat(room), + }); }, includeInDashboard() { diff --git a/apps/meteor/server/lib/rooms/roomTypes/livechat.ts b/apps/meteor/server/lib/rooms/roomTypes/livechat.ts index 7a00f75796c02..36285eb4b389f 100644 --- a/apps/meteor/server/lib/rooms/roomTypes/livechat.ts +++ b/apps/meteor/server/lib/rooms/roomTypes/livechat.ts @@ -5,6 +5,7 @@ import { LivechatVisitors, LivechatRooms } from '@rocket.chat/models'; import { RoomSettingsEnum, RoomMemberActions } from '../../../../definition/IRoomTypeConfig'; import type { IRoomTypeServerDirectives } from '../../../../definition/IRoomTypeConfig'; import { getLivechatRoomType } from '../../../../lib/rooms/roomTypes/livechat'; +import { buildNotificationDetails } from '../buildNotificationDetails'; import { roomCoordinator } from '../roomCoordinator'; const LivechatRoomType = getLivechatRoomType(roomCoordinator); @@ -31,12 +32,15 @@ roomCoordinator.add(LivechatRoomType, { return token && rid && !!(await LivechatRooms.findOneByIdAndVisitorToken(rid, token)); }, - async getNotificationDetails(room, _sender, notificationMessage, userId) { - const roomName = await this.roomName(room, userId); - const title = `[Omnichannel] ${roomName}`; - const text = notificationMessage; - - return { title, text, name: roomName }; + async getNotificationDetails(room, sender, notificationMessage, userId, language) { + return buildNotificationDetails({ + expectedNotificationMessage: notificationMessage, + sender, + room, + expectedTitle: `[Omnichannel] ${await this.roomName(room, userId)}`, + language, + senderNameExpectedInMessage: false, + }); }, async getMsgSender(message) { diff --git a/apps/meteor/server/lib/rooms/roomTypes/voip.ts b/apps/meteor/server/lib/rooms/roomTypes/voip.ts index c7cb26b476b48..3d908e7b56f85 100644 --- a/apps/meteor/server/lib/rooms/roomTypes/voip.ts +++ b/apps/meteor/server/lib/rooms/roomTypes/voip.ts @@ -3,6 +3,7 @@ import { Users } from '@rocket.chat/models'; import type { IRoomTypeServerDirectives } from '../../../../definition/IRoomTypeConfig'; import { getVoipRoomType } from '../../../../lib/rooms/roomTypes/voip'; +import { buildNotificationDetails } from '../buildNotificationDetails'; import { roomCoordinator } from '../roomCoordinator'; const VoipRoomType = getVoipRoomType(roomCoordinator); @@ -12,11 +13,15 @@ roomCoordinator.add(VoipRoomType, { return room.name || room.fname || (room as any).label; }, - async getNotificationDetails(room, _sender, notificationMessage, userId) { - const title = `[Omnichannel] ${this.roomName(room, userId)}`; - const text = notificationMessage; - - return { title, text, name: room.name }; + async getNotificationDetails(room, sender, notificationMessage, userId, language) { + return buildNotificationDetails({ + expectedNotificationMessage: notificationMessage, + room, + sender, + expectedTitle: `[Omnichannel] ${await this.roomName(room, userId)}`, + language, + senderNameExpectedInMessage: false, + }); }, async getMsgSender(message) {