Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion apps/meteor/app/livechat/lib/messageTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,20 @@ MessageTypes.registerType({
...(comment && { comment }),
}),
queue: (): string =>
TAPi18n.__('Livechat_transfer_return_to_the_queue', {
TAPi18n.__(`Livechat_transfer_return_to_the_queue${commentLabel}`, {
from,
...(comment && { comment }),
}),
autoTransferUnansweredChatsToAgent: (): string =>
TAPi18n.__(`Livechat_transfer_to_agent_auto_transfer_unanswered_chat`, {
from,
to: message?.transferData?.transferredTo?.name || message?.transferData?.transferredTo?.username || '',
duration: comment,
}),
autoTransferUnansweredChatsToQueue: (): string =>
TAPi18n.__(`Livechat_transfer_return_to_the_queue_auto_transfer_unanswered_chat`, {
from,
duration: comment,
}),
};
return {
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/app/livechat/server/lib/Livechat.js
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ export const Livechat = {
return RoutingManager.transferRoom(room, guest, transferData);
},

returnRoomAsInquiry(rid, departmentId) {
returnRoomAsInquiry(rid, departmentId, overrideTransferData = {}) {
Livechat.logger.debug(`Transfering room ${rid} to ${departmentId ? 'department' : ''} queue`);
const room = LivechatRooms.findOneById(rid);
if (!room) {
Expand Down Expand Up @@ -791,7 +791,7 @@ export const Livechat = {

const transferredBy = normalizeTransferredByData(user, room);
Livechat.logger.debug(`Transfering room ${room._id} by user ${transferredBy._id}`);
const transferData = { roomId: rid, scope: 'queue', departmentId, transferredBy };
const transferData = { roomId: rid, scope: 'queue', departmentId, transferredBy, ...overrideTransferData };
try {
this.saveTransferHistory(room, transferData);
RoutingManager.unassignAgent(inquiry, departmentId);
Expand Down
39 changes: 0 additions & 39 deletions apps/meteor/app/models/server/models/LivechatRooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -835,45 +835,6 @@ export class LivechatRooms extends Base {
return this.update(query, update);
}

setAutoTransferredAtById(roomId) {
const query = {
_id: roomId,
};
const update = {
$set: {
autoTransferredAt: new Date(),
},
};

return this.update(query, update);
}

setAutoTransferOngoingById(roomId) {
const query = {
_id: roomId,
};
const update = {
$set: {
autoTransferOngoing: true,
},
};

return this.update(query, update);
}

unsetAutoTransferOngoingById(roomId) {
const query = {
_id: roomId,
};
const update = {
$unset: {
autoTransferOngoing: 1,
},
};

return this.update(query, update);
}

changeVisitorByRoomId(roomId, { _id, username, token }) {
const query = {
_id: roomId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const OmnichannelLivechatToggle = (): ReactElement => {

return (
<Sidebar.TopBar.Action
id={'omnichannel-status-toggle'}
data-tooltip={agentAvailable ? t('Turn_off_answer_chats') : t('Turn_on_answer_chats')}
color={agentAvailable ? 'success' : undefined}
icon={agentAvailable ? 'message' : 'message-disabled'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import { settings } from '../../../../../app/settings/server';
import { AutoCloseOnHoldScheduler } from '../lib/AutoCloseOnHoldScheduler';
import { cbLogger } from '../lib/logger';

const DEFAULT_CLOSED_MESSAGE = TAPi18n.__('Closed_automatically');

let autoCloseOnHoldChatTimeout = 0;
let customCloseMessage = DEFAULT_CLOSED_MESSAGE;

const handleAfterOnHold = async (room: any = {}): Promise<any> => {
const { _id: rid } = room;
Expand All @@ -23,7 +20,12 @@ const handleAfterOnHold = async (room: any = {}): Promise<any> => {
}

cbLogger.debug(`Scheduling room ${rid} to be closed in ${autoCloseOnHoldChatTimeout} seconds`);
await AutoCloseOnHoldScheduler.scheduleRoom(room._id, autoCloseOnHoldChatTimeout, customCloseMessage);
const closeComment =
settings.get<string>('Livechat_auto_close_on_hold_chats_custom_message') ||
TAPi18n.__('Closed_automatically_because_chat_was_onhold_for_seconds', {
onHoldTime: autoCloseOnHoldChatTimeout,
});
await AutoCloseOnHoldScheduler.scheduleRoom(room._id, autoCloseOnHoldChatTimeout, closeComment);
};

settings.watch('Livechat_auto_close_on_hold_chats_timeout', (value) => {
Expand All @@ -33,7 +35,3 @@ settings.watch('Livechat_auto_close_on_hold_chats_timeout', (value) => {
}
callbacks.add('livechat:afterOnHold', handleAfterOnHold, callbacks.priority.HIGH, 'livechat-auto-close-on-hold');
});

settings.watch('Livechat_auto_close_on_hold_chats_custom_message', (value) => {
customCloseMessage = (value as string) || DEFAULT_CLOSED_MESSAGE;
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ import { Agenda } from '@rocket.chat/agenda';
import { MongoInternals } from 'meteor/mongo';
import { Meteor } from 'meteor/meteor';
import moment from 'moment';
import { LivechatRooms, Users } from '@rocket.chat/models';
import type { IUser } from '@rocket.chat/core-typings';

import { Livechat } from '../../../../../app/livechat/server';
import { LivechatRooms, Users } from '../../../../../app/models/server';

const schedulerUser = Users.findOneById('rocket.cat');
const SCHEDULER_NAME = 'omnichannel_auto_close_on_hold_scheduler';

class AutoCloseOnHoldSchedulerClass {
scheduler: Agenda;

schedulerUser: IUser;

running: boolean;

public init(): void {
Expand Down Expand Up @@ -48,15 +50,27 @@ class AutoCloseOnHoldSchedulerClass {
const { roomId, comment } = data;

const payload = {
user: schedulerUser,
room: LivechatRooms.findOneById(roomId),
user: await this.getSchedulerUser(),
room: await LivechatRooms.findOneById(roomId),
comment,
options: {},
visitor: undefined,
};

Livechat.closeRoom(payload);
}

private async getSchedulerUser(): Promise<IUser> {
Comment thread
murtaza98 marked this conversation as resolved.
if (!this.schedulerUser) {
const schedulerUser = await Users.findOneById('rocket.cat');
if (!schedulerUser) {
throw new Error('Scheduler user not found');
}
this.schedulerUser = schedulerUser;
}

return this.schedulerUser;
}
}

export const AutoCloseOnHoldScheduler = new AutoCloseOnHoldSchedulerClass();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Agenda } from '@rocket.chat/agenda';
import { MongoInternals } from 'meteor/mongo';
import { Meteor } from 'meteor/meteor';
import { LivechatRooms } from '@rocket.chat/models';
import type { IUser } from '@rocket.chat/core-typings';

import { LivechatRooms, Users } from '../../../../../app/models/server';
import { Users } from '../../../../../app/models/server';
import { Livechat } from '../../../../../app/livechat/server';
import { RoutingManager } from '../../../../../app/livechat/server/lib/RoutingManager';
import { forwardRoomToAgent } from '../../../../../app/livechat/server/lib/Helper';
import { settings } from '../../../../../app/settings/server';

const schedulerUser = Users.findOneById('rocket.cat');
const SCHEDULER_NAME = 'omnichannel_scheduler';
Expand Down Expand Up @@ -53,7 +55,7 @@ class AutoTransferChatSchedulerClass {
}

private async transferRoom(roomId: string): Promise<boolean> {
const room = LivechatRooms.findOneById(roomId, {
const room = await LivechatRooms.findOneById(roomId, {
_id: 1,
v: 1,
servedBy: 1,
Expand All @@ -69,8 +71,14 @@ class AutoTransferChatSchedulerClass {
servedBy: { _id: ignoreAgentId },
} = room;

const timeoutDuration = settings.get<number>('Livechat_auto_transfer_chat_timeout').toString();

if (!RoutingManager.getConfig().autoAssignAgent) {
return Livechat.returnRoomAsInquiry(room._id, departmentId);
return Livechat.returnRoomAsInquiry(room._id, departmentId, {
scope: 'autoTransferUnansweredChatsToQueue',
comment: timeoutDuration,
transferredBy: schedulerUser,
});
}

const agent = await RoutingManager.getNextAgent(departmentId, ignoreAgentId);
Expand All @@ -79,6 +87,8 @@ class AutoTransferChatSchedulerClass {
userId: agent.agentId,
transferredBy: schedulerUser,
transferredTo: agent,
scope: 'autoTransferUnansweredChatsToAgent',
comment: timeoutDuration,
});
}

Expand All @@ -89,7 +99,7 @@ class AutoTransferChatSchedulerClass {
const { roomId } = data;

if (await this.transferRoom(roomId)) {
LivechatRooms.setAutoTransferredAtById(roomId);
await LivechatRooms.setAutoTransferredAtById(roomId);
}

await this.unscheduleRoom(roomId);
Expand Down
6 changes: 5 additions & 1 deletion apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,7 @@
"Closed": "Closed",
"Closed_At": "Closed at",
"Closed_automatically": "Closed automatically by the system",
"Closed_automatically_because_chat_was_onhold_for_seconds": "Closed automatically because chat was On Hold for __onHoldTime__ seconds",
Comment thread
KevLehman marked this conversation as resolved.
"Closed_automatically_chat_queued_too_long": "Closed automatically by the system (queue maximum time exceeded)",
"Closed_by_visitor": "Closed by visitor",
"Closing_chat": "Closing chat",
Expand Down Expand Up @@ -2936,8 +2937,11 @@
"Livechat_transcript_request_has_been_canceled": "The chat transcription request has been canceled.",
"Livechat_transcript_sent": "Omnichannel transcript sent",
"Livechat_transfer_return_to_the_queue": "__from__ returned the chat to the queue",
"Livechat_transfer_return_to_the_queue_with_a_comment": "__from__ returned the chat to the queue with a comment: __comment__",
"Livechat_transfer_return_to_the_queue_auto_transfer_unanswered_chat": "__from__ returned the chat to the queue since it was unanswered for __duration__ seconds",
"Livechat_transfer_to_agent": "__from__ transferred the chat to __to__",
"Livechat_transfer_to_agent_with_a_comment": "__from__ transferred the chat to __to__ with a comment: __comment__",
"Livechat_transfer_to_agent_auto_transfer_unanswered_chat": "__from__ transferred the chat to __to__ since it was unanswered for __duration__ seconds",
"Livechat_transfer_to_department": "__from__ transferred the chat to the department __to__",
"Livechat_transfer_to_department_with_a_comment": "__from__ transferred the chat to the department __to__ with a comment: __comment__",
"Livechat_transfer_failed_fallback": "The original department ( __from__ ) doesn't have online agents. Chat succesfully transferred to __to__",
Expand Down Expand Up @@ -5465,4 +5469,4 @@
"onboarding.form.standaloneServerForm.manuallyIntegrate": "Need to manually integrate with external services",
"Something_Went_Wrong": "Something went wrong",
"Toolbox_room_actions": "Primary Room actions"
}
}
41 changes: 40 additions & 1 deletion apps/meteor/server/models/raw/LivechatRooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -1190,10 +1190,49 @@ export class LivechatRoomsRaw extends BaseRaw {
}

setDepartmentByRoomId(roomId, departmentId) {
return this.update({ _id: roomId }, { $set: { departmentId } });
return this.updateOne({ _id: roomId }, { $set: { departmentId } });
}

findOpen() {
return this.find({ t: 'l', open: true });
}

setAutoTransferOngoingById(roomId) {
const query = {
_id: roomId,
};
const update = {
$set: {
autoTransferOngoing: true,
},
};

return this.updateOne(query, update);
}

unsetAutoTransferOngoingById(roomId) {
const query = {
_id: roomId,
};
const update = {
$unset: {
autoTransferOngoing: 1,
},
};

return this.updateOne(query, update);
}

setAutoTransferredAtById(roomId) {
const query = {
_id: roomId,
};
const update = {
$set: {
autoTransferredAt: new Date(),
},
};

return this.updateOne(query, update);
}
}
Loading