diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json
index 5044976a2ebb..08c631347b9f 100644
--- a/packages/rocketchat-i18n/i18n/en.i18n.json
+++ b/packages/rocketchat-i18n/i18n/en.i18n.json
@@ -422,6 +422,7 @@
"Current_Chats": "Current Chats",
"Current_Status": "Current Status",
"Custom": "Custom",
+ "Custom_agent": "Custom agent",
"Custom_Emoji": "Custom Emoji",
"Custom_Emoji_Add": "Add New Emoji",
"Custom_Emoji_Added_Successfully": "Custom emoji added successfully",
@@ -809,6 +810,7 @@
"Iframe_Integration_send_target_origin_Description": "Origin with protocol prefix, which commands are sent to e.g. 'https://localhost', or * to allow sending to anywhere.",
"IMAP_intercepter_already_running": "IMAP intercepter already running",
"IMAP_intercepter_Not_running": "IMAP intercepter Not running",
+ "Impersonate_next_agent_from_queue": "Impersonate next agent from queue",
"Impersonate_user": "Impersonate User",
"Impersonate_user_description": "When enabled, integration posts as the user that triggered integration",
"Import": "Import",
@@ -1575,6 +1577,7 @@
"Select_a_department": "Select a department",
"Select_a_user": "Select a user",
"Select_an_avatar": "Select an avatar",
+ "Select_an_option": "Select an option",
"Select_file": "Select file",
"Select_role": "Select a Role",
"Select_service_to_login": "Select a service to login to load your picture or upload one directly from your computer",
diff --git a/packages/rocketchat-livechat/.app/client/lib/chatMessages.js b/packages/rocketchat-livechat/.app/client/lib/chatMessages.js
index 664f7df344a8..1209391f61cc 100644
--- a/packages/rocketchat-livechat/.app/client/lib/chatMessages.js
+++ b/packages/rocketchat-livechat/.app/client/lib/chatMessages.js
@@ -112,7 +112,16 @@ this.ChatMessages = class ChatMessages {
};
MsgTyping.stop(rid);
- Meteor.call('sendMessageLivechat', msgObject, (error, result) => {
+ let agent;
+ const currentAgent = !visitor.roomSubscribed && Livechat.agent;
+ if (currentAgent) {
+ agent = {
+ _id: currentAgent._id,
+ username: currentAgent.username
+ };
+ }
+
+ Meteor.call('sendMessageLivechat', msgObject, agent, (error, result) => {
if (error) {
ChatMessage.update(msgObject._id, { $set: { error: true } });
showError(error.reason);
diff --git a/packages/rocketchat-livechat/.app/client/lib/triggers.js b/packages/rocketchat-livechat/.app/client/lib/triggers.js
index 72f68df99294..3f958c47b97d 100644
--- a/packages/rocketchat-livechat/.app/client/lib/triggers.js
+++ b/packages/rocketchat-livechat/.app/client/lib/triggers.js
@@ -1,5 +1,44 @@
+/* globals Livechat */
import visitor from '../../imports/client/visitor';
+function getAgent(triggerAction) {
+ return new Promise((resolve, reject) => {
+ const { params } = triggerAction;
+ if (params.sender === 'queue') {
+ const cache = localStorage.getItem('triggerAgent');
+ if (cache) {
+ const cacheAgent = JSON.parse(cache);
+
+ // cache valid for 1h
+ if (cacheAgent.ts && Date.now() - cacheAgent.ts < 3600000) {
+ return resolve(cacheAgent.agent);
+ }
+ }
+
+ Meteor.call('livechat:getNextAgent', {
+ token: visitor.getToken(),
+ department: Livechat.department
+ }, (error, result) => {
+ if (error) {
+ return reject(error);
+ }
+ localStorage.setItem('triggerAgent', JSON.stringify({
+ agent: result,
+ ts: Date.now()
+ }));
+
+ resolve(result);
+ });
+ } else if (params.sender === 'custom') {
+ resolve({
+ username: params.name
+ });
+ } else {
+ reject('Unknown sender');
+ }
+ });
+}
+
this.Triggers = (function() {
let triggers = [];
let initiated = false;
@@ -15,23 +54,27 @@ this.Triggers = (function() {
// flag to skip the trigger if the action is 'send-message'
trigger.skip = true;
- let roomId = visitor.getRoom();
+ getAgent(action).then((agent) => {
+ let roomId = visitor.getRoom();
- if (!roomId) {
- roomId = Random.id();
- visitor.setRoom(roomId);
- }
+ if (!roomId) {
+ roomId = Random.id();
+ visitor.setRoom(roomId);
+ }
- Session.set('triggered', true);
- ChatMessage.insert({
- msg: action.params.msg,
- rid: roomId,
- u: {
- username: action.params.name
+ Session.set('triggered', true);
+ ChatMessage.insert({
+ msg: action.params.msg,
+ rid: roomId,
+ u: agent
+ });
+
+ if (agent._id) {
+ Livechat.agent = agent;
}
- });
- parentCall('openWidget');
+ parentCall('openWidget');
+ });
}
});
};
diff --git a/packages/rocketchat-livechat/client/stylesheets/livechat.less b/packages/rocketchat-livechat/client/stylesheets/livechat.less
index 6b86af663b38..7d2e34e95075 100644
--- a/packages/rocketchat-livechat/client/stylesheets/livechat.less
+++ b/packages/rocketchat-livechat/client/stylesheets/livechat.less
@@ -26,9 +26,11 @@
.trigger-value {
width: 70%;
- input {
- display: inline-block !important;
+ textarea, input, select {
+ display: block !important;
width: auto !important;
+ margin-bottom: 4px;
+ min-width: 50%;
}
}
diff --git a/packages/rocketchat-livechat/client/views/app/livechatTriggersForm.js b/packages/rocketchat-livechat/client/views/app/livechatTriggersForm.js
index 651b2367a092..f5360e5468b5 100644
--- a/packages/rocketchat-livechat/client/views/app/livechatTriggersForm.js
+++ b/packages/rocketchat-livechat/client/views/app/livechatTriggersForm.js
@@ -56,12 +56,16 @@ Template.livechatTriggersForm.events({
$('.each-action').each(function() {
if ($('.trigger-action', this).val() === 'send-message') {
+ const params = {
+ sender: $('[name=send-message-sender]', this).val(),
+ msg: $('[name=send-message-msg]', this).val()
+ };
+ if (params.sender === 'custom') {
+ params.name = $('[name=send-message-name]', this).val();
+ }
data.actions.push({
name: $('.trigger-action', this).val(),
- params: {
- name: $('[name=send-message-name]', this).val(),
- msg: $('[name=send-message-msg]', this).val()
- }
+ params
});
} else {
data.actions.push({
diff --git a/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.html b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.html
index 4a4328b7ae87..9eb80a69147a 100644
--- a/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.html
+++ b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.html
@@ -7,8 +7,13 @@
diff --git a/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.js b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.js
index f47ad1c549e2..355f46f54a3f 100644
--- a/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.js
+++ b/packages/rocketchat-livechat/client/views/app/triggers/livechatTriggerAction.js
@@ -6,6 +6,15 @@ Template.livechatTriggerAction.helpers({
} else if (this.name !== current) {
return 'hidden';
}
+ },
+ showCustomName() {
+ return Template.instance().sender.get() === 'custom' ? '' : 'hidden';
+ },
+ senderSelected(current) {
+ return this.params && this.params.sender === current ? true : false;
+ },
+ disableIfGuestPool() {
+ return RocketChat.settings.get('Livechat_Routing_Method') === 'Guest_Pool';
}
});
@@ -13,9 +22,19 @@ Template.livechatTriggerAction.events({
'change .trigger-action'(e, instance) {
instance.$('.trigger-action-value ').addClass('hidden');
instance.$(`.${ e.currentTarget.value }`).removeClass('hidden');
+ },
+ 'change [name=send-message-sender]'(e, instance) {
+ instance.sender.set(e.currentTarget.value);
}
});
Template.livechatTriggerAction.onCreated(function() {
this.firstAction = true;
+
+ this.sender = new ReactiveVar('');
+
+ const data = Template.currentData();
+ if (data && data.name === 'send-message') {
+ this.sender.set(data.params.sender);
+ }
});
diff --git a/packages/rocketchat-livechat/package.js b/packages/rocketchat-livechat/package.js
index ea9bbad4675e..79fb59df8fab 100644
--- a/packages/rocketchat-livechat/package.js
+++ b/packages/rocketchat-livechat/package.js
@@ -148,6 +148,7 @@ Package.onUse(function(api) {
api.addFiles('server/methods/getCustomFields.js', 'server');
api.addFiles('server/methods/getAgentData.js', 'server');
api.addFiles('server/methods/getInitialData.js', 'server');
+ api.addFiles('server/methods/getNextAgent.js', 'server');
api.addFiles('server/methods/loadHistory.js', 'server');
api.addFiles('server/methods/loginByToken.js', 'server');
api.addFiles('server/methods/pageVisited.js', 'server');
diff --git a/packages/rocketchat-livechat/server/lib/Livechat.js b/packages/rocketchat-livechat/server/lib/Livechat.js
index 4b996733d818..d4f26ccb8789 100644
--- a/packages/rocketchat-livechat/server/lib/Livechat.js
+++ b/packages/rocketchat-livechat/server/lib/Livechat.js
@@ -61,7 +61,21 @@ RocketChat.Livechat = {
return RocketChat.models.Users.findOnlineAgents();
}
},
- getRoom(guest, message, roomInfo) {
+ getRequiredDepartment(onlineRequired = true) {
+ const departments = RocketChat.models.LivechatDepartment.findEnabledWithAgents();
+
+ return departments.fetch().find((dept) => {
+ if (!dept.showOnRegistration) {
+ return false;
+ }
+ if (!onlineRequired) {
+ return true;
+ }
+ const onlineAgents = RocketChat.models.LivechatDepartmentAgents.getOnlineForDepartment(dept._id);
+ return onlineAgents.count() > 0;
+ });
+ },
+ getRoom(guest, message, roomInfo, agent) {
let room = RocketChat.models.Rooms.findOneById(message.rid);
let newRoom = false;
@@ -72,20 +86,17 @@ RocketChat.Livechat = {
if (room == null) {
// if no department selected verify if there is at least one active and pick the first
- if (!guest.department) {
- const departments = RocketChat.models.LivechatDepartment.findEnabledWithAgents();
- if (departments.count() > 0) {
- departments.forEach((dept) => {
- if (!guest.department && dept.showOnRegistration) {
- guest.department = dept._id;
- }
- });
+ if (!agent && !guest.department) {
+ const department = this.getRequiredDepartment();
+
+ if (department) {
+ guest.department = department._id;
}
}
// delegate room creation to QueueMethods
const routingMethod = RocketChat.settings.get('Livechat_Routing_Method');
- room = RocketChat.QueueMethods[routingMethod](guest, message, roomInfo);
+ room = RocketChat.QueueMethods[routingMethod](guest, message, roomInfo, agent);
newRoom = true;
}
@@ -96,8 +107,8 @@ RocketChat.Livechat = {
return { room, newRoom };
},
- sendMessage({ guest, message, roomInfo }) {
- const { room, newRoom } = this.getRoom(guest, message, roomInfo);
+ sendMessage({ guest, message, roomInfo, agent }) {
+ const { room, newRoom } = this.getRoom(guest, message, roomInfo, agent);
if (guest.name) {
message.alias = guest.name;
}
diff --git a/packages/rocketchat-livechat/server/lib/QueueMethods.js b/packages/rocketchat-livechat/server/lib/QueueMethods.js
index 1e4086e98f30..831b4407efa0 100644
--- a/packages/rocketchat-livechat/server/lib/QueueMethods.js
+++ b/packages/rocketchat-livechat/server/lib/QueueMethods.js
@@ -6,10 +6,12 @@ RocketChat.QueueMethods = {
* default method where the agent with the least number
* of open chats is paired with the incoming livechat
*/
- 'Least_Amount'(guest, message, roomInfo) {
- const agent = RocketChat.Livechat.getNextAgent(guest.department);
+ 'Least_Amount'(guest, message, roomInfo, agent) {
if (!agent) {
- throw new Meteor.Error('no-agent-online', 'Sorry, no online agents');
+ agent = RocketChat.Livechat.getNextAgent(guest.department);
+ if (!agent) {
+ throw new Meteor.Error('no-agent-online', 'Sorry, no online agents');
+ }
}
const roomCode = RocketChat.models.Rooms.getNextLivechatRoomCode();
diff --git a/packages/rocketchat-livechat/server/methods/getNextAgent.js b/packages/rocketchat-livechat/server/methods/getNextAgent.js
new file mode 100644
index 000000000000..a9d09f5c6332
--- /dev/null
+++ b/packages/rocketchat-livechat/server/methods/getNextAgent.js
@@ -0,0 +1,25 @@
+Meteor.methods({
+ 'livechat:getNextAgent'({ token, department }) {
+ check(token, String);
+
+ const room = RocketChat.models.Rooms.findOpenByVisitorToken(token).fetch();
+
+ if (room && room.length > 0) {
+ return;
+ }
+
+ if (!department) {
+ const requireDeparment = RocketChat.Livechat.getRequiredDepartment();
+ if (requireDeparment) {
+ department = requireDeparment._id;
+ }
+ }
+
+ const agent = RocketChat.Livechat.getNextAgent(department);
+ if (!agent) {
+ return;
+ }
+
+ return RocketChat.models.Users.getAgentInfo(agent.agentId);
+ }
+});
diff --git a/packages/rocketchat-livechat/server/methods/sendMessageLivechat.js b/packages/rocketchat-livechat/server/methods/sendMessageLivechat.js
index b112474e4aeb..88a2ff587648 100644
--- a/packages/rocketchat-livechat/server/methods/sendMessageLivechat.js
+++ b/packages/rocketchat-livechat/server/methods/sendMessageLivechat.js
@@ -1,7 +1,7 @@
import LivechatVisitors from '../models/LivechatVisitors';
Meteor.methods({
- sendMessageLivechat({ token, _id, rid, msg }) {
+ sendMessageLivechat({ token, _id, rid, msg }, agent) {
check(token, String);
check(_id, String);
check(rid, String);
@@ -27,7 +27,8 @@ Meteor.methods({
rid,
msg,
token
- }
+ },
+ agent
});
}
});