From 366a45275881fb188a68a379e45c87357c5381e8 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Fri, 8 Dec 2017 17:04:37 -0200 Subject: [PATCH] Add support to external livechat queue service provider --- packages/rocketchat-i18n/i18n/en.i18n.json | 5 +- packages/rocketchat-livechat/config.js | 74 ++++++++++++------- .../server/lib/Livechat.js | 33 ++++++++- .../server/lib/QueueMethods.js | 3 + .../server/models/Users.js | 18 +++++ 5 files changed, 104 insertions(+), 29 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 7b12e2b6c797..969e20e7d22b 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -678,6 +678,8 @@ "Example_s": "Example: %s", "Exclude_Botnames": "Exclude Bots", "Exclude_Botnames_Description": "Do not propagate messages from bots whose name matches the regular expression above. If left empty, all messages from bots will be propagated.", + "External_Service": "External Service", + "External_Queue_Service_URL": "External Queue Service URL", "False": "False", "Favorite_Rooms": "Enable Favorite Rooms", "Favorites": "Favorites", @@ -726,6 +728,7 @@ "Food_and_Drink": "Food & Drink", "Footer": "Footer", "Footer_Direct_Reply": "Footer When Direct Reply is Enabled", + "For_more_details_please_check_our_docs": "For more details please check our docs.", "For_your_security_you_must_enter_your_current_password_to_continue": "For your security, you must enter your current password to continue", "force-delete-message": "Force Delete Message", "force-delete-message_description": "Permission to delete a message bypassing all restrictions", @@ -2103,4 +2106,4 @@ "your_message_optional": "your message (optional)", "Your_password_is_wrong": "Your password is wrong!", "Your_push_was_sent_to_s_devices": "Your push was sent to %s devices" -} \ No newline at end of file +} diff --git a/packages/rocketchat-livechat/config.js b/packages/rocketchat-livechat/config.js index b9ea597aa5ae..d2325da875f5 100644 --- a/packages/rocketchat-livechat/config.js +++ b/packages/rocketchat-livechat/config.js @@ -164,31 +164,6 @@ Meteor.startup(function() { ] }); - RocketChat.settings.add('Livechat_Routing_Method', 'Least_Amount', { - type: 'select', - group: 'Livechat', - public: true, - values: [ - {key: 'Least_Amount', i18nLabel: 'Least_Amount'}, - {key: 'Guest_Pool', i18nLabel: 'Guest_Pool'} - ] - }); - - RocketChat.settings.add('Livechat_guest_pool_with_no_agents', false, { - type: 'boolean', - group: 'Livechat', - i18nLabel: 'Accept_with_no_online_agents', - i18nDescription: 'Accept_incoming_livechat_requests_even_if_there_are_no_online_agents', - enableQuery: { _id: 'Livechat_Routing_Method', value: 'Guest_Pool' } - }); - - RocketChat.settings.add('Livechat_show_queue_list_link', false, { - type: 'boolean', - group: 'Livechat', - public: true, - i18nLabel: 'Show_queue_list_to_all_agents' - }); - RocketChat.settings.add('Livechat_enable_office_hours', false, { type: 'boolean', group: 'Livechat', @@ -243,4 +218,53 @@ Meteor.startup(function() { section: 'RD Station', i18nLabel: 'RDStation_Token' }); + + RocketChat.settings.add('Livechat_Routing_Method', 'Least_Amount', { + type: 'select', + group: 'Livechat', + public: true, + section: 'Routing', + values: [ + {key: 'External', i18nLabel: 'External_Service'}, + {key: 'Least_Amount', i18nLabel: 'Least_Amount'}, + {key: 'Guest_Pool', i18nLabel: 'Guest_Pool'} + ] + }); + + RocketChat.settings.add('Livechat_guest_pool_with_no_agents', false, { + type: 'boolean', + group: 'Livechat', + section: 'Routing', + i18nLabel: 'Accept_with_no_online_agents', + i18nDescription: 'Accept_incoming_livechat_requests_even_if_there_are_no_online_agents', + enableQuery: { _id: 'Livechat_Routing_Method', value: 'Guest_Pool' } + }); + + RocketChat.settings.add('Livechat_show_queue_list_link', false, { + type: 'boolean', + group: 'Livechat', + public: true, + section: 'Routing', + i18nLabel: 'Show_queue_list_to_all_agents', + enableQuery: { _id: 'Livechat_Routing_Method', value: { $ne: 'External' } } + }); + + RocketChat.settings.add('Livechat_External_Queue_URL', '', { + type: 'string', + group: 'Livechat', + public: false, + section: 'Routing', + i18nLabel: 'External_Queue_Service_URL', + i18nDescription: 'For_more_details_please_check_our_docs', + enableQuery: { _id: 'Livechat_Routing_Method', value: 'External' } + }); + + RocketChat.settings.add('Livechat_External_Queue_Token', '', { + type: 'string', + group: 'Livechat', + public: false, + section: 'Routing', + i18nLabel: 'Secret_token', + enableQuery: { _id: 'Livechat_Routing_Method', value: 'External' } + }); }); diff --git a/packages/rocketchat-livechat/server/lib/Livechat.js b/packages/rocketchat-livechat/server/lib/Livechat.js index 9450dc57556a..89c5b0976f7a 100644 --- a/packages/rocketchat-livechat/server/lib/Livechat.js +++ b/packages/rocketchat-livechat/server/lib/Livechat.js @@ -13,11 +13,38 @@ RocketChat.Livechat = { }), getNextAgent(department) { - if (department) { + if (RocketChat.settings.get('Livechat_Routing_Method') === 'External') { + for (let i = 0; i < 10; i++) { + try { + const queryString = department ? `?departmentId=${ department }` : ''; + const result = HTTP.call('GET', `${ RocketChat.settings.get('Livechat_External_Queue_URL') }${ queryString }`, { + headers: { + 'User-Agent': 'RocketChat Server', + 'Accept': 'application/json', + 'X-RocketChat-Secret-Token': RocketChat.settings.get('Livechat_External_Queue_Token') + } + }); + + if (result && result.data && result.data.username) { + const agent = RocketChat.models.Users.findOneOnlineAgentByUsername(result.data.username); + + if (agent) { + return { + agentId: agent._id, + username: agent.username + }; + } + } + } catch (e) { + console.error('Error requesting agent from external queue.', e); + break; + } + } + throw new Meteor.Error('no-agent-online', 'Sorry, no online agents'); + } else if (department) { return RocketChat.models.LivechatDepartmentAgents.getNextAgentForDepartment(department); - } else { - return RocketChat.models.Users.getNextAgent(); } + return RocketChat.models.Users.getNextAgent(); }, getAgents(department) { if (department) { diff --git a/packages/rocketchat-livechat/server/lib/QueueMethods.js b/packages/rocketchat-livechat/server/lib/QueueMethods.js index 318ce9918f76..1289b4aad559 100644 --- a/packages/rocketchat-livechat/server/lib/QueueMethods.js +++ b/packages/rocketchat-livechat/server/lib/QueueMethods.js @@ -135,5 +135,8 @@ RocketChat.QueueMethods = { RocketChat.models.Rooms.insert(room); return room; + }, + 'External'(guest, message, roomInfo) { + return this['Least_Amount'](guest, message, roomInfo); // eslint-disable-line } }; diff --git a/packages/rocketchat-livechat/server/models/Users.js b/packages/rocketchat-livechat/server/models/Users.js index d4062ae6b2d2..0fe717d36d78 100644 --- a/packages/rocketchat-livechat/server/models/Users.js +++ b/packages/rocketchat-livechat/server/models/Users.js @@ -32,6 +32,24 @@ RocketChat.models.Users.findOnlineAgents = function() { return this.find(query); }; +/** + * Find an online agent by his username + * @return + */ +RocketChat.models.Users.findOneOnlineAgentByUsername = function(username) { + const query = { + username, + status: { + $exists: true, + $ne: 'offline' + }, + statusLivechat: 'available', + roles: 'livechat-agent' + }; + + return this.findOne(query); +}; + /** * Gets all agents * @return