Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,7 @@
"Incoming_WebHook": "Incoming WebHook",
"Industry": "Industry",
"initials_avatar": "Initials Avatar",
"Initially_routes_the_visitor_to_a_bot_agent": "Initially routes the visitor to a bot agent",
"inline_code": "inline code",
"Install_Extension": "Install Extension",
"Install_FxOs": "Install Rocket.Chat on your Firefox",
Expand Down Expand Up @@ -1588,6 +1589,7 @@
"Livechat_Queue": "Livechat Queue",
"Livechat_registration_form": "Registration Form",
"Livechat_room_count": "Livechat Room Count",
"Livechat_Routing_Bot_First": "First routes the visitor to a bot agent",
"Livechat_Routing_Method": "Livechat Routing Method",
"Livechat_Take_Confirm": "Do you want to take this client?",
"Livechat_title": "Livechat Title",
Expand Down
2 changes: 2 additions & 0 deletions packages/rocketchat-i18n/i18n/pt-BR.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1309,6 +1309,7 @@
"Incoming_WebHook": "WebHook entrante",
"Industry": "Indústria",
"initials_avatar": "Iniciais Avatar",
"Initially_routes_the_visitor_to_a_bot_agent": "Inicialmente encaminha o visitante para um bot cadastrado como agente",
"inline_code": "código",
"Install_Extension": "Instalar Extensão",
"Install_FxOs": "Instale o Rocket.Chat em seu Firefox",
Expand Down Expand Up @@ -1583,6 +1584,7 @@
"Livechat_Queue": "Roleta Livechat",
"Livechat_registration_form": "Formulário de Registro",
"Livechat_room_count": "Contador de salas de livechat",
"Livechat_Routing_Bot_First": "Inicialmente encaminha visitante para bot",
"Livechat_Routing_Method": "Método de roteamento Livechat",
"Livechat_Take_Confirm": "Você quer levar esse cliente?",
"Livechat_title": "Título Livechat",
Expand Down
32 changes: 32 additions & 0 deletions packages/rocketchat-lib/server/models/Subscriptions.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import _ from 'underscore';

class ModelSubscriptions extends RocketChat.models._Base {
constructor() {
super(...arguments);
Expand Down Expand Up @@ -798,6 +800,36 @@ class ModelSubscriptions extends RocketChat.models._Base {
}


// INSERT
subscribeWithRoomAndUser(room, user, extraData) {
const subscription = {
open: true,
alert: true,
unread: 1,
userMentions: 1,
groupMentions: 0,
ts: room.ts,
rid: room._id,
name: room.name,
fname: room.fname,
customFields: room.customFields,
t: room.t,
u: {
_id: user.agentId || user._id,
username: user.username,
name: user.name
},
desktopNotifications: 'all',
mobilePushNotifications: 'all',
emailNotifications: 'all'
};

_.extend(subscription, extraData);

return this.insert(subscription);
}


// REMOVE
removeByUserId(userId) {
const query = {
Expand Down
9 changes: 9 additions & 0 deletions packages/rocketchat-livechat/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,15 @@ Meteor.startup(function() {
i18nLabel: 'RDStation_Token'
});

RocketChat.settings.add('Livechat_Routing_Bot_First', false, {
type: 'boolean',
group: 'Livechat',
public: true,
section: 'Routing',
i18nLabel: 'Livechat_Routing_Bot_First',
i18nDescription: 'Initially_routes_the_visitor_to_a_bot_agent'
});

RocketChat.settings.add('Livechat_Routing_Method', 'Least_Amount', {
type: 'select',
group: 'Livechat',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ RocketChat.API.v1.addRoute('livechat/messages', { authRequired: true }, {
message: {
_id: Random.id(),
rid,
noBot: this.bodyParams.noBot,
token: visitorToken,
msg: message.msg
}
Expand Down
2 changes: 1 addition & 1 deletion packages/rocketchat-livechat/imports/server/rest/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ RocketChat.API.v1.addRoute('livechat/users/:type', { authRequired: true }, {
const users = RocketChat.authz.getUsersInRole(role);

return RocketChat.API.v1.success({
users: users.fetch().map(user => _.pick(user, '_id', 'username', 'name', 'status', 'statusLivechat'))
users: users.fetch().map(user => _.pick(user, '_id', 'username', 'name', 'status', 'statusLivechat', 'roles'))
});
} catch (e) {
return RocketChat.API.v1.failure(e.error);
Expand Down
20 changes: 17 additions & 3 deletions packages/rocketchat-livechat/server/lib/Livechat.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,24 @@ RocketChat.Livechat = {
guest.department = department._id;
}
}
room = RocketChat.models.Rooms.create(message.rid, guest, roomInfo, agent);

if (!agent && message.noBot !== true && RocketChat.settings.get('Livechat_Routing_Bot_First')) {
agent = RocketChat.models.Users.getBotAgent();
if (agent) {
RocketChat.models.Rooms.changeAgentByRoomId(room._id, agent);
RocketChat.models.Subscriptions.subscribeWithRoomAndUser(room, agent);
RocketChat.Livechat.stream.emit(room._id, {
type: 'agentData',
data: RocketChat.models.Users.getAgentInfo(agent.agentId)
});
}
}

// delegate room creation to QueueMethods
const routingMethod = RocketChat.settings.get('Livechat_Routing_Method');
room = RocketChat.QueueMethods[routingMethod](guest, message, roomInfo, agent);
if (agent == null) {
const routingMethod = RocketChat.settings.get('Livechat_Routing_Method');
agent = RocketChat.QueueMethods[routingMethod](guest, message, room, agent);
}

newRoom = true;
}
Expand Down
91 changes: 9 additions & 82 deletions packages/rocketchat-livechat/server/lib/QueueMethods.js
Original file line number Diff line number Diff line change
@@ -1,84 +1,35 @@
import _ from 'underscore';

RocketChat.QueueMethods = {
/* Least Amount Queuing method:
*
* default method where the agent with the least number
* of open chats is paired with the incoming livechat
*/
'Least_Amount'(guest, message, roomInfo, agent) {
'Least_Amount'(guest, message, room, agent) {
if (!agent) {
agent = RocketChat.Livechat.getNextAgent(guest.department);
if (!agent) {
throw new Meteor.Error('no-agent-online', 'Sorry, no online agents');
}
}

RocketChat.models.Rooms.updateLivechatRoomCount();

const room = _.extend({
_id: message.rid,
msgs: 1,
usersCount: 1,
lm: new Date(),
fname: (roomInfo && roomInfo.fname) || guest.name || guest.username,
// usernames: [agent.username, guest.username],
t: 'l',
ts: new Date(),
v: {
_id: guest._id,
username: guest.username,
token: message.token,
status: guest.status || 'online'
},
servedBy: {
_id: agent.agentId,
username: agent.username
},
cl: false,
open: true,
waitingResponse: true
}, roomInfo);

const subscriptionData = {
rid: message.rid,
fname: guest.name || guest.username,
alert: true,
open: true,
unread: 1,
userMentions: 1,
groupMentions: 0,
u: {
_id: agent.agentId,
username: agent.username
},
t: 'l',
desktopNotifications: 'all',
mobilePushNotifications: 'all',
emailNotifications: 'all'
};

RocketChat.models.Rooms.insert(room);

RocketChat.models.Subscriptions.insert(subscriptionData);
RocketChat.models.Rooms.changeAgentByRoomId(room._id, agent);
RocketChat.models.Subscriptions.subscribeWithRoomAndUser(room, agent);

RocketChat.Livechat.stream.emit(room._id, {
type: 'agentData',
data: RocketChat.models.Users.getAgentInfo(agent.agentId)
});

return room;
return agent;
},
/* Guest Pool Queuing Method:
*
* An incomming livechat is created as an Inquiry
* which is picked up from an agent.
* An Inquiry is visible to all agents (TODO: in the correct department)
*
* A room is still created with the initial message, but it is occupied by
* only the client until paired with an agent
*
*/
'Guest_Pool'(guest, message, roomInfo) {
'Guest_Pool'(guest, message) {
let agents = RocketChat.Livechat.getOnlineAgents(guest.department);

if (agents.count() === 0 && RocketChat.settings.get('Livechat_guest_pool_with_no_agents')) {
Expand All @@ -89,8 +40,6 @@ RocketChat.QueueMethods = {
throw new Meteor.Error('no-agent-online', 'Sorry, no online agents');
}

RocketChat.models.Rooms.updateLivechatRoomCount();

const agentIds = [];

agents.forEach((agent) => {
Expand All @@ -117,33 +66,11 @@ RocketChat.QueueMethods = {
},
t: 'l'
};

const room = _.extend({
_id: message.rid,
msgs: 1,
usersCount: 0,
lm: new Date(),
fname: guest.name || guest.username,
// usernames: [guest.username],
t: 'l',
ts: new Date(),
v: {
_id: guest._id,
username: guest.username,
token: message.token,
status: guest.status
},
cl: false,
open: true,
waitingResponse: true
}, roomInfo);

RocketChat.models.LivechatInquiry.insert(inquiry);
RocketChat.models.Rooms.insert(room);

return room;
return undefined;
},
'External'(guest, message, roomInfo, agent) {
return this['Least_Amount'](guest, message, roomInfo, agent); // eslint-disable-line
'External'(guest, message, room, agent) {
return this['Least_Amount'](guest, message, room, agent); // eslint-disable-line
}
};
4 changes: 4 additions & 0 deletions packages/rocketchat-livechat/server/methods/getInitialData.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ Meteor.methods({
info.allowSwitchingDepartments = initSettings.Livechat_allow_switching_departments;

info.online = RocketChat.models.Users.findOnlineAgents().count() > 0;
if (!info.online && RocketChat.settings.get('Livechat_Routing_Bot_First')) {
info.online = RocketChat.models.Users.getBotAgent() !== undefined;
}

return info;
}
});
39 changes: 38 additions & 1 deletion packages/rocketchat-livechat/server/models/Rooms.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
import _ from 'underscore';

/**
* Gets visitor by token
* @param {string} token - Visitor token
*/
RocketChat.models.Rooms.create = function(rid, guest, roomInfo, agent) {
this.updateLivechatRoomCount();
rid = rid || Random.id();
const room = _.extend({
_id: rid,
msgs: 1,
usersCount: 0,
lm: new Date(),
fname: (roomInfo && roomInfo.fname) || guest.name || guest.username,
// usernames: [agent.username, guest.username],
t: 'l',
ts: new Date(),
v: {
_id: guest._id,
username: guest.username,
token: guest.token,
status: guest.status || 'online'
},
cl: false,
open: true,
waitingResponse: true
}, roomInfo);
if (agent) {
room.servedBy = {
_id: agent._id || agent.agentId,
username: agent.username
};
room.usersCount = 1;
}
this.insert(room);
return room;
};

/**
* Gets visitor by token
* @param {string} token - Visitor token
Expand Down Expand Up @@ -187,7 +224,7 @@ RocketChat.models.Rooms.changeAgentByRoomId = function(roomId, newAgent) {
const update = {
$set: {
servedBy: {
_id: newAgent.agentId,
_id: newAgent.agentId || newAgent._id,
username: newAgent.username
}
}
Expand Down
14 changes: 14 additions & 0 deletions packages/rocketchat-livechat/server/models/Users.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,20 @@ RocketChat.models.Users.getNextAgent = function() {
}
};

/**
* Get bot agent
* @return {object} User from db
*/
RocketChat.models.Users.getBotAgent = function() {
const query = {
roles: {
$all: ['bot', 'livechat-agent']
}
};

return this.findOne(query);
};

/**
* Change user's livechat status
* @param {string} token - Visitor token
Expand Down