From 53cf1f5940c76e6d4df132e3ca8e7118206d1ea5 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Thu, 19 Oct 2023 19:25:00 -0600 Subject: [PATCH] refactor: Move functions out of `livechat.js` (#30664) --- .../app/apps/server/bridges/livechat.ts | 2 +- .../app/livechat/imports/server/rest/sms.js | 2 +- .../app/livechat/server/api/v1/message.ts | 16 +- .../app/livechat/server/api/v1/visitor.ts | 2 +- apps/meteor/app/livechat/server/lib/Helper.ts | 6 +- .../app/livechat/server/lib/Livechat.js | 191 +--------------- .../app/livechat/server/lib/LivechatTyped.ts | 207 +++++++++++++++++- .../server/methods/returnAsInquiry.ts | 4 +- .../server/methods/sendMessageLivechat.ts | 28 +-- apps/meteor/app/livechat/server/startup.ts | 10 +- .../server/lib/AutoTransferChatScheduler.ts | 4 +- .../EmailInbox/EmailInbox_Incoming.ts | 3 +- 12 files changed, 238 insertions(+), 237 deletions(-) diff --git a/apps/meteor/app/apps/server/bridges/livechat.ts b/apps/meteor/app/apps/server/bridges/livechat.ts index 5b6c76257667..70802f280095 100644 --- a/apps/meteor/app/apps/server/bridges/livechat.ts +++ b/apps/meteor/app/apps/server/bridges/livechat.ts @@ -44,7 +44,7 @@ export class AppLivechatBridge extends LivechatBridge { throw new Error('Invalid token for livechat message'); } - const msg = await Livechat.sendMessage({ + const msg = await LivechatTyped.sendMessage({ guest: this.orch.getConverters()?.get('visitors').convertAppVisitor(message.visitor), message: await this.orch.getConverters()?.get('messages').convertAppMessage(message), agent: undefined, diff --git a/apps/meteor/app/livechat/imports/server/rest/sms.js b/apps/meteor/app/livechat/imports/server/rest/sms.js index 7ecb3b3fc100..9d2bee133784 100644 --- a/apps/meteor/app/livechat/imports/server/rest/sms.js +++ b/apps/meteor/app/livechat/imports/server/rest/sms.js @@ -182,7 +182,7 @@ API.v1.addRoute('livechat/sms-incoming/:service', { }; try { - const msg = SMSService.response.call(this, await Livechat.sendMessage(sendMessage)); + const msg = SMSService.response.call(this, await LivechatTyped.sendMessage(sendMessage)); setImmediate(async () => { if (sms.extra) { if (sms.extra.fromCountry) { diff --git a/apps/meteor/app/livechat/server/api/v1/message.ts b/apps/meteor/app/livechat/server/api/v1/message.ts index 0d5a22b90d89..1dcf54e403a6 100644 --- a/apps/meteor/app/livechat/server/api/v1/message.ts +++ b/apps/meteor/app/livechat/server/api/v1/message.ts @@ -17,7 +17,6 @@ import { isWidget } from '../../../../api/server/helpers/isWidget'; import { loadMessageHistory } from '../../../../lib/server/functions/loadMessageHistory'; import { settings } from '../../../../settings/server'; import { normalizeMessageFileUpload } from '../../../../utils/server/functions/normalizeMessageFileUpload'; -import { Livechat } from '../../lib/Livechat'; import { Livechat as LivechatTyped } from '../../lib/LivechatTyped'; import { findGuest, findRoom, normalizeHttpHeaderData } from '../lib/livechat'; @@ -67,7 +66,7 @@ API.v1.addRoute( }, }; - const result = await Livechat.sendMessage(sendMessage); + const result = await LivechatTyped.sendMessage(sendMessage); if (result) { const message = await Messages.findOneById(_id); if (!message) { @@ -176,7 +175,7 @@ API.v1.addRoute( throw new Error('invalid-message'); } - const result = await Livechat.deleteMessage({ guest, message }); + const result = await LivechatTyped.deleteMessage({ guest, message }); if (result) { return API.v1.success({ message: { @@ -272,10 +271,15 @@ API.v1.addRoute( visitor = await LivechatVisitors.findOneEnabledById(visitorId); } + const guest = visitor; + if (!guest) { + throw new Error('error-invalid-token'); + } + const sentMessages = await Promise.all( this.bodyParams.messages.map(async (message: { msg: string }): Promise<{ username: string; msg: string; ts: number }> => { const sendMessage = { - guest: visitor, + guest, message: { _id: Random.id(), rid, @@ -288,8 +292,8 @@ API.v1.addRoute( }, }, }; - // @ts-expect-error -- Typings on sendMessage are wrong - const sentMessage = await Livechat.sendMessage(sendMessage); + + const sentMessage = await LivechatTyped.sendMessage(sendMessage); return { username: sentMessage.u.username, msg: sentMessage.msg, diff --git a/apps/meteor/app/livechat/server/api/v1/visitor.ts b/apps/meteor/app/livechat/server/api/v1/visitor.ts index 84f7b96e155d..6488d34eab7a 100644 --- a/apps/meteor/app/livechat/server/api/v1/visitor.ts +++ b/apps/meteor/app/livechat/server/api/v1/visitor.ts @@ -121,7 +121,7 @@ API.v1.addRoute('livechat/visitor/:token', { } const { _id } = visitor; - const result = await Livechat.removeGuest(_id); + const result = await LivechatTyped.removeGuest(_id); if (!result.modifiedCount) { throw new Meteor.Error('error-removing-visitor', 'An error ocurred while deleting visitor'); } diff --git a/apps/meteor/app/livechat/server/lib/Helper.ts b/apps/meteor/app/livechat/server/lib/Helper.ts index 63cbbd6998ef..4acbdf5090ad 100644 --- a/apps/meteor/app/livechat/server/lib/Helper.ts +++ b/apps/meteor/app/livechat/server/lib/Helper.ts @@ -437,7 +437,7 @@ export const forwardRoomToAgent = async (room: IOmnichannelRoom, transferData: T return false; } - await Livechat.saveTransferHistory(room, transferData); + await LivechatTyped.saveTransferHistory(room, transferData); const { servedBy } = roomTaken; if (servedBy) { @@ -537,7 +537,7 @@ export const forwardRoomToDepartment = async (room: IOmnichannelRoom, guest: ILi logger.debug( `Routing algorithm doesn't support auto assignment (using ${RoutingManager.methodName}). Chat will be on department queue`, ); - await Livechat.saveTransferHistory(room, transferData); + await LivechatTyped.saveTransferHistory(room, transferData); return RoutingManager.unassignAgent(inquiry, departmentId); } @@ -573,7 +573,7 @@ export const forwardRoomToDepartment = async (room: IOmnichannelRoom, guest: ILi } } - await Livechat.saveTransferHistory(room, transferData); + await LivechatTyped.saveTransferHistory(room, transferData); if (oldServedBy) { // if chat is queued then we don't ignore the new servedBy agent bcs at this // point the chat is not assigned to him/her and it is still in the queue diff --git a/apps/meteor/app/livechat/server/lib/Livechat.js b/apps/meteor/app/livechat/server/lib/Livechat.js index 837a8eb7309b..b208c9fb5e85 100644 --- a/apps/meteor/app/livechat/server/lib/Livechat.js +++ b/apps/meteor/app/livechat/server/lib/Livechat.js @@ -8,11 +8,9 @@ import { LivechatRooms, LivechatInquiry, Subscriptions, - Messages, LivechatDepartment as LivechatDepartmentRaw, Rooms, Users, - ReadReceipts, } from '@rocket.chat/models'; import { Match, check } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; @@ -25,15 +23,11 @@ import { i18n } from '../../../../server/lib/i18n'; import { addUserRolesAsync } from '../../../../server/lib/roles/addUserRoles'; import { removeUserFromRolesAsync } from '../../../../server/lib/roles/removeUserFromRoles'; import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission'; -import { FileUpload } from '../../../file-upload/server'; -import { deleteMessage } from '../../../lib/server/functions/deleteMessage'; -import { sendMessage } from '../../../lib/server/functions/sendMessage'; import * as Mailer from '../../../mailer/server/api'; import { settings } from '../../../settings/server'; import { businessHourManager } from '../business-hour'; import { Analytics } from './Analytics'; -import { normalizeTransferredByData, parseAgentCustomFields, updateDepartmentAgents } from './Helper'; -import { Livechat as LivechatTyped } from './LivechatTyped'; +import { parseAgentCustomFields, updateDepartmentAgents } from './Helper'; import { RoutingManager } from './RoutingManager'; const logger = new Logger('Livechat'); @@ -43,41 +37,6 @@ export const Livechat = { logger, - async sendMessage({ guest, message, roomInfo, agent }) { - const { room, newRoom } = await LivechatTyped.getRoom(guest, message, roomInfo, agent); - if (guest.name) { - message.alias = guest.name; - } - return Object.assign(await sendMessage(guest, message, room), { - newRoom, - showConnecting: this.showConnecting(), - }); - }, - - async deleteMessage({ guest, message }) { - Livechat.logger.debug(`Attempting to delete a message by visitor ${guest._id}`); - check(message, Match.ObjectIncluding({ _id: String })); - - const msg = await Messages.findOneById(message._id); - if (!msg || !msg._id) { - return; - } - - const deleteAllowed = settings.get('Message_AllowDeleting'); - const editOwn = msg.u && msg.u._id === guest._id; - - if (!deleteAllowed || !editOwn) { - Livechat.logger.debug('Cannot delete message: not allowed'); - throw new Meteor.Error('error-action-not-allowed', 'Message deleting not allowed', { - method: 'livechatDeleteMessage', - }); - } - - await deleteMessage(message, guest); - - return true; - }, - async saveGuest(guestData, userId) { const { _id, name, email, phone, livechatData = {} } = guestData; Livechat.logger.debug(`Saving data for visitor ${_id}`); @@ -234,111 +193,6 @@ export const Livechat = { return Message.saveSystemMessage('livechat_navigation_history', roomId, `${pageTitle} - ${pageUrl}`, user, extraData); }, - async saveTransferHistory(room, transferData) { - Livechat.logger.debug(`Saving transfer history for room ${room._id}`); - const { departmentId: previousDepartment } = room; - const { department: nextDepartment, transferredBy, transferredTo, scope, comment } = transferData; - - check( - transferredBy, - Match.ObjectIncluding({ - _id: String, - username: String, - name: Match.Maybe(String), - type: String, - }), - ); - - const { _id, username } = transferredBy; - const scopeData = scope || (nextDepartment ? 'department' : 'agent'); - Livechat.logger.debug(`Storing new chat transfer of ${room._id} [Transfered by: ${_id} to ${scopeData}]`); - - const transfer = { - transferData: { - transferredBy, - ts: new Date(), - scope: scopeData, - comment, - ...(previousDepartment && { previousDepartment }), - ...(nextDepartment && { nextDepartment }), - ...(transferredTo && { transferredTo }), - }, - }; - - const type = 'livechat_transfer_history'; - const transferMessage = { - t: type, - rid: room._id, - ts: new Date(), - msg: '', - u: { - _id, - username, - }, - groupable: false, - }; - - Object.assign(transferMessage, transfer); - - await sendMessage(transferredBy, transferMessage, room); - }, - - async returnRoomAsInquiry(rid, departmentId, overrideTransferData = {}) { - Livechat.logger.debug(`Transfering room ${rid} to ${departmentId ? 'department' : ''} queue`); - const room = await LivechatRooms.findOneById(rid); - if (!room) { - throw new Meteor.Error('error-invalid-room', 'Invalid room', { - method: 'livechat:returnRoomAsInquiry', - }); - } - - if (!room.open) { - throw new Meteor.Error('room-closed', 'Room closed', { - method: 'livechat:returnRoomAsInquiry', - }); - } - - if (room.onHold) { - throw new Meteor.Error('error-room-onHold', 'Room On Hold', { - method: 'livechat:returnRoomAsInquiry', - }); - } - - if (!room.servedBy) { - return false; - } - - const user = await Users.findOneById(room.servedBy._id); - if (!user || !user._id) { - throw new Meteor.Error('error-invalid-user', 'Invalid user', { - method: 'livechat:returnRoomAsInquiry', - }); - } - - // find inquiry corresponding to room - const inquiry = await LivechatInquiry.findOne({ rid }); - if (!inquiry) { - return false; - } - - const transferredBy = normalizeTransferredByData(user, room); - Livechat.logger.debug(`Transfering room ${room._id} by user ${transferredBy._id}`); - const transferData = { roomId: rid, scope: 'queue', departmentId, transferredBy, ...overrideTransferData }; - try { - await this.saveTransferHistory(room, transferData); - await RoutingManager.unassignAgent(inquiry, departmentId); - } catch (e) { - this.logger.error(e); - throw new Meteor.Error('error-returning-inquiry', 'Error returning inquiry to the queue', { - method: 'livechat:returnRoomAsInquiry', - }); - } - - callbacks.runAsync('livechat:afterReturnRoomAsInquiry', { room }); - - return true; - }, - async getLivechatRoomGuestInfo(room) { const visitor = await LivechatVisitors.findOneEnabledById(room.v._id); const agent = await Users.findOneById(room.servedBy && room.servedBy._id); @@ -481,55 +335,12 @@ export const Livechat = { return removeUserFromRolesAsync(user._id, ['livechat-manager']); }, - async removeGuest(_id) { - const guest = await LivechatVisitors.findOneEnabledById(_id, { projection: { _id: 1, token: 1 } }); - if (!guest) { - throw new Meteor.Error('error-invalid-guest', 'Invalid guest', { - method: 'livechat:removeGuest', - }); - } - - await this.cleanGuestHistory(guest); - return LivechatVisitors.disableById(_id); - }, - async setUserStatusLivechat(userId, status) { const user = await Users.setLivechatStatus(userId, status); callbacks.runAsync('livechat.setUserStatusLivechat', { userId, status }); return user; }, - async setUserStatusLivechatIf(userId, status, condition, fields) { - const user = await Users.setLivechatStatusIf(userId, status, condition, fields); - callbacks.runAsync('livechat.setUserStatusLivechat', { userId, status }); - return user; - }, - - async cleanGuestHistory(guest) { - const { token } = guest; - - // This shouldn't be possible, but just in case - if (!token) { - throw new Error('error-invalid-guest'); - } - - const extraQuery = await callbacks.run('livechat.applyRoomRestrictions', {}); - const cursor = LivechatRooms.findByVisitorToken(token, extraQuery); - for await (const room of cursor) { - await Promise.all([ - FileUpload.removeFilesByRoomId(room._id), - Messages.removeByRoomId(room._id), - ReadReceipts.removeByRoomId(room._id), - ]); - } - - await Promise.all([ - Subscriptions.removeByVisitorToken(token), - LivechatRooms.removeByVisitorToken(token), - LivechatInquiry.removeByVisitorToken(token), - ]); - }, - async saveDepartmentAgents(_id, departmentAgents) { check(_id, String); check(departmentAgents, { diff --git a/apps/meteor/app/livechat/server/lib/LivechatTyped.ts b/apps/meteor/app/livechat/server/lib/LivechatTyped.ts index 293b15e8d63c..32cb5c83acd9 100644 --- a/apps/meteor/app/livechat/server/lib/LivechatTyped.ts +++ b/apps/meteor/app/livechat/server/lib/LivechatTyped.ts @@ -15,6 +15,9 @@ import type { ILivechatDepartment, AtLeast, TransferData, + MessageAttachment, + IMessageInbox, + ILivechatAgentStatus, } from '@rocket.chat/core-typings'; import { UserStatus, isOmnichannelRoom } from '@rocket.chat/core-typings'; import { Logger, type MainLogger } from '@rocket.chat/logger'; @@ -34,13 +37,15 @@ import { import { Random } from '@rocket.chat/random'; import { serverFetch as fetch } from '@rocket.chat/server-fetch'; import moment from 'moment-timezone'; -import type { FindCursor, UpdateFilter } from 'mongodb'; +import type { Filter, FindCursor, UpdateFilter } from 'mongodb'; import { Apps, AppEvents } from '../../../../ee/server/apps'; import { callbacks } from '../../../../lib/callbacks'; import { i18n } from '../../../../server/lib/i18n'; import { canAccessRoomAsync } from '../../../authorization/server'; import { hasRoleAsync } from '../../../authorization/server/functions/hasRole'; +import { FileUpload } from '../../../file-upload/server'; +import { deleteMessage } from '../../../lib/server/functions/deleteMessage'; import { sendMessage } from '../../../lib/server/functions/sendMessage'; import { updateMessage } from '../../../lib/server/functions/updateMessage'; import * as Mailer from '../../../mailer/server/api'; @@ -89,6 +94,40 @@ type OfflineMessageData = { host?: string; }; +export interface ILivechatMessage { + token: string; + _id: string; + rid: string; + msg: string; + file?: { + _id: string; + name?: string; + type?: string; + size?: number; + description?: string; + identify?: { size: { width: number; height: number } }; + format?: string; + }; + files?: { + _id: string; + name?: string; + type?: string; + size?: number; + description?: string; + identify?: { size: { width: number; height: number } }; + format?: string; + }[]; + attachments?: MessageAttachment[]; + alias?: string; + groupable?: boolean; + blocks?: IMessage['blocks']; + email?: IMessageInbox['email']; +} + +type AKeyOf = { + [K in keyof T]?: T[K]; +}; + const dnsResolveMx = util.promisify(dns.resolveMx); class LivechatClass { @@ -1123,6 +1162,172 @@ class LivechatClass { void callbacks.run('livechat.offlineMessage', data); }); } + + async sendMessage({ + guest, + message, + roomInfo, + agent, + }: { + guest: ILivechatVisitor; + message: ILivechatMessage; + roomInfo: { + source?: IOmnichannelRoom['source']; + [key: string]: unknown; + }; + agent?: SelectedAgent; + }) { + const { room, newRoom } = await this.getRoom(guest, message, roomInfo, agent); + if (guest.name) { + message.alias = guest.name; + } + return Object.assign(await sendMessage(guest, message, room), { + newRoom, + showConnecting: this.showConnecting(), + }); + } + + async removeGuest(_id: string) { + const guest = await LivechatVisitors.findOneEnabledById(_id, { projection: { _id: 1, token: 1 } }); + if (!guest) { + throw new Error('error-invalid-guest'); + } + + await this.cleanGuestHistory(guest); + return LivechatVisitors.disableById(_id); + } + + async cleanGuestHistory(guest: ILivechatVisitor) { + const { token } = guest; + + // This shouldn't be possible, but just in case + if (!token) { + throw new Error('error-invalid-guest'); + } + + const cursor = LivechatRooms.findByVisitorToken(token); + for await (const room of cursor) { + await Promise.all([ + FileUpload.removeFilesByRoomId(room._id), + Messages.removeByRoomId(room._id), + ReadReceipts.removeByRoomId(room._id), + ]); + } + + await Promise.all([ + Subscriptions.removeByVisitorToken(token), + LivechatRooms.removeByVisitorToken(token), + LivechatInquiry.removeByVisitorToken(token), + ]); + } + + async deleteMessage({ guest, message }: { guest: ILivechatVisitor; message: IMessage }) { + const deleteAllowed = settings.get('Message_AllowDeleting'); + const editOwn = message.u && message.u._id === guest._id; + + if (!deleteAllowed || !editOwn) { + throw new Error('error-action-not-allowed'); + } + + await deleteMessage(message, guest as unknown as IUser); + + return true; + } + + async setUserStatusLivechatIf(userId: string, status: ILivechatAgentStatus, condition?: Filter, fields?: AKeyOf) { + const user = await Users.setLivechatStatusIf(userId, status, condition, fields); + callbacks.runAsync('livechat.setUserStatusLivechat', { userId, status }); + return user; + } + + async returnRoomAsInquiry(room: IOmnichannelRoom, departmentId?: string, overrideTransferData: any = {}) { + this.logger.debug({ msg: `Transfering room to ${departmentId ? 'department' : ''} queue`, room }); + if (!room.open) { + throw new Meteor.Error('room-closed'); + } + + if (room.onHold) { + throw new Meteor.Error('error-room-onHold'); + } + + if (!room.servedBy) { + return false; + } + + const user = await Users.findOneById(room.servedBy._id); + if (!user?._id) { + throw new Meteor.Error('error-invalid-user'); + } + + // find inquiry corresponding to room + const inquiry = await LivechatInquiry.findOne({ rid: room._id }); + if (!inquiry) { + return false; + } + + const transferredBy = normalizeTransferredByData(user, room); + this.logger.debug(`Transfering room ${room._id} by user ${transferredBy._id}`); + const transferData = { roomId: room._id, scope: 'queue', departmentId, transferredBy, ...overrideTransferData }; + try { + await this.saveTransferHistory(room, transferData); + await RoutingManager.unassignAgent(inquiry, departmentId); + } catch (e) { + this.logger.error(e); + throw new Meteor.Error('error-returning-inquiry'); + } + + callbacks.runAsync('livechat:afterReturnRoomAsInquiry', { room }); + + return true; + } + + async saveTransferHistory(room: IOmnichannelRoom, transferData: TransferData) { + const { departmentId: previousDepartment } = room; + const { department: nextDepartment, transferredBy, transferredTo, scope, comment } = transferData; + + check( + transferredBy, + Match.ObjectIncluding({ + _id: String, + username: String, + name: Match.Maybe(String), + type: String, + }), + ); + + const { _id, username } = transferredBy; + const scopeData = scope || (nextDepartment ? 'department' : 'agent'); + this.logger.info(`Storing new chat transfer of ${room._id} [Transfered by: ${_id} to ${scopeData}]`); + + const transfer = { + transferData: { + transferredBy, + ts: new Date(), + scope: scopeData, + comment, + ...(previousDepartment && { previousDepartment }), + ...(nextDepartment && { nextDepartment }), + ...(transferredTo && { transferredTo }), + }, + }; + + const type = 'livechat_transfer_history'; + const transferMessage = { + t: type, + rid: room._id, + ts: new Date(), + msg: '', + u: { + _id, + username, + }, + groupable: false, + }; + + Object.assign(transferMessage, transfer); + + await sendMessage(transferredBy, transferMessage, room); + } } export const Livechat = new LivechatClass(); diff --git a/apps/meteor/app/livechat/server/methods/returnAsInquiry.ts b/apps/meteor/app/livechat/server/methods/returnAsInquiry.ts index 57a2b0afa3d5..0c12d0df5275 100644 --- a/apps/meteor/app/livechat/server/methods/returnAsInquiry.ts +++ b/apps/meteor/app/livechat/server/methods/returnAsInquiry.ts @@ -4,7 +4,7 @@ import type { ServerMethods } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission'; -import { Livechat } from '../lib/Livechat'; +import { Livechat } from '../lib/LivechatTyped'; declare module '@rocket.chat/ui-contexts' { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -33,6 +33,6 @@ Meteor.methods({ throw new Meteor.Error('room-closed', 'Room closed', { method: 'livechat:returnAsInquiry' }); } - return Livechat.returnRoomAsInquiry(rid, departmentId); + return Livechat.returnRoomAsInquiry(room, departmentId); }, }); diff --git a/apps/meteor/app/livechat/server/methods/sendMessageLivechat.ts b/apps/meteor/app/livechat/server/methods/sendMessageLivechat.ts index c7d412ea4a06..516a9bc5081f 100644 --- a/apps/meteor/app/livechat/server/methods/sendMessageLivechat.ts +++ b/apps/meteor/app/livechat/server/methods/sendMessageLivechat.ts @@ -1,36 +1,12 @@ import { OmnichannelSourceType } from '@rocket.chat/core-typings'; -import type { MessageAttachment } from '@rocket.chat/core-typings'; import { LivechatVisitors } from '@rocket.chat/models'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; import { Match, check } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; import { settings } from '../../../settings/server'; -import { Livechat } from '../lib/Livechat'; - -interface ILivechatMessage { - token: string; - _id: string; - rid: string; - msg: string; - file?: { - _id: string; - name?: string; - type?: string; - size?: number; - description?: string; - identify?: { size: { width: number; height: number } }; - }; - files?: { - _id: string; - name?: string; - type?: string; - size?: number; - description?: string; - identify?: { size: { width: number; height: number } }; - }[]; - attachments?: MessageAttachment[]; -} +import { Livechat } from '../lib/LivechatTyped'; +import type { ILivechatMessage } from '../lib/LivechatTyped'; interface ILivechatMessageAgent { agentId: string; diff --git a/apps/meteor/app/livechat/server/startup.ts b/apps/meteor/app/livechat/server/startup.ts index f9fce509e39a..c8487f742b3a 100644 --- a/apps/meteor/app/livechat/server/startup.ts +++ b/apps/meteor/app/livechat/server/startup.ts @@ -1,5 +1,5 @@ import type { IUser } from '@rocket.chat/core-typings'; -import { isOmnichannelRoom } from '@rocket.chat/core-typings'; +import { ILivechatAgentStatus, isOmnichannelRoom } from '@rocket.chat/core-typings'; import { LivechatRooms } from '@rocket.chat/models'; import { Accounts } from 'meteor/accounts-base'; import { Meteor } from 'meteor/meteor'; @@ -13,6 +13,7 @@ import { settings } from '../../settings/server'; import { businessHourManager } from './business-hour'; import { createDefaultBusinessHourIfNotExists } from './business-hour/Helper'; import { Livechat } from './lib/Livechat'; +import { Livechat as LivechatTyped } from './lib/LivechatTyped'; import { RoutingManager } from './lib/RoutingManager'; import { LivechatAgentActivityMonitor } from './statistics/LivechatAgentActivityMonitor'; import './roomAccessValidator.internalService'; @@ -79,6 +80,11 @@ Meteor.startup(async () => { ({ user }: { user: IUser }) => user?.roles?.includes('livechat-agent') && !user?.roles?.includes('bot') && - void Livechat.setUserStatusLivechatIf(user._id, 'not-available', {}, { livechatStatusSystemModified: true }).catch(), + void LivechatTyped.setUserStatusLivechatIf( + user._id, + ILivechatAgentStatus.NOT_AVAILABLE, + {}, + { livechatStatusSystemModified: true }, + ).catch(), ); }); diff --git a/apps/meteor/ee/app/livechat-enterprise/server/lib/AutoTransferChatScheduler.ts b/apps/meteor/ee/app/livechat-enterprise/server/lib/AutoTransferChatScheduler.ts index 9d4590836ac9..68044a550277 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/lib/AutoTransferChatScheduler.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/lib/AutoTransferChatScheduler.ts @@ -5,8 +5,8 @@ import { LivechatRooms, Users } from '@rocket.chat/models'; import { Meteor } from 'meteor/meteor'; import { MongoInternals } from 'meteor/mongo'; -import { Livechat } from '../../../../../app/livechat/server'; import { forwardRoomToAgent } from '../../../../../app/livechat/server/lib/Helper'; +import { Livechat as LivechatTyped } from '../../../../../app/livechat/server/lib/LivechatTyped'; import { RoutingManager } from '../../../../../app/livechat/server/lib/RoutingManager'; import { settings } from '../../../../../app/settings/server'; import { schedulerLogger } from './logger'; @@ -90,7 +90,7 @@ class AutoTransferChatSchedulerClass { if (!RoutingManager.getConfig()?.autoAssignAgent) { this.logger.debug(`Auto-assign agent is disabled, returning room ${roomId} as inquiry`); - await Livechat.returnRoomAsInquiry(room._id, departmentId, { + await LivechatTyped.returnRoomAsInquiry(room, departmentId, { scope: 'autoTransferUnansweredChatsToQueue', comment: timeoutDuration, transferredBy: await this.getSchedulerUser(), diff --git a/apps/meteor/server/features/EmailInbox/EmailInbox_Incoming.ts b/apps/meteor/server/features/EmailInbox/EmailInbox_Incoming.ts index 939d91661650..ebdd9cdcac01 100644 --- a/apps/meteor/server/features/EmailInbox/EmailInbox_Incoming.ts +++ b/apps/meteor/server/features/EmailInbox/EmailInbox_Incoming.ts @@ -12,7 +12,6 @@ import type { ParsedMail, Attachment } from 'mailparser'; import stripHtml from 'string-strip-html'; import { FileUpload } from '../../../app/file-upload/server'; -import { Livechat } from '../../../app/livechat/server/lib/Livechat'; import { Livechat as LivechatTyped } from '../../../app/livechat/server/lib/LivechatTyped'; import { QueueManager } from '../../../app/livechat/server/lib/QueueManager'; import { settings } from '../../../app/settings/server'; @@ -148,7 +147,7 @@ export async function onEmailReceived(email: ParsedMail, inbox: string, departme const rid = room?._id ?? Random.id(); const msgId = Random.id(); - Livechat.sendMessage({ + LivechatTyped.sendMessage({ guest, message: { _id: msgId,