From 65e54c2b52abbb4a01f4e599ec0fb5c19d915e9d Mon Sep 17 00:00:00 2001 From: Murtaza Patrawala <34130764+murtaza98@users.noreply.github.com> Date: Fri, 22 Apr 2022 19:24:58 +0530 Subject: [PATCH] [FIX] Message preview not available for queued chats (#25092) Co-authored-by: Kevin Aleman --- .../app/apps/server/converters/messages.js | 26 +++++----- .../server/hooks/saveLastMessageToInquiry.ts | 35 ++++++++++++++ apps/meteor/app/livechat/server/index.js | 1 + .../app/models/server/raw/LivechatInquiry.ts | 8 +++- .../RoomList/SideBarItemTemplateWithData.js | 9 +++- packages/core-typings/src/IInquiry.ts | 48 ++++++++++--------- 6 files changed, 88 insertions(+), 39 deletions(-) create mode 100644 apps/meteor/app/livechat/server/hooks/saveLastMessageToInquiry.ts diff --git a/apps/meteor/app/apps/server/converters/messages.js b/apps/meteor/app/apps/server/converters/messages.js index 98ad0875dab..35d6daa4b46 100644 --- a/apps/meteor/app/apps/server/converters/messages.js +++ b/apps/meteor/app/apps/server/converters/messages.js @@ -120,24 +120,24 @@ export class AppMessagesConverter { const newMessage = { _id: message.id || Random.id(), - tmid: message.threadId, + ...('threadId' in message && { tmid: message.threadId }), rid: room._id, u, msg: message.text, ts: message.createdAt || new Date(), _updatedAt: message.updatedAt || new Date(), - editedBy, - editedAt: message.editedAt, - emoji: message.emoji, - avatar: message.avatarUrl, - alias: message.alias, - customFields: message.customFields, - groupable: message.groupable, - attachments, - reactions: message.reactions, - parseUrls: message.parseUrls, - blocks: message.blocks, - token: message.token, + ...(editedBy && { editedBy }), + ...('editedAt' in message && { editedAt: message.editedAt }), + ...('emoji' in message && { emoji: message.emoji }), + ...('avatarUrl' in message && { avatar: message.avatarUrl }), + ...('alias' in message && { alias: message.alias }), + ...('customFields' in message && { customFields: message.customFields }), + ...('groupable' in message && { groupable: message.groupable }), + ...(attachments && { attachments }), + ...('reactions' in message && { reactions: message.reactions }), + ...('parseUrls' in message && { parseUrls: message.parseUrls }), + ...('blocks' in message && { blocks: message.blocks }), + ...('token' in message && { token: message.token }), }; return Object.assign(newMessage, message._unmappedProperties_); diff --git a/apps/meteor/app/livechat/server/hooks/saveLastMessageToInquiry.ts b/apps/meteor/app/livechat/server/hooks/saveLastMessageToInquiry.ts new file mode 100644 index 00000000000..6372de15773 --- /dev/null +++ b/apps/meteor/app/livechat/server/hooks/saveLastMessageToInquiry.ts @@ -0,0 +1,35 @@ +import { isOmnichannelRoom, isEditedMessage } from '@rocket.chat/core-typings'; + +import { callbacks } from '../../../../lib/callbacks'; +import { LivechatInquiry } from '../../../models/server/raw'; +import { settings } from '../../../settings/server'; +import { RoutingManager } from '../lib/RoutingManager'; + +callbacks.add( + 'afterSaveMessage', + async (message, room) => { + if (!isOmnichannelRoom(room)) { + return message; + } + + // skip callback if message was edited + if (isEditedMessage(message)) { + return message; + } + + if (!RoutingManager.getConfig().showQueue) { + // since last message is only getting used on UI as preview message when queue is enabled + return message; + } + + if (!settings.get('Store_Last_Message')) { + return message; + } + + await LivechatInquiry.setLastMessageByRoomId(room._id, message); + + return message; + }, + callbacks.priority.LOW, + 'save-last-message-to-inquiry', +); diff --git a/apps/meteor/app/livechat/server/index.js b/apps/meteor/app/livechat/server/index.js index 389ec96013a..a6f03ba9c4d 100644 --- a/apps/meteor/app/livechat/server/index.js +++ b/apps/meteor/app/livechat/server/index.js @@ -19,6 +19,7 @@ import './hooks/saveLastVisitorMessageTs'; import './hooks/markRoomNotResponded'; import './hooks/sendTranscriptOnClose'; import './hooks/saveContactLastChat'; +import './hooks/saveLastMessageToInquiry'; import './methods/addAgent'; import './methods/addManager'; import './methods/changeLivechatStatus'; diff --git a/apps/meteor/app/models/server/raw/LivechatInquiry.ts b/apps/meteor/app/models/server/raw/LivechatInquiry.ts index 2f8baf7df73..4a39b54673e 100644 --- a/apps/meteor/app/models/server/raw/LivechatInquiry.ts +++ b/apps/meteor/app/models/server/raw/LivechatInquiry.ts @@ -1,5 +1,5 @@ -import { FindOneOptions, MongoDistinctPreferences } from 'mongodb'; -import { ILivechatInquiryRecord, LivechatInquiryStatus } from '@rocket.chat/core-typings'; +import { FindOneOptions, MongoDistinctPreferences, UpdateWriteOpResult } from 'mongodb'; +import { IMessage, ILivechatInquiryRecord, LivechatInquiryStatus } from '@rocket.chat/core-typings'; import { BaseRaw } from './BaseRaw'; @@ -30,4 +30,8 @@ export class LivechatInquiryRaw extends BaseRaw { const updated = await this.findOneAndUpdate({ _id: inquiryId }, { $set: { department } }, { returnDocument: 'after' }); return updated.value; } + + async setLastMessageByRoomId(rid: string, message: IMessage): Promise { + return this.updateOne({ rid }, { $set: { lastMessage: message } }); + } } diff --git a/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.js b/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.js index 41794bc8137..8efa329a377 100644 --- a/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.js +++ b/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.js @@ -117,6 +117,13 @@ function SideBarItemTemplateWithData({ ); } +function safeDateNotEqualCheck(a, b) { + if (!a || !b) { + return a !== b; + } + return new Date(a).toISOString() !== new Date(b).toISOString(); +} + const propsAreEqual = (prevProps, nextProps) => { if ( ['id', 'style', 'extended', 'selected', 'SideBarItemTemplate', 'AvatarTemplate', 't', 'sidebarViewMode'].some( @@ -136,7 +143,7 @@ const propsAreEqual = (prevProps, nextProps) => { if (prevProps.room._updatedAt?.toISOString() !== nextProps.room._updatedAt?.toISOString()) { return false; } - if (prevProps.room.lastMessage?._updatedAt?.toISOString() !== nextProps.room.lastMessage?._updatedAt?.toISOString()) { + if (safeDateNotEqualCheck(prevProps.lastMessage?._updatedAt, nextProps.lastMessage?._updatedAt)) { return false; } if (prevProps.room.alert !== nextProps.room.alert) { diff --git a/packages/core-typings/src/IInquiry.ts b/packages/core-typings/src/IInquiry.ts index bdf5e75ebe4..90cccbef6cf 100644 --- a/packages/core-typings/src/IInquiry.ts +++ b/packages/core-typings/src/IInquiry.ts @@ -1,35 +1,37 @@ -import type { IRocketChatRecord } from "./IRocketChatRecord"; +import type { IMessage } from './IMessage'; +import type { IRocketChatRecord } from './IRocketChatRecord'; export interface IInquiry { - _id: string; - _updatedAt?: Date; - department?: string; + _id: string; + _updatedAt?: Date; + department?: string; } export enum LivechatInquiryStatus { - QUEUED = "queued", - TAKEN = "taken", - READY = "ready", + QUEUED = 'queued', + TAKEN = 'taken', + READY = 'ready', } export interface IVisitor { - _id: string; - username: string; - token: string; - status: string; + _id: string; + username: string; + token: string; + status: string; } export interface ILivechatInquiryRecord extends IRocketChatRecord { - rid: string; - name: string; - ts: Date; - message: string; - status: LivechatInquiryStatus; - v: IVisitor; - t: "l"; - queueOrder: number; - estimatedWaitingTimeQueue: number; - estimatedServiceTimeAt: string; - department: string; - estimatedInactivityCloseTimeAt: Date; + rid: string; + name: string; + ts: Date; + message: string; + status: LivechatInquiryStatus; + v: IVisitor; + t: 'l'; + queueOrder: number; + estimatedWaitingTimeQueue: number; + estimatedServiceTimeAt: string; + department: string; + estimatedInactivityCloseTimeAt: Date; + lastMessage?: IMessage & { token?: string }; }