From f1968e7cfdbf3e2a45fe1c6a2f486f8960898934 Mon Sep 17 00:00:00 2001 From: "dionisio-bot[bot]" <117394943+dionisio-bot[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2025 10:50:52 +0100 Subject: [PATCH] fix: Allow bot agents to skip the queue (#35096) Co-authored-by: Kevin Aleman --- .changeset/silly-emus-remain.md | 5 + .../app/livechat/server/lib/QueueManager.ts | 7 +- .../end-to-end/api/livechat/24-routing.ts | 180 ++++++++++++++++++ 3 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 .changeset/silly-emus-remain.md diff --git a/.changeset/silly-emus-remain.md b/.changeset/silly-emus-remain.md new file mode 100644 index 00000000000..1d35264e21a --- /dev/null +++ b/.changeset/silly-emus-remain.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +Fixes a behavior in Omnichannel that was causing bot agents to be waiting in the queue, when they should always skip it. diff --git a/apps/meteor/app/livechat/server/lib/QueueManager.ts b/apps/meteor/app/livechat/server/lib/QueueManager.ts index 2e846bc24d9..f27bbdb6b77 100644 --- a/apps/meteor/app/livechat/server/lib/QueueManager.ts +++ b/apps/meteor/app/livechat/server/lib/QueueManager.ts @@ -132,6 +132,11 @@ export class QueueManager { return LivechatInquiryStatus.QUEUED; } + // bots should be able to skip the queue and the routing check + if (agent && (await allowAgentSkipQueue(agent))) { + return LivechatInquiryStatus.READY; + } + if (settings.get('Livechat_waiting_queue')) { return LivechatInquiryStatus.QUEUED; } @@ -140,7 +145,7 @@ export class QueueManager { return LivechatInquiryStatus.READY; } - if (!agent || !(await allowAgentSkipQueue(agent))) { + if (!agent) { return LivechatInquiryStatus.QUEUED; } diff --git a/apps/meteor/tests/end-to-end/api/livechat/24-routing.ts b/apps/meteor/tests/end-to-end/api/livechat/24-routing.ts index 582d9c096b7..1d72bbab117 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/24-routing.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/24-routing.ts @@ -28,6 +28,186 @@ import { IS_EE } from '../../../e2e/config/constants'; await updateSetting('Livechat_Routing_Method', 'Manual_Selection'); }); + // Basically: if there's a bot in the department, it should be assigned to the conversation + // No matter what settings workspace has in, as long as the setting to assign new conversations to bots is enabled + describe('Bots - Manual selection', () => { + let botUser: { user: IUser; credentials: Credentials }; + let testDepartment: ILivechatDepartment; + let testDepartment2: ILivechatDepartment; + before(async () => { + const bot = await createUser({ roles: ['bot', 'livechat-agent'] }); + const credentials = await login(bot.username, password); + + botUser = { user: bot, credentials }; + }); + before(async () => { + testDepartment = await createDepartment([{ agentId: botUser.user._id }]); + testDepartment2 = await createDepartment(); + await updateSetting('Livechat_Routing_Method', 'Manual_Selection'); + await updateSetting('Livechat_assign_new_conversation_to_bot', true); + await updateSetting('Livechat_accept_chats_with_no_agents', true); + }); + + after(async () => { + await deleteUser(botUser.user); + await updateSetting('Livechat_Routing_Method', 'Auto_Selection'); + await updateSetting('Livechat_assign_new_conversation_to_bot', false); + await updateSetting('Livechat_accept_chats_with_no_agents', false); + }); + + it('should assign conversation to bot', async () => { + const visitor = await createVisitor(testDepartment._id); + const room = await createLivechatRoom(visitor.token); + + const roomInfo = await getLivechatRoomInfo(room._id); + + expect(roomInfo.servedBy?._id).to.be.equal(botUser.user._id); + }); + it('should not assign conversation to bot if department has no bots', async () => { + const visitor = await createVisitor(testDepartment2._id); + const room = await createLivechatRoom(visitor.token); + + expect(room.servedBy).to.be.undefined; + }); + + describe('with setting disabled', () => { + before(async () => { + await updateSetting('Livechat_assign_new_conversation_to_bot', false); + }); + after(async () => { + await updateSetting('Livechat_assign_new_conversation_to_bot', true); + }); + + it('should not assign conversation to bot', async () => { + const visitor = await createVisitor(testDepartment._id); + const room = await createLivechatRoom(visitor.token); + + expect(room.servedBy).to.be.undefined; + }); + }); + }); + + describe('Bots - Auto selection', () => { + let botUser: { user: IUser; credentials: Credentials }; + let otherUser: { user: IUser; credentials: Credentials }; + let testDepartment: ILivechatDepartment; + let testDepartment2: ILivechatDepartment; + before(async () => { + const bot = await createUser({ roles: ['bot', 'livechat-agent'] }); + const credentials = await login(bot.username, password); + + const other = await createUser({ roles: ['livechat-agent'] }); + const otherCredentials = await login(other.username, password); + + await makeAgentAvailable(otherCredentials); + + botUser = { user: bot, credentials }; + otherUser = { user: other, credentials: otherCredentials }; + }); + before(async () => { + testDepartment = await createDepartment([{ agentId: botUser.user._id }, { agentId: otherUser.user._id }]); + testDepartment2 = await createDepartment(); + await updateSetting('Livechat_Routing_Method', 'Auto_Selection'); + await updateSetting('Livechat_assign_new_conversation_to_bot', true); + await updateSetting('Livechat_accept_chats_with_no_agents', true); + }); + + after(async () => { + await deleteUser(botUser.user); + await updateSetting('Livechat_assign_new_conversation_to_bot', false); + await updateSetting('Livechat_accept_chats_with_no_agents', false); + }); + + it('should assign conversation to bot', async () => { + const visitor = await createVisitor(testDepartment._id); + const room = await createLivechatRoom(visitor.token); + + const roomInfo = await getLivechatRoomInfo(room._id); + + expect(roomInfo.servedBy?._id).to.be.equal(botUser.user._id); + }); + it('should not assign conversation to bot if department has no bots', async () => { + const visitor = await createVisitor(testDepartment2._id); + const room = await createLivechatRoom(visitor.token); + + expect(room.servedBy).to.be.undefined; + }); + + describe('with setting disabled', () => { + before(async () => { + await updateSetting('Livechat_assign_new_conversation_to_bot', false); + }); + after(async () => { + await updateSetting('Livechat_assign_new_conversation_to_bot', true); + }); + + it('should not assign conversation to bot', async () => { + const visitor = await createVisitor(testDepartment._id); + const room = await createLivechatRoom(visitor.token); + + expect(room.servedBy?._id).to.be.equal(otherUser.user._id); + }); + }); + }); + + describe('Bots - Auto selection & Waiting queue', () => { + let botUser: { user: IUser; credentials: Credentials }; + let testDepartment: ILivechatDepartment; + let testDepartment2: ILivechatDepartment; + before(async () => { + const bot = await createUser({ roles: ['bot', 'livechat-agent'] }); + const credentials = await login(bot.username, password); + + botUser = { user: bot, credentials }; + }); + before(async () => { + testDepartment = await createDepartment([{ agentId: botUser.user._id }]); + testDepartment2 = await createDepartment(); + await updateSetting('Livechat_Routing_Method', 'Auto_Selection'); + await updateSetting('Livechat_waiting_queue', true); + await updateSetting('Livechat_assign_new_conversation_to_bot', true); + await updateSetting('Livechat_accept_chats_with_no_agents', true); + }); + + after(async () => { + await deleteUser(botUser.user); + await updateSetting('Livechat_waiting_queue', false); + await updateSetting('Livechat_assign_new_conversation_to_bot', false); + await updateSetting('Livechat_accept_chats_with_no_agents', false); + }); + + it('should assign conversation to bot', async () => { + const visitor = await createVisitor(testDepartment._id); + const room = await createLivechatRoom(visitor.token); + + const roomInfo = await getLivechatRoomInfo(room._id); + + expect(roomInfo.servedBy?._id).to.be.equal(botUser.user._id); + }); + it('should not assign conversation to bot if department has no bots', async () => { + const visitor = await createVisitor(testDepartment2._id); + const room = await createLivechatRoom(visitor.token); + + expect(room.servedBy).to.be.undefined; + }); + + describe('with setting disabled', () => { + before(async () => { + await updateSetting('Livechat_assign_new_conversation_to_bot', false); + }); + after(async () => { + await updateSetting('Livechat_assign_new_conversation_to_bot', true); + }); + + it('should not assign conversation to bot', async () => { + const visitor = await createVisitor(testDepartment._id); + const room = await createLivechatRoom(visitor.token); + + expect(room.servedBy).to.be.undefined; + }); + }); + }); + describe('Auto-Selection', () => { before(async () => { await updateSetting('Livechat_Routing_Method', 'Auto_Selection');