From 0474935f7905bbda1414e1197678890181d91f1a Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 14 Jan 2026 09:32:08 -0600 Subject: [PATCH 1/4] adapt logs to object 3 --- .../classes/converters/MessageConverter.ts | 10 ++-- .../integrations/server/lib/triggerHandler.ts | 60 +++++++++++-------- .../app/livechat/server/lib/QueueManager.ts | 18 +++--- .../app/livechat/server/lib/RoutingManager.ts | 20 +++---- .../app/livechat/server/lib/closeRoom.ts | 28 ++++----- .../migrateVisitorIfMissingContact.ts | 2 +- .../lib/contacts/migrateVisitorToContactId.ts | 4 +- .../app/livechat/server/lib/custom-fields.ts | 4 +- .../app/livechat/server/lib/departmentsLib.ts | 2 +- apps/meteor/app/livechat/server/lib/guests.ts | 4 +- apps/meteor/app/livechat/server/lib/rooms.ts | 26 ++++---- .../app/livechat/server/lib/service-status.ts | 8 +-- .../app/livechat/server/lib/tracking.ts | 2 +- .../app/livechat/server/lib/transfer.ts | 8 +-- .../app/livechat/server/lib/webhooks.ts | 4 +- 15 files changed, 104 insertions(+), 96 deletions(-) diff --git a/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts b/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts index aa47be4434186..102593cb38452 100644 --- a/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts +++ b/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts @@ -42,7 +42,7 @@ export class MessageConverter extends RecordConverter { try { await Rooms.resetLastMessageById(rid, null); } catch (e) { - this._logger.warn(`Failed to update last message of room ${rid}`); + this._logger.warn({ msg: 'Failed to update last message of room', roomId: rid }); this._logger.error(e); } } @@ -55,7 +55,7 @@ export class MessageConverter extends RecordConverter { const creator = await this._cache.findImportedUser(data.u._id); if (!creator) { - this._logger.warn(`Imported user not found: ${data.u._id}`); + this._logger.warn({ msg: 'Imported user not found', userId: data.u._id }); throw new Error('importer-message-unknown-user'); } const rid = await this._cache.findImportedRoomId(data.rid); @@ -71,7 +71,7 @@ export class MessageConverter extends RecordConverter { try { await insertMessage(creator, msgObj as unknown as IDBMessage, rid, true); } catch (e) { - this._logger.warn(`Failed to import message with timestamp ${String(msgObj.ts)} to room ${rid}`); + this._logger.warn({ msg: 'Failed to import message', timestamp: String(msgObj.ts), roomId: rid }); this._logger.error(e); } } @@ -126,7 +126,7 @@ export class MessageConverter extends RecordConverter { const { name, _id } = (await this.getMentionedChannelData(importId)) || {}; if (!_id || !name) { - this._logger.warn(`Mentioned room not found: ${importId}`); + this._logger.warn({ msg: 'Mentioned room not found', importId }); continue; } @@ -162,7 +162,7 @@ export class MessageConverter extends RecordConverter { const data = await this._cache.findImportedUser(importId); if (!data) { - this._logger.warn(`Mentioned user not found: ${importId}`); + this._logger.warn({ msg: 'Mentioned user not found', importId }); continue; } diff --git a/apps/meteor/app/integrations/server/lib/triggerHandler.ts b/apps/meteor/app/integrations/server/lib/triggerHandler.ts index e3808da9ef8e9..1844f34b8a940 100644 --- a/apps/meteor/app/integrations/server/lib/triggerHandler.ts +++ b/apps/meteor/app/integrations/server/lib/triggerHandler.ts @@ -69,7 +69,7 @@ class RocketChatIntegrationHandler { } addIntegration(record: IOutgoingIntegration): void { - outgoingLogger.debug(`Adding the integration ${record.name} of the event ${record.event}!`); + outgoingLogger.debug({ msg: 'Adding integration', integrationName: record.name, event: record.event }); let channels = []; if (record.event && !outgoingEvents[record.event].use.channel) { outgoingLogger.debug('The integration doesnt rely on channels.'); @@ -79,7 +79,7 @@ class RocketChatIntegrationHandler { outgoingLogger.debug('The integration had an empty channel property, so it is going on all the public channels.'); channels = ['all_public_channels']; } else { - outgoingLogger.debug('The integration is going on these channels:', record.channel); + outgoingLogger.debug({ msg: 'The integration is going on these channels', channels: record.channel }); channels = ([] as string[]).concat(record.channel); } @@ -140,7 +140,7 @@ class RocketChatIntegrationHandler { } if (!user) { - outgoingLogger.error(`The user "${trigger.username}" doesn't exist, so we can't send the message.`); + outgoingLogger.error({ msg: 'Integration user not found', username: trigger.username }); return; } @@ -164,7 +164,7 @@ class RocketChatIntegrationHandler { return; } - outgoingLogger.debug(`Found a room for ${trigger.name} which is: ${tmpRoom.name} with a type of ${tmpRoom.t}`); + outgoingLogger.debug({ msg: 'Found room for integration', integrationName: trigger.name, roomName: tmpRoom.name, roomType: tmpRoom.t }); message.bot = { i: trigger._id }; @@ -233,13 +233,14 @@ class RocketChatIntegrationHandler { } break; default: - outgoingLogger.warn(`An Unhandled Trigger Event was called: ${argObject.event}`); + outgoingLogger.warn({ msg: 'Unhandled trigger event', event: argObject.event }); argObject.event = undefined; break; } outgoingLogger.debug({ - msg: `Got the event arguments for the event: ${argObject.event}`, + msg: 'Got the event arguments for the event', + event: argObject.event, messageId: argObject.message?._id, roomId: argObject.room?._id, userId: argObject.user?._id || argObject.owner?._id, @@ -264,7 +265,7 @@ class RocketChatIntegrationHandler { const ownerWithoutServicesField = owner?.services ? omitServicesField(owner) : owner; if (!room || !message) { - outgoingLogger.warn(`The integration ${event} was called but the room or message was not defined.`); + outgoingLogger.warn({ msg: 'Integration called without room or message', event }); return; } @@ -317,7 +318,7 @@ class RocketChatIntegrationHandler { break; case 'roomCreated': if (!owner) { - outgoingLogger.warn(`The integration ${event} was called but the owner was not defined.`); + outgoingLogger.warn({ msg: 'Integration called without owner data', event }); return; } data.channel_id = room._id; @@ -332,7 +333,7 @@ class RocketChatIntegrationHandler { case 'roomJoined': case 'roomLeft': if (!user) { - outgoingLogger.warn(`The integration ${event} was called but the owner was not defined.`); + outgoingLogger.warn({ msg: 'Integration called without owner data', event }); return; } data.timestamp = new Date(); @@ -349,7 +350,7 @@ class RocketChatIntegrationHandler { break; case 'userCreated': if (!user) { - outgoingLogger.warn(`The integration ${event} was called but the owner was not defined.`); + outgoingLogger.warn({ msg: 'Integration called without owner data', event }); return; } data.timestamp = user.createdAt; @@ -450,7 +451,7 @@ class RocketChatIntegrationHandler { return; } - outgoingLogger.debug(`Starting search for triggers for the room: ${room ? room._id : '__any'}`); + outgoingLogger.debug({ msg: 'Starting search for triggers for room', roomId: room ? room._id : '__any' }); const triggersToExecute = this.getTriggersToExecute(room, message); @@ -461,12 +462,15 @@ class RocketChatIntegrationHandler { } } - outgoingLogger.debug(`Found ${triggersToExecute.length} to iterate over and see if the match the event.`); + outgoingLogger.debug({ msg: 'Found triggers to iterate over', triggerCount: triggersToExecute.length, event }); for await (const triggerToExecute of triggersToExecute) { - outgoingLogger.debug( - `Is "${triggerToExecute.name}" enabled, ${triggerToExecute.enabled}, and what is the event? ${triggerToExecute.event}`, - ); + outgoingLogger.debug({ + msg: 'Checking trigger execution eligibility', + triggerName: triggerToExecute.name, + isEnabled: triggerToExecute.enabled, + triggerEvent: triggerToExecute.event, + }); if (triggerToExecute.enabled === true && triggerToExecute.event === event) { await this.executeTrigger(triggerToExecute, argObject); } @@ -495,11 +499,11 @@ class RocketChatIntegrationHandler { async executeTriggerUrl(url: string, trigger: IOutgoingIntegration, { event, message, room, owner, user }: ArgumentsObject, tries = 0) { if (!this.isTriggerEnabled(trigger)) { - outgoingLogger.warn(`The trigger "${trigger.name}" is no longer enabled, stopping execution of it at try: ${tries}`); + outgoingLogger.warn({ msg: 'Trigger is not enabled', triggerName: trigger.name, tries }); return; } - outgoingLogger.debug(`Starting to execute trigger: ${trigger.name} (${trigger._id})`); + outgoingLogger.debug({ msg: 'Starting to execute trigger', triggerName: trigger.name, triggerId: trigger._id }); let word; // Not all triggers/events support triggerWords @@ -517,14 +521,14 @@ class RocketChatIntegrationHandler { // Stop if there are triggerWords but none match if (!word) { - outgoingLogger.debug(`The trigger word which "${trigger.name}" was expecting could not be found, not executing.`); + outgoingLogger.debug({ msg: 'Trigger word not found', triggerName: trigger.name }); return; } } } if (message && message.editedAt && !trigger.runOnEdits) { - outgoingLogger.debug(`The trigger "${trigger.name}"'s run on edits is disabled and the message was edited.`); + outgoingLogger.debug({ msg: 'Trigger run on edits disabled and message was edited', triggerName: trigger.name }); return; } @@ -547,7 +551,7 @@ class RocketChatIntegrationHandler { this.mapEventArgsToData(data, { event, message, room, owner, user }); await updateHistory({ historyId, step: 'mapped-args-to-data', data, triggerWord: word }); - outgoingLogger.info(`Will be executing the Integration "${trigger.name}" to the url: ${url}`); + outgoingLogger.info({ msg: 'Will be executing integration', integrationName: trigger.name, url }); outgoingLogger.debug({ data }); const scriptEngine = this.getEngine(trigger); @@ -620,9 +624,9 @@ class RocketChatIntegrationHandler { .then(async (res) => { const content = await res.text(); if (!content) { - outgoingLogger.warn(`Result for the Integration ${trigger.name} to ${url} is empty`); + outgoingLogger.warn({ msg: 'Integration result is empty', integrationName: trigger.name, url }); } else { - outgoingLogger.info(`Status code for the Integration ${trigger.name} to ${url} is ${res.status}`); + outgoingLogger.info({ msg: 'Integration HTTP status', integrationName: trigger.name, url, status: res.status }); } const data = (() => { @@ -686,13 +690,15 @@ class RocketChatIntegrationHandler { if (!content || !this.successResults.includes(res.status)) { if (content) { outgoingLogger.error({ - msg: `Error for the Integration "${trigger.name}" to ${url}`, + msg: 'Error for integration request', + integrationName: trigger.name, + url, result: content, }); if (res.status === 410) { await updateHistory({ historyId, step: 'after-process-http-status-410', error: true }); - outgoingLogger.error(`Disabling the Integration "${trigger.name}" because the status code was 401 (Gone).`); + outgoingLogger.error({ msg: 'Disabling integration due to 401 status', integrationName: trigger.name }); await Integrations.updateOne({ _id: trigger._id }, { $set: { enabled: false } }); void notifyOnIntegrationChangedById(trigger._id); return; @@ -701,7 +707,9 @@ class RocketChatIntegrationHandler { if (res.status === 500) { await updateHistory({ historyId, step: 'after-process-http-status-500', error: true }); outgoingLogger.error({ - msg: `Error "500" for the Integration "${trigger.name}" to ${url}.`, + msg: 'Error 500 for integration request', + integrationName: trigger.name, + url, content, }); return; @@ -738,7 +746,7 @@ class RocketChatIntegrationHandler { return; } - outgoingLogger.info(`Trying the Integration ${trigger.name} to ${url} again in ${waitTime} milliseconds.`); + outgoingLogger.info({ msg: 'Retrying integration', integrationName: trigger.name, url, waitTime }); setTimeout(() => { void this.executeTriggerUrl(url, trigger, { event, message, room, owner, user }, tries + 1); }, waitTime); diff --git a/apps/meteor/app/livechat/server/lib/QueueManager.ts b/apps/meteor/app/livechat/server/lib/QueueManager.ts index 8e28c3334a828..c012a8a7d8a0b 100644 --- a/apps/meteor/app/livechat/server/lib/QueueManager.ts +++ b/apps/meteor/app/livechat/server/lib/QueueManager.ts @@ -195,7 +195,7 @@ export class QueueManager { await Promise.all([afterInquiryQueued(inquiry), afterRoomQueued(room)]); if (defaultAgent) { - logger.debug(`Setting default agent for inquiry ${inquiry._id} to ${defaultAgent.username}`); + logger.debug({ msg: 'Setting default agent for inquiry', inquiryId: inquiry._id, agentUsername: defaultAgent.username }); await LivechatInquiry.setDefaultAgentById(inquiry._id, defaultAgent); } @@ -225,7 +225,7 @@ export class QueueManager { }); if (!newRoom) { - logger.error(`Room with id ${room._id} not found after inquiry verification.`); + logger.error({ msg: 'Room not found after inquiry verification', roomId: room._id }); throw new Error('room-not-found'); } @@ -259,7 +259,7 @@ export class QueueManager { try { session.startTransaction(); const room = await createLivechatRoom(insertionRoom, session); - logger.debug(`Room for visitor ${guest._id} created with id ${room._id}`); + logger.debug({ msg: 'Room created for visitor', visitorId: guest._id, roomId: room._id }); const inquiry = await createLivechatInquiry({ rid, name: room.fname, @@ -301,7 +301,7 @@ export class QueueManager { agent?: SelectedAgent; extraData?: IOmnichannelRoomExtraData; }) { - logger.debug(`Requesting a room for guest ${guest._id}`); + logger.debug({ msg: 'Requesting room for guest', guestId: guest._id }); check( guest, Match.ObjectIncluding({ @@ -386,7 +386,7 @@ export class QueueManager { const newRoom = await LivechatRooms.findOneById(rid); if (!newRoom) { - logger.error(`Room with id ${rid} not found`); + logger.error({ msg: 'Room not found', roomId: rid }); throw new Error('room-not-found'); } @@ -427,11 +427,11 @@ export class QueueManager { return archivedRoom; } - logger.debug(`Attempting to unarchive room with id ${rid}`); + logger.debug({ msg: 'Attempting to unarchive room', roomId: rid }); const oldInquiry = await LivechatInquiry.findOneByRoomId>(rid, { projection: { _id: 1 } }); if (oldInquiry) { - logger.debug(`Removing old inquiry (${oldInquiry._id}) for room ${rid}`); + logger.debug({ msg: 'Removing old inquiry before unarchiving room', inquiryId: oldInquiry._id, roomId: rid }); await LivechatInquiry.removeByRoomId(rid); void notifyOnLivechatInquiryChangedById(oldInquiry._id, 'removed'); } @@ -467,7 +467,7 @@ export class QueueManager { } await this.requeueInquiry(inquiry, room, defaultAgent); - logger.debug(`Inquiry ${inquiry._id} queued`); + logger.debug({ msg: 'Inquiry queued', inquiryId: inquiry._id }); return room; } @@ -477,7 +477,7 @@ export class QueueManager { return; } - logger.debug(`Notifying agents of new inquiry ${inquiry._id} queued`); + logger.debug({ msg: 'Notifying agents of queued inquiry', inquiryId: inquiry._id }); const { department, rid, v } = inquiry; // Alert only the online agents of the queued request diff --git a/apps/meteor/app/livechat/server/lib/RoutingManager.ts b/apps/meteor/app/livechat/server/lib/RoutingManager.ts index ff91d04819846..3f49c43e89a3a 100644 --- a/apps/meteor/app/livechat/server/lib/RoutingManager.ts +++ b/apps/meteor/app/livechat/server/lib/RoutingManager.ts @@ -95,7 +95,7 @@ export const RoutingManager: Routing = { }, async getNextAgent(department, ignoreAgentId) { - logger.debug(`Getting next available agent with method ${settings.get('Livechat_Routing_Method')}`); + logger.debug({ msg: 'Getting next available agent with method', routingMethod: settings.get('Livechat_Routing_Method'), department, ignoreAgentId }); return this.getMethod().getNextAgent(department, ignoreAgentId); }, @@ -114,7 +114,7 @@ export const RoutingManager: Routing = { } if (!agent) { - logger.debug(`No agents available. Unable to delegate inquiry ${inquiry._id}`); + logger.debug({ msg: 'No agents available. Unable to delegate inquiry', inquiryId: inquiry._id }); // When an inqury reaches here on CE, it will stay here as 'ready' since on CE there's no mechanism to re queue it. // When reaching this point, managers have to manually transfer the inquiry to another room. This is expected. return LivechatRooms.findOneById(rid); @@ -141,7 +141,7 @@ export const RoutingManager: Routing = { const { rid, name, v, department } = inquiry; if (!(await createLivechatSubscription(rid, name, v, agent, department))) { - logger.debug(`Cannot assign agent to inquiry ${inquiry._id}: Cannot create subscription`); + logger.debug({ msg: 'Cannot assign agent to inquiry. Cannot create subscription', inquiryId: inquiry._id, agentId: agent.agentId }); throw new Meteor.Error('error-creating-subscription', 'Error creating subscription'); } @@ -157,7 +157,7 @@ export const RoutingManager: Routing = { await dispatchAgentDelegated(rid, agent.agentId); - logger.debug(`Agent ${agent.agentId} assigned to inquiry ${inquiry._id}. Instances notified`); + logger.debug({ msg: 'Agent assigned to inquiry. Instances notified', agentId: agent.agentId, inquiryId: inquiry._id }); return { inquiry, user }; }, @@ -176,7 +176,7 @@ export const RoutingManager: Routing = { }); if (!room?.open) { - logger.debug(`Cannot unassign agent from inquiry ${inquiry._id}: Room already closed`); + logger.debug({ msg: 'Cannot unassign agent from inquiry. Room already closed', inquiryId: inquiry._id }); return false; } @@ -243,12 +243,12 @@ export const RoutingManager: Routing = { const { _id, rid } = inquiry; if (!room?.open) { - logger.debug(`Cannot take Inquiry ${inquiry._id}: Room is closed`); + logger.debug({ msg: 'Cannot take inquiry. Room is closed', inquiryId: inquiry._id }); return room; } if (room.servedBy && room.servedBy._id === agent.agentId) { - logger.debug(`Cannot take Inquiry ${inquiry._id}: Already taken by agent ${room.servedBy._id}`); + logger.debug({ msg: 'Cannot take inquiry. Already taken by agent', inquiryId: inquiry._id, agentId: room.servedBy._id }); return room; } @@ -266,7 +266,7 @@ export const RoutingManager: Routing = { } if (!agent) { - logger.debug(`Cannot take Inquiry ${inquiry._id}: Precondition failed for agent`); + logger.debug({ msg: 'Cannot take inquiry. Precondition failed for agent', inquiryId: inquiry._id }); const cbRoom = await callbacks.run<'livechat.onAgentAssignmentFailed'>('livechat.onAgentAssignmentFailed', room, { inquiry, options, @@ -313,11 +313,11 @@ export const RoutingManager: Routing = { } if (transferData.userId) { - logger.debug(`Transfering room ${room._id} to user ${transferData.userId}`); + logger.debug({ msg: 'Transferring room to user', roomId: room._id, userId: transferData.userId }); return forwardRoomToAgent(room, transferData); } - logger.debug(`Unable to transfer room ${room._id}: No target provided`); + logger.debug({ msg: 'Unable to transfer room. No target provided', roomId: room._id }); return false; }, diff --git a/apps/meteor/app/livechat/server/lib/closeRoom.ts b/apps/meteor/app/livechat/server/lib/closeRoom.ts index 24770e40af29c..78bdb3887c30a 100644 --- a/apps/meteor/app/livechat/server/lib/closeRoom.ts +++ b/apps/meteor/app/livechat/server/lib/closeRoom.ts @@ -46,7 +46,7 @@ export async function closeRoom(params: CloseRoomParams, attempts = 2): Promise< // Dont propagate transaction errors if (shouldRetryTransaction(e)) { if (attempts > 0) { - logger.debug(`Retrying close room because of transient error. Attempts left: ${attempts}`); + logger.debug({ msg: 'Retrying close room because of transient error', attemptsLeft: attempts }); return closeRoom(params, attempts - 1); } @@ -77,7 +77,7 @@ async function afterRoomClosed( // And passing just _some_ actions to the transaction creates some deadlocks since messages are updated in the afterSaveMessages callbacks. const transcriptRequested = !!params.room.transcriptRequest || (!settings.get('Livechat_enable_transcript') && settings.get('Livechat_transcript_send_always')); - logger.debug(`Sending closing message to room ${newRoom._id}`); + logger.debug({ msg: 'Sending closing message to room', roomId: newRoom._id }); await Message.saveSystemMessageAndNotifyUser('livechat-close', newRoom._id, params.comment ?? '', chatCloser, { groupable: false, transcriptRequested, @@ -88,7 +88,7 @@ async function afterRoomClosed( await Message.saveSystemMessage('command', newRoom._id, 'promptTranscript', chatCloser); } - logger.debug(`Running callbacks for room ${newRoom._id}`); + logger.debug({ msg: 'Running callbacks for room', roomId: newRoom._id }); process.nextTick(() => { /** @@ -118,7 +118,7 @@ async function afterRoomClosed( void notifyOnLivechatInquiryChanged(inquiry, 'removed'); } - logger.debug(`Room ${newRoom._id} was closed`); + logger.debug({ msg: 'Room was closed', roomId: newRoom._id }); } async function doCloseRoom( @@ -128,9 +128,9 @@ async function doCloseRoom( const { comment } = params; const { room, forceClose } = params; - logger.debug({ msg: `Attempting to close room`, roomId: room._id, forceClose }); + logger.debug({ msg: 'Attempting to close room', roomId: room._id, forceClose }); if (!room || !isOmnichannelRoom(room) || (!forceClose && !room.open)) { - logger.debug(`Room ${room._id} is not open`); + logger.debug({ msg: 'Room is not open', roomId: room._id }); throw new Error('error-room-closed'); } @@ -140,7 +140,7 @@ async function doCloseRoom( } const { updatedOptions: options } = await resolveChatTags(room, params.options); - logger.debug(`Resolved chat tags for room ${room._id}`); + logger.debug({ msg: 'Resolved chat tags for room', roomId: room._id }); const now = new Date(); const { _id: rid, servedBy } = room; @@ -152,11 +152,11 @@ async function doCloseRoom( ...(serviceTimeDuration && { serviceTimeDuration }), ...options, }; - logger.debug(`Room ${room._id} was closed at ${closeData.closedAt} (duration ${closeData.chatDuration})`); + logger.debug({ msg: 'Room was closed', roomId: room._id, closedAt: closeData.closedAt, chatDuration: closeData.chatDuration }); if (isRoomClosedByUserParams(params)) { const { user } = params; - logger.debug(`Closing by user ${user?._id}`); + logger.debug({ msg: 'Closing by user', userId: user?._id }); closeData.closer = 'user'; closeData.closedBy = { _id: user?._id || '', @@ -164,7 +164,7 @@ async function doCloseRoom( }; } else if (isRoomClosedByVisitorParams(params)) { const { visitor } = params; - logger.debug(`Closing by visitor ${params.visitor._id}`); + logger.debug({ msg: 'Closing by visitor', visitorId: params.visitor._id }); closeData.closer = 'visitor'; closeData.closedBy = { _id: visitor._id, @@ -174,7 +174,7 @@ async function doCloseRoom( throw new Error('Error: Please provide details of the user or visitor who closed the room'); } - logger.debug(`Updating DB for room ${room._id} with close data`); + logger.debug({ msg: 'Updating DB for room with close data', roomId: room._id }); const inquiry = await LivechatInquiry.findOneByRoomId(rid, { session }); const removedInquiry = await LivechatInquiry.removeByRoomId(rid, { session }); @@ -204,7 +204,7 @@ async function doCloseRoom( } } - logger.debug(`DB updated for room ${room._id}`); + logger.debug({ msg: 'DB updated for room', roomId: room._id }); // Retrieve the closed room const newRoom = await LivechatRooms.findOneById(rid, { session }); @@ -220,7 +220,7 @@ async function resolveChatTags( room: IOmnichannelRoom, options: CloseRoomParams['options'] = {}, ): Promise<{ updatedOptions: CloseRoomParams['options'] }> { - logger.debug(`Resolving chat tags for room ${room._id}`); + logger.debug({ msg: 'Resolving chat tags for room', roomId: room._id }); const concatUnique = (...arrays: (string[] | undefined)[]): string[] => [ ...new Set(([] as string[]).concat(...arrays.filter((a): a is string[] => !!a))), @@ -281,7 +281,7 @@ async function resolveChatTags( } export async function closeOpenChats(userId: string, comment?: string) { - logger.debug(`Closing open chats for user ${userId}`); + logger.debug({ msg: 'Closing open chats for user', userId }); const user = await Users.findOneById(userId); const extraQuery = await applyDepartmentRestrictions({}, userId); diff --git a/apps/meteor/app/livechat/server/lib/contacts/migrateVisitorIfMissingContact.ts b/apps/meteor/app/livechat/server/lib/contacts/migrateVisitorIfMissingContact.ts index 852effa66370f..ba6851555130b 100644 --- a/apps/meteor/app/livechat/server/lib/contacts/migrateVisitorIfMissingContact.ts +++ b/apps/meteor/app/livechat/server/lib/contacts/migrateVisitorIfMissingContact.ts @@ -9,7 +9,7 @@ export async function migrateVisitorIfMissingContact( visitorId: ILivechatVisitor['_id'], source: IOmnichannelSource, ): Promise { - logger.debug(`Detecting visitor's contact ID`); + logger.debug({ msg: 'Detecting visitor contact ID' }); // Check if there is any contact already linking to this visitorId and source const contactId = await getContactIdByVisitor({ visitorId, source }); if (contactId) { diff --git a/apps/meteor/app/livechat/server/lib/contacts/migrateVisitorToContactId.ts b/apps/meteor/app/livechat/server/lib/contacts/migrateVisitorToContactId.ts index c0f8ad917d6f0..42be5926c5f2f 100644 --- a/apps/meteor/app/livechat/server/lib/contacts/migrateVisitorToContactId.ts +++ b/apps/meteor/app/livechat/server/lib/contacts/migrateVisitorToContactId.ts @@ -34,12 +34,12 @@ export async function migrateVisitorToContactId({ // Search for any contact that is not yet associated with any visitor and that have the same email or phone number as this visitor. const existingContact = await LivechatContacts.findContactMatchingVisitor(visitor); if (!existingContact) { - logger.debug(`Creating a new contact for existing visitor ${visitor._id}`); + logger.debug({ msg: 'Creating a new contact for existing visitor', visitorId: visitor._id }); return createContactFromVisitor(visitor, source); } // There is already an existing contact with no linked visitors and matching this visitor's phone or email, so let's use it - logger.debug(`Adding channel to existing contact ${existingContact._id}`); + logger.debug({ msg: 'Adding channel to existing contact', contactId: existingContact._id }); await ContactMerger.mergeVisitorIntoContact(visitor, existingContact, source); // Update all existing rooms matching the visitor id and source to set the contactId to them diff --git a/apps/meteor/app/livechat/server/lib/custom-fields.ts b/apps/meteor/app/livechat/server/lib/custom-fields.ts index 64d1776316c23..09cdc4f0b7d9a 100644 --- a/apps/meteor/app/livechat/server/lib/custom-fields.ts +++ b/apps/meteor/app/livechat/server/lib/custom-fields.ts @@ -59,7 +59,7 @@ export async function setCustomFields({ overwrite: boolean; token: string; }): Promise { - livechatLogger.debug(`Setting custom fields data for visitor with token ${token}`); + livechatLogger.debug({ msg: 'Setting custom fields data for visitor with token', token }); const customField = await LivechatCustomField.findOneById(key); if (!customField) { @@ -169,7 +169,7 @@ export async function setMultipleCustomFields({ overwrite: boolean; }[] > { - livechatLogger.debug(`Setting custom fields data for visitor with token ${visitor.token}`); + livechatLogger.debug({ msg: 'Setting custom fields data for visitor with token', token: visitor.token }); const keys = customFields.map((customField) => customField.key); const dbFields = await LivechatCustomField.find( diff --git a/apps/meteor/app/livechat/server/lib/departmentsLib.ts b/apps/meteor/app/livechat/server/lib/departmentsLib.ts index d6a8acc646315..0a0d46c8ba322 100644 --- a/apps/meteor/app/livechat/server/lib/departmentsLib.ts +++ b/apps/meteor/app/livechat/server/lib/departmentsLib.ts @@ -215,7 +215,7 @@ export async function setDepartmentForGuest({ visitorId, department }: { visitor } export async function removeDepartment(departmentId: string) { - livechatLogger.debug(`Removing department: ${departmentId}`); + livechatLogger.debug({ msg: 'Removing department', departmentId }); const department = await LivechatDepartment.findOneById>(departmentId, { projection: { _id: 1, businessHourId: 1, parentId: 1 }, diff --git a/apps/meteor/app/livechat/server/lib/guests.ts b/apps/meteor/app/livechat/server/lib/guests.ts index b4213d8211e91..1d0eb7dcb0406 100644 --- a/apps/meteor/app/livechat/server/lib/guests.ts +++ b/apps/meteor/app/livechat/server/lib/guests.ts @@ -48,7 +48,7 @@ export async function saveGuest( const customFields: Record = {}; if ((!userId || (await hasPermissionAsync(userId, 'edit-livechat-room-customfields'))) && Object.keys(livechatData).length) { - livechatLogger.debug({ msg: `Saving custom fields for visitor ${_id}`, livechatData }); + livechatLogger.debug({ msg: 'Saving custom fields for visitor', visitorId: _id, livechatData }); for await (const field of LivechatCustomField.findByScope('visitor')) { if (!livechatData.hasOwnProperty(field._id)) { continue; @@ -63,7 +63,7 @@ export async function saveGuest( customFields[field._id] = value; } updateData.livechatData = customFields; - livechatLogger.debug(`About to update ${Object.keys(customFields).length} custom fields for visitor ${_id}`); + livechatLogger.debug({ msg: 'About to update custom fields for visitor', visitorId: _id, customFieldCount: Object.keys(customFields).length }); } const ret = await LivechatVisitors.saveGuestById(_id, updateData); diff --git a/apps/meteor/app/livechat/server/lib/rooms.ts b/apps/meteor/app/livechat/server/lib/rooms.ts index 6a7beca8da944..a7921fcdb3560 100644 --- a/apps/meteor/app/livechat/server/lib/rooms.ts +++ b/apps/meteor/app/livechat/server/lib/rooms.ts @@ -54,7 +54,7 @@ export async function getRoom( if (!settings.get('Livechat_enabled')) { throw new Meteor.Error('error-omnichannel-is-disabled'); } - livechatLogger.debug(`Attempting to find or create a room for visitor ${guest._id}`); + livechatLogger.debug({ msg: 'Attempting to find or create a room for visitor', visitorId: guest._id }); const room = await LivechatRooms.findOneById(message.rid); if (room?.v._id && (await LivechatContacts.isChannelBlocked(Visitors.makeVisitorAssociation(room.v._id, room.source)))) { @@ -62,7 +62,7 @@ export async function getRoom( } if (!room?.open) { - livechatLogger.debug(`Last room for visitor ${guest._id} closed. Creating new one`); + livechatLogger.debug({ msg: 'Last room for visitor closed. Creating new one', visitorId: guest._id }); } if (!room?.open) { @@ -73,7 +73,7 @@ export async function getRoom( } if (room.v.token !== guest.token) { - livechatLogger.debug(`Visitor ${guest._id} trying to access another visitor's room`); + livechatLogger.debug({ msg: 'Visitor trying to access another visitor's room', visitorId: guest._id }); throw new Meteor.Error('cannot-access-room'); } @@ -111,16 +111,16 @@ export async function createRoom({ // if no department selected verify if there is at least one active and pick the first if (!defaultAgent && !visitor.department) { const department = await getRequiredDepartment(); - livechatLogger.debug(`No department or default agent selected for ${visitor._id}`); + livechatLogger.debug({ msg: 'No department or default agent selected for visitor', visitorId: visitor._id }); if (department) { - livechatLogger.debug(`Assigning ${visitor._id} to department ${department._id}`); + livechatLogger.debug({ msg: 'Assigning visitor to department', visitorId: visitor._id, departmentId: department._id }); visitor.department = department._id; } } // delegate room creation to QueueManager - livechatLogger.debug(`Calling QueueManager to request a room for visitor ${visitor._id}`); + livechatLogger.debug({ msg: 'Calling QueueManager to request a room for visitor', visitorId: visitor._id }); const room = await QueueManager.requestRoom({ guest: visitor, @@ -131,7 +131,7 @@ export async function createRoom({ extraData, }); - livechatLogger.debug(`Room obtained for visitor ${visitor._id} -> ${room._id}`); + livechatLogger.debug({ msg: 'Room obtained for visitor', visitorId: visitor._id, roomId: room._id }); await Messages.setRoomIdByToken(visitor.token, room._id); @@ -157,7 +157,7 @@ export async function saveRoomInfo( }, userId?: string, ) { - livechatLogger.debug(`Saving room information on room ${roomData._id}`); + livechatLogger.debug({ msg: 'Saving room information', roomId: roomData._id }); const { livechatData = {} } = roomData; const customFields: Record = {}; @@ -177,7 +177,7 @@ export async function saveRoomInfo( customFields[field._id] = value; } roomData.livechatData = customFields; - livechatLogger.debug(`About to update ${Object.keys(customFields).length} custom fields on room ${roomData._id}`); + livechatLogger.debug({ msg: 'About to update custom fields on room', roomId: roomData._id, customFieldCount: Object.keys(customFields).length }); } await LivechatRooms.saveRoomById(roomData); @@ -211,7 +211,7 @@ export async function saveRoomInfo( } export async function returnRoomAsInquiry(room: IOmnichannelRoom, departmentId?: string, overrideTransferData: Partial = {}) { - livechatLogger.debug({ msg: `Transfering room to ${departmentId ? 'department' : ''} queue`, room }); + livechatLogger.debug({ msg: 'Transferring room to queue', scope: departmentId ? 'department' : undefined, room }); if (!room.open) { throw new Meteor.Error('room-closed', 'Room closed'); } @@ -245,7 +245,7 @@ export async function returnRoomAsInquiry(room: IOmnichannelRoom, departmentId?: } const transferredBy = normalizeTransferredByData(user, room); - livechatLogger.debug(`Transfering room ${room._id} by user ${transferredBy._id}`); + livechatLogger.debug({ msg: 'Transferring room by user', roomId: room._id, transferredBy: transferredBy._id }); const transferData = { scope: 'queue' as const, departmentId, transferredBy, ...overrideTransferData }; try { await saveTransferHistory(room, transferData); @@ -261,7 +261,7 @@ export async function returnRoomAsInquiry(room: IOmnichannelRoom, departmentId?: } export async function removeOmnichannelRoom(rid: string) { - livechatLogger.debug(`Deleting room ${rid}`); + livechatLogger.debug({ msg: 'Deleting room', roomId: rid }); check(rid, String); const room = await LivechatRooms.findOneById(rid); if (!room) { @@ -299,7 +299,7 @@ export async function removeOmnichannelRoom(rid: string) { for (const r of result) { if (r.status === 'rejected') { - livechatLogger.error(`Error removing room ${rid}: ${r.reason}`); + livechatLogger.error({ msg: 'Error removing room', roomId: rid, err: r.reason }); throw new Meteor.Error('error-removing-room', 'Error removing room'); } } diff --git a/apps/meteor/app/livechat/server/lib/service-status.ts b/apps/meteor/app/livechat/server/lib/service-status.ts index fc57ff7817323..471ab72558dda 100644 --- a/apps/meteor/app/livechat/server/lib/service-status.ts +++ b/apps/meteor/app/livechat/server/lib/service-status.ts @@ -18,18 +18,18 @@ export async function getOnlineAgents(department?: string, agent?: SelectedAgent } export async function online(department?: string, skipNoAgentSetting = false, skipFallbackCheck = false): Promise { - livechatLogger.debug(`Checking online agents ${department ? `for department ${department}` : ''}`); + livechatLogger.debug({ msg: 'Checking online agents', department }); if (!skipNoAgentSetting && settings.get('Livechat_accept_chats_with_no_agents')) { livechatLogger.debug('Can accept without online agents: true'); return true; } if (settings.get('Livechat_assign_new_conversation_to_bot')) { - livechatLogger.debug(`Fetching online bot agents for department ${department}`); + livechatLogger.debug({ msg: 'Fetching online bot agents for department', department }); // get & count where doing the same, but get was getting data, while count was only counting. We only need the count here const botAgents = await countBotAgents(department); if (botAgents) { - livechatLogger.debug(`Found ${botAgents} online`); + livechatLogger.debug({ msg: 'Found online bot agents', botAgents }); if (botAgents > 0) { return true; } @@ -37,7 +37,7 @@ export async function online(department?: string, skipNoAgentSetting = false, sk } const agentsOnline = await checkOnlineAgents(department, undefined, skipFallbackCheck); - livechatLogger.debug(`Are online agents ${department ? `for department ${department}` : ''}?: ${agentsOnline}`); + livechatLogger.debug({ msg: 'Online agents status', department, agentsOnline }); return agentsOnline; } diff --git a/apps/meteor/app/livechat/server/lib/tracking.ts b/apps/meteor/app/livechat/server/lib/tracking.ts index bfbcf9912212e..ef42ff6661e53 100644 --- a/apps/meteor/app/livechat/server/lib/tracking.ts +++ b/apps/meteor/app/livechat/server/lib/tracking.ts @@ -39,7 +39,7 @@ export async function savePageHistory(token: string, roomId: string | undefined, }; if (!roomId) { - livechatLogger.warn(`Saving page history without room id for visitor with token ${token}`); + livechatLogger.warn({ msg: 'Saving page history without room id for visitor', token }); // keep history of unregistered visitors for 1 month const keepHistoryMiliseconds = 2592000000; extraData.expireAt = new Date().getTime() + keepHistoryMiliseconds; diff --git a/apps/meteor/app/livechat/server/lib/transfer.ts b/apps/meteor/app/livechat/server/lib/transfer.ts index 74dcca09893ae..61d8af806c4ca 100644 --- a/apps/meteor/app/livechat/server/lib/transfer.ts +++ b/apps/meteor/app/livechat/server/lib/transfer.ts @@ -22,7 +22,7 @@ export async function saveTransferHistory(room: IOmnichannelRoom, transferData: const { _id, username } = transferredBy; const scopeData = scope || (nextDepartment ? 'department' : 'agent'); - livechatLogger.info(`Storing new chat transfer of ${room._id} [Transfered by: ${_id} to ${scopeData}]`); + livechatLogger.info({ msg: 'Storing new chat transfer', roomId: room._id, transferredBy: _id, scope: scopeData }); const transferMessage = { ...(transferData.transferredBy.userType === 'visitor' && { token: room.v.token }), @@ -41,7 +41,7 @@ export async function saveTransferHistory(room: IOmnichannelRoom, transferData: } export async function forwardOpenChats(userId: string) { - livechatLogger.debug(`Transferring open chats for user ${userId}`); + livechatLogger.debug({ msg: 'Transferring open chats for user', userId }); const user = await Users.findOneById(userId); if (!user) { throw new Error('error-invalid-user'); @@ -63,7 +63,7 @@ export async function forwardOpenChats(userId: string) { } export async function transfer(room: IOmnichannelRoom, guest: ILivechatVisitor, transferData: TransferData) { - livechatLogger.debug(`Transfering room ${room._id} [Transfered by: ${transferData?.transferredBy?._id}]`); + livechatLogger.debug({ msg: 'Transferring room', roomId: room._id, transferredBy: transferData?.transferredBy?._id }); if (room.onHold) { throw new Error('error-room-onHold'); } @@ -77,7 +77,7 @@ export async function transfer(room: IOmnichannelRoom, guest: ILivechatVisitor, } transferData.department = department; - livechatLogger.debug(`Transfering room ${room._id} to department ${transferData.department?._id}`); + livechatLogger.debug({ msg: 'Transferring room to department', roomId: room._id, departmentId: transferData.department?._id }); } return RoutingManager.transferRoom(room, guest, transferData); diff --git a/apps/meteor/app/livechat/server/lib/webhooks.ts b/apps/meteor/app/livechat/server/lib/webhooks.ts index 25af2060c470d..04cada08bf59e 100644 --- a/apps/meteor/app/livechat/server/lib/webhooks.ts +++ b/apps/meteor/app/livechat/server/lib/webhooks.ts @@ -37,7 +37,7 @@ export async function sendRequest( if (!isRetryable(result.status)) { webhooksLogger.error({ - msg: `Non-retryable error response from webhook`, + msg: 'Non-retryable error response from webhook', webhookUrl, status: result.status, response: await result.text(), @@ -50,7 +50,7 @@ export async function sendRequest( throw new Error(await result.text()); } catch (err) { const retryAfter = timeout * 4; - webhooksLogger.debug({ msg: `Error response on ${6 - attempts} try ->`, err, newAttemptAfterSeconds: retryAfter / 1000, webhookUrl }); + webhooksLogger.debug({ msg: 'Error response on retry', attempt: 6 - attempts, err, newAttemptAfterSeconds: retryAfter / 1000, webhookUrl }); const remainingAttempts = attempts - 1; // try 5 times after 20 seconds each if (!remainingAttempts) { From 739fa62d3835cb3bb6bd16a8527ecd754a027362 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 14 Jan 2026 10:00:12 -0600 Subject: [PATCH 2/4] lint --- apps/meteor/app/integrations/server/lib/triggerHandler.ts | 8 ++++---- apps/meteor/app/livechat/server/lib/RoutingManager.ts | 7 ++++++- apps/meteor/app/livechat/server/lib/guests.ts | 6 +++++- apps/meteor/app/livechat/server/lib/rooms.ts | 8 ++++++-- apps/meteor/app/livechat/server/lib/webhooks.ts | 8 +++++++- 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/apps/meteor/app/integrations/server/lib/triggerHandler.ts b/apps/meteor/app/integrations/server/lib/triggerHandler.ts index 1844f34b8a940..a610085713781 100644 --- a/apps/meteor/app/integrations/server/lib/triggerHandler.ts +++ b/apps/meteor/app/integrations/server/lib/triggerHandler.ts @@ -691,8 +691,8 @@ class RocketChatIntegrationHandler { if (content) { outgoingLogger.error({ msg: 'Error for integration request', - integrationName: trigger.name, - url, + integrationName: trigger.name, + url, result: content, }); @@ -708,8 +708,8 @@ class RocketChatIntegrationHandler { await updateHistory({ historyId, step: 'after-process-http-status-500', error: true }); outgoingLogger.error({ msg: 'Error 500 for integration request', - integrationName: trigger.name, - url, + integrationName: trigger.name, + url, content, }); return; diff --git a/apps/meteor/app/livechat/server/lib/RoutingManager.ts b/apps/meteor/app/livechat/server/lib/RoutingManager.ts index 3f49c43e89a3a..ce8b9bb3d0da7 100644 --- a/apps/meteor/app/livechat/server/lib/RoutingManager.ts +++ b/apps/meteor/app/livechat/server/lib/RoutingManager.ts @@ -95,7 +95,12 @@ export const RoutingManager: Routing = { }, async getNextAgent(department, ignoreAgentId) { - logger.debug({ msg: 'Getting next available agent with method', routingMethod: settings.get('Livechat_Routing_Method'), department, ignoreAgentId }); + logger.debug({ + msg: 'Getting next available agent with method', + routingMethod: settings.get('Livechat_Routing_Method'), + department, + ignoreAgentId, + }); return this.getMethod().getNextAgent(department, ignoreAgentId); }, diff --git a/apps/meteor/app/livechat/server/lib/guests.ts b/apps/meteor/app/livechat/server/lib/guests.ts index 1d0eb7dcb0406..f913ef83c05d6 100644 --- a/apps/meteor/app/livechat/server/lib/guests.ts +++ b/apps/meteor/app/livechat/server/lib/guests.ts @@ -63,7 +63,11 @@ export async function saveGuest( customFields[field._id] = value; } updateData.livechatData = customFields; - livechatLogger.debug({ msg: 'About to update custom fields for visitor', visitorId: _id, customFieldCount: Object.keys(customFields).length }); + livechatLogger.debug({ + msg: 'About to update custom fields for visitor', + visitorId: _id, + customFieldCount: Object.keys(customFields).length, + }); } const ret = await LivechatVisitors.saveGuestById(_id, updateData); diff --git a/apps/meteor/app/livechat/server/lib/rooms.ts b/apps/meteor/app/livechat/server/lib/rooms.ts index a7921fcdb3560..a4b6d0dbc22b6 100644 --- a/apps/meteor/app/livechat/server/lib/rooms.ts +++ b/apps/meteor/app/livechat/server/lib/rooms.ts @@ -73,7 +73,7 @@ export async function getRoom( } if (room.v.token !== guest.token) { - livechatLogger.debug({ msg: 'Visitor trying to access another visitor's room', visitorId: guest._id }); + livechatLogger.debug({ msg: 'Visitor trying to access another visitor room', visitorId: guest._id }); throw new Meteor.Error('cannot-access-room'); } @@ -177,7 +177,11 @@ export async function saveRoomInfo( customFields[field._id] = value; } roomData.livechatData = customFields; - livechatLogger.debug({ msg: 'About to update custom fields on room', roomId: roomData._id, customFieldCount: Object.keys(customFields).length }); + livechatLogger.debug({ + msg: 'About to update custom fields on room', + roomId: roomData._id, + customFieldCount: Object.keys(customFields).length, + }); } await LivechatRooms.saveRoomById(roomData); diff --git a/apps/meteor/app/livechat/server/lib/webhooks.ts b/apps/meteor/app/livechat/server/lib/webhooks.ts index 04cada08bf59e..e973484fe57e1 100644 --- a/apps/meteor/app/livechat/server/lib/webhooks.ts +++ b/apps/meteor/app/livechat/server/lib/webhooks.ts @@ -50,7 +50,13 @@ export async function sendRequest( throw new Error(await result.text()); } catch (err) { const retryAfter = timeout * 4; - webhooksLogger.debug({ msg: 'Error response on retry', attempt: 6 - attempts, err, newAttemptAfterSeconds: retryAfter / 1000, webhookUrl }); + webhooksLogger.debug({ + msg: 'Error response on retry', + attempt: 6 - attempts, + err, + newAttemptAfterSeconds: retryAfter / 1000, + webhookUrl, + }); const remainingAttempts = attempts - 1; // try 5 times after 20 seconds each if (!remainingAttempts) { From fd2a2b7f355a0c6c0871ebb60cee0cd130b95b5e Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 14 Jan 2026 10:38:11 -0600 Subject: [PATCH 3/4] 410 --- apps/meteor/app/integrations/server/lib/triggerHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/app/integrations/server/lib/triggerHandler.ts b/apps/meteor/app/integrations/server/lib/triggerHandler.ts index a610085713781..0a29396ec2c32 100644 --- a/apps/meteor/app/integrations/server/lib/triggerHandler.ts +++ b/apps/meteor/app/integrations/server/lib/triggerHandler.ts @@ -698,7 +698,7 @@ class RocketChatIntegrationHandler { if (res.status === 410) { await updateHistory({ historyId, step: 'after-process-http-status-410', error: true }); - outgoingLogger.error({ msg: 'Disabling integration due to 401 status', integrationName: trigger.name }); + outgoingLogger.error({ msg: 'Disabling integration due to 410 (Gone) status', integrationName: trigger.name }); await Integrations.updateOne({ _id: trigger._id }, { $set: { enabled: false } }); void notifyOnIntegrationChangedById(trigger._id); return; From 7fdc1f5fc42982a16248c1ffc22d75eed6cb01fc Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 14 Jan 2026 12:35:09 -0600 Subject: [PATCH 4/4] Apply suggestion from @sampaiodiego Co-authored-by: Diego Sampaio --- .../app/importer/server/classes/converters/MessageConverter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts b/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts index 102593cb38452..8fa9eaba04534 100644 --- a/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts +++ b/apps/meteor/app/importer/server/classes/converters/MessageConverter.ts @@ -71,7 +71,7 @@ export class MessageConverter extends RecordConverter { try { await insertMessage(creator, msgObj as unknown as IDBMessage, rid, true); } catch (e) { - this._logger.warn({ msg: 'Failed to import message', timestamp: String(msgObj.ts), roomId: rid }); + this._logger.warn({ msg: 'Failed to import message', timestamp: msgObj.ts, roomId: rid }); this._logger.error(e); } }