Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2fb6d12
Fix livechat routes to allow inviting other agents to the same chat.
renatobecker Feb 26, 2018
41e7cbd
Fix indentation tabs.
renatobecker Feb 26, 2018
089e15e
Merge branch 'fix-invite-agents-to-livechat-rooms' into send-visitor-…
renatobecker Feb 27, 2018
587ffda
Started working on send visitor navigation history as a message to ag…
renatobecker Feb 28, 2018
460b76b
- Sending the navigation history of the visitor as a message;
renatobecker Mar 9, 2018
221c595
Fix Ci build validations.
renatobecker Mar 12, 2018
bc8c03d
Fix PR review.
renatobecker Mar 12, 2018
5b4ec2a
Fix filter of the navigation history subscribe.
renatobecker Mar 14, 2018
57d0bf3
Fix PR review.
renatobecker Mar 14, 2018
d86fb7b
Merge branch 'develop' into send-visitor-navigaton-history-as-a-message
renatobecker May 18, 2018
cacc518
Merge branch 'develop' into send-visitor-navigaton-history-as-a-message
renatobecker May 29, 2018
a25f9ea
New feature added to send messages related to Livechat visitor naviga…
renatobecker May 29, 2018
632baf1
Fix codacy-bot review issues.
renatobecker May 29, 2018
f4c62d8
Merge branch 'develop' into send-visitor-navigaton-history-as-a-message
sampaiodiego Jun 4, 2018
d314565
Fix coding styling
sampaiodiego Jun 5, 2018
2cc736b
Do not return message on pageVisited method
sampaiodiego Jun 5, 2018
bf90817
Better styling for navigation history messages
sampaiodiego Jun 5, 2018
b2535ea
Improved livechat history migration to run faster
sampaiodiego Jun 5, 2018
cb2274d
Disable showing livechat navigation history as message by default
sampaiodiego Jun 5, 2018
c086d6c
Better visitor navigation translation
sampaiodiego Jun 5, 2018
b350a0b
Remove unnecessary files
sampaiodiego Jun 5, 2018
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
4 changes: 4 additions & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,7 @@
"False": "False",
"Favorite_Rooms": "Enable Favorite Rooms",
"Favorites": "Favorites",
"Feature_Depends_on_Livechat_Visitor_navigation_as_a_message_to_be_enabled": "This feature depends on \"Send Visitor Navigation History as a Message\" to be enabled.",
"Features_Enabled": "Features Enabled",
"Field": "Field",
"Field_removed": "Field removed",
Expand Down Expand Up @@ -1463,6 +1464,8 @@
"Mobile_Notifications_Default_Alert": "Mobile Notifications Default Alert",
"Monday": "Monday",
"Monitor_history_for_changes_on": "Monitor History for Changes on",
"Send_Visitor_navigation_history_as_a_message": "Send Visitor Navigation History as a Message",
"Send_visitor_navigation_history_on_request": "Send Visitor Navigation History on Request",
"More_channels": "More channels",
"More_direct_messages": "More direct messages",
"More_groups": "More private groups",
Expand Down Expand Up @@ -1505,6 +1508,7 @@
"New_Trigger": "New Trigger",
"New_version_available_(s)": "New version available (%s)",
"New_videocall_request": "New Video Call Request",
"New_visitor_navigation": "New Navigation: __history__",
"No_available_agents_to_transfer": "No available agents to transfer",
"No_channel_with_name_%s_was_found": "No channel with name <strong>\"%s\"</strong> was found!",
"No_channels_yet": "You aren't part of any channel yet",
Expand Down
6 changes: 5 additions & 1 deletion packages/rocketchat-i18n/i18n/pt-BR.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,7 @@
"False": "Não",
"Favorite_Rooms": "Ativar salas favoritas",
"Favorites": "Favoritos",
"Feature_Depends_on_Livechat_Visitor_navigation_as_a_message_to_be_enabled": "Esta Funcionalidade depende que \"Enviar histórico de navegação do visitante como mensagem\" esteja habilitada.",
"Features_Enabled": "Funcionalidades habilitadas",
"Field": "Campo",
"Field_removed": "Campo removido",
Expand Down Expand Up @@ -1458,6 +1459,7 @@
"New_Trigger": "Novo Gatilho",
"New_version_available_(s)": "Nova versão disponível (% s)",
"New_videocall_request": "Nova requisição de chamada de vídeo",
"New_visitor_navigation": "Nova Navegação: __history__",
"No_available_agents_to_transfer": "Nenhum agente disponível para transferir",
"No_channel_with_name_%s_was_found": "Nenhum canal com nome <strong>\"%s\"</strong> foi encontrado!",
"No_channels_yet": "Você não faz parte de nenhum canal ainda.",
Expand Down Expand Up @@ -1818,6 +1820,8 @@
"Send_request_on_visitor_message": "Enviar requisição para mensagens do Visitante",
"Send_request_on_agent_message": "Enviar requisição para mensagens do Agente",
"Send_Test": "Enviar teste",
"Send_Visitor_navigation_history_as_a_message": "Enviar histórico de navegação do visitante como mensagem",
"Send_visitor_navigation_history_on_request": "Enviar histórico de navegação do visitante na requisição",
"Send_welcome_email": "Enviar e-mail de boas-vindas",
"Send_your_JSON_payloads_to_this_URL": "Envie seu payload JSON para esta URL.",
"Sending": "Enviando ...",
Expand Down Expand Up @@ -2348,4 +2352,4 @@
"your_message_optional": "sua mensagem (opcional)",
"Your_password_is_wrong": "Sua senha está errada!",
"Your_push_was_sent_to_s_devices": "Sua notificação foi enviada para %s dispositivos"
}
}
39 changes: 39 additions & 0 deletions packages/rocketchat-lib/server/models/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,17 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base {
return this.findOne(query);
}

findByRoomIdAndType(roomId, type, options) {
const query = {
rid: roomId,
t: type
};

if (options == null) { options = {}; }

return this.find(query, options);
}

findByRoomId(roomId, options) {
const query = {
rid: roomId
Expand Down Expand Up @@ -569,6 +580,34 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base {
return record;
}

createNavigationHistoryWithRoomIdMessageAndUser(roomId, message, user, extraData) {
const type = 'livechat_navigation_history';
const room = RocketChat.models.Rooms.findOneById(roomId, { fields: { sysMes: 1 }});
if ((room != null ? room.sysMes : undefined) === false) {
return;
}
const record = {
t: type,
rid: roomId,
ts: new Date,
msg: message,
u: {
_id: user._id,
username: user.username
},
groupable: false
};

if (RocketChat.settings.get('Message_Read_Receipt_Enabled')) {
record.unread = true;
}

_.extend(record, extraData);

record._id = this.insertOrUpsert(record);
return record;
}

createUserJoinWithRoomIdAndUser(roomId, user, extraData) {
const message = user.username;
return this.createWithTypeRoomIdMessageAndUser('uj', roomId, message, user, extraData);
Expand Down
2 changes: 1 addition & 1 deletion packages/rocketchat-livechat/.app/client/lib/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const api = {
Triggers.processRequest(info);
}

Meteor.call('livechat:pageVisited', visitor.getToken(), info);
Meteor.call('livechat:pageVisited', visitor.getToken(), visitor.getRoom(), info);
},

setCustomField(key, value, overwrite = true) {
Expand Down
2 changes: 1 addition & 1 deletion packages/rocketchat-livechat/.app/client/views/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Template.messages.helpers({
return ChatMessage.find({
rid: visitor.getRoom(),
t: {
'$ne': 't'
'$nin': ['t', 'livechat_navigation_history']
}
}, {
sort: {
Expand Down
3 changes: 2 additions & 1 deletion packages/rocketchat-livechat/.app/imports/client/visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,11 @@ export default {

this.roomSubscribed = roomId;

const msgTypesNotDisplayed = ['livechat_video_call', 'livechat_navigation_history', 'au'];
msgStream.on(roomId, { token: this.getToken() }, (msg) => {
if (msg.t === 'command') {
Commands[msg.msg] && Commands[msg.msg]();
} else if ((msg.t !== 'livechat_video_call') && (msg.t !== 'au')) {
} else if (!msgTypesNotDisplayed.includes(msg.t)) {
ChatMessage.upsert({ _id: msg._id }, msg);

if (msg.t === 'livechat-close') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ <h4>{{_ "Navigation_History"}}</h4>
{{else}}
<div class="visitor-scroll">
<ul>
{{#each pageVisited}}
<li><a href="{{page.location.href}}" target="_blank" title="{{accessDateTime}}">{{pageTitle}}</a></li>
{{#each pages}}
<li><a href="{{navigation.page.location.href}}" target="_blank" title="{{accessDateTime}}">{{pageTitle}}</a></li>
{{/each}}
</ul>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import moment from 'moment';
const visitorNavigationHistory = new Mongo.Collection('visitor_navigation_history');

Template.visitorNavigation.helpers({
loadingNavigation() {
return !Template.instance().pageVisited.ready();
},

pageVisited() {
pages() {
const room = ChatRoom.findOne({ _id: this.rid }, { fields: { 'v.token': 1 } });

if (room && room.v && room.v.token) {
return LivechatPageVisited.find({ token: room.v.token }, { sort: { ts: -1 } });
if (room) {
return visitorNavigationHistory.find({ rid: room._id }, { sort: { ts: -1 } });
}
},

pageTitle() {
return this.page.title || t('Empty_title');
return this.navigation.page.title || t('Empty_title');
},

accessDateTime() {
Expand Down
16 changes: 16 additions & 0 deletions packages/rocketchat-livechat/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,15 @@ Meteor.startup(function() {
i18nLabel: 'Send_request_on_agent_message'
});

RocketChat.settings.add('Send_visitor_navigation_history_livechat_webhook_request', false, {
type: 'boolean',
group: 'Livechat',
section: 'CRM_Integration',
i18nLabel: 'Send_visitor_navigation_history_on_request',
i18nDescription: 'Feature_Depends_on_Livechat_Visitor_navigation_as_a_message_to_be_enabled',
enableQuery: { _id: 'Livechat_Visitor_navigation_as_a_message', value: true }
});

RocketChat.settings.add('Livechat_webhook_on_capture', false, {
type: 'boolean',
group: 'Livechat',
Expand Down Expand Up @@ -236,6 +245,13 @@ Meteor.startup(function() {
]
});

RocketChat.settings.add('Livechat_Visitor_navigation_as_a_message', false, {
type: 'boolean',
group: 'Livechat',
public: true,
i18nLabel: 'Send_Visitor_navigation_history_as_a_message'
});

RocketChat.settings.add('Livechat_enable_office_hours', false, {
type: 'boolean',
group: 'Livechat',
Expand Down
14 changes: 14 additions & 0 deletions packages/rocketchat-livechat/messageTypes.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
RocketChat.MessageTypes.registerType({
id: 'livechat_navigation_history',
system: true,
message: 'New_visitor_navigation',
data(message) {
if (!message.navigation || !message.navigation.page) {
return;
}
return {
history: `${ (message.navigation.page.title ? `${ message.navigation.page.title } - ` : '') + message.navigation.page.location.href }`
};
}
});

RocketChat.MessageTypes.registerType({
id: 'livechat_video_call',
system: true,
Expand Down
1 change: 1 addition & 0 deletions packages/rocketchat-livechat/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ Package.onUse(function(api) {
// models
api.addFiles('server/models/Users.js', 'server');
api.addFiles('server/models/Rooms.js', 'server');
api.addFiles('server/models/Messages.js', 'server');
api.addFiles('server/models/LivechatExternalMessage.js', ['client', 'server']);
api.addFiles('server/models/LivechatCustomField.js', 'server');
api.addFiles('server/models/LivechatDepartment.js', 'server');
Expand Down
19 changes: 16 additions & 3 deletions packages/rocketchat-livechat/server/hooks/sendToCRM.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
const msgNavType = 'livechat_navigation_history';

const sendMessageType = (msgType) => {
const sendNavHistory = RocketChat.settings.get('Livechat_Visitor_navigation_as_a_message') && RocketChat.settings.get('Send_visitor_navigation_history_livechat_webhook_request');

return sendNavHistory && msgType === msgNavType;
};

function sendToCRM(type, room, includeMessages = true) {
const postData = RocketChat.Livechat.getLivechatRoomGuestInfo(room);

Expand All @@ -14,7 +22,7 @@ function sendToCRM(type, room, includeMessages = true) {

if (messages) {
messages.forEach((message) => {
if (message.t) {
if (message.t && !sendMessageType(message.t)) {
return;
}
const msg = {
Expand All @@ -28,6 +36,11 @@ function sendToCRM(type, room, includeMessages = true) {
if (message.u.username !== postData.visitor.username) {
msg.agentId = message.u._id;
}

if (message.t === msgNavType) {
msg.navigation = message.navigation;
}

postData.messages.push(msg);
});
}
Expand Down Expand Up @@ -73,9 +86,9 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) {
} else if (!RocketChat.settings.get('Livechat_webhook_on_agent_message')) {
return message;
}

// if the message has a type means it is a special message (like the closing comment), so skips
if (message.t) {
// unless the settings that handle with visitor navigation history are enabled
if (message.t && !sendMessageType(message.t)) {
return message;
}

Expand Down
30 changes: 28 additions & 2 deletions packages/rocketchat-livechat/server/lib/Livechat.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ RocketChat.Livechat = {
throw new Meteor.Error('cannot-access-room');
}

if (newRoom) {
RocketChat.models.Messages.setRoomIdByToken(guest.token, room._id);
}

return { room, newRoom };
},
sendMessage({ guest, message, roomInfo, agent }) {
Expand Down Expand Up @@ -315,9 +319,31 @@ RocketChat.Livechat = {
});
},

savePageHistory(token, pageInfo) {
savePageHistory(token, roomId, pageInfo) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need to receive roomId here.. we can rely on RocketChat.models.Rooms.findOneOpenByVisitorToken to get visitor's current room.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sampaiodiego, the RocketChat.models.Rooms.findOneOpenByVisitorToken has a roomId parameter, due to this I changed the savePageHistory to get this parameter.
How can I call the RocketChat.models.Rooms.findOneOpenByVisitorToken method if I don't pass the roomId parameter?
I'm sorry if I'm making a mistake but I think this parameter is necessary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're correct @renatobecker .. I didn't notice RocketChat.models.Rooms.findOneOpenByVisitorToken has a roomId parameter as well. 😉
I'll give this PR a whole review to see how we could still save visitor's navigation history without a room.

if (pageInfo.change === RocketChat.Livechat.historyMonitorType) {
return RocketChat.models.LivechatPageVisited.saveByToken(token, pageInfo);

const user = RocketChat.models.Users.findOneById('rocket.cat');

const pageTitle = pageInfo.title;
const pageUrl = pageInfo.location.href;
const extraData = {
navigation: {
page: pageInfo,
token
}
};

if (!roomId) {
// keep history of unregistered visitors for 1 month
const keepHistoryMiliseconds = 2592000000;
extraData.expireAt = new Date().getTime() + keepHistoryMiliseconds;
}

if (!RocketChat.settings.get('Livechat_Visitor_navigation_as_a_message')) {
extraData._hidden = true;
}

return RocketChat.models.Messages.createNavigationHistoryWithRoomIdMessageAndUser(roomId, `${ pageTitle } - ${ pageUrl }`, user, extraData);
}

return;
Expand Down
4 changes: 2 additions & 2 deletions packages/rocketchat-livechat/server/methods/pageVisited.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Meteor.methods({
'livechat:pageVisited'(token, pageInfo) {
return RocketChat.Livechat.savePageHistory(token, pageInfo);
'livechat:pageVisited'(token, room, pageInfo) {
RocketChat.Livechat.savePageHistory(token, room, pageInfo);
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Meteor.methods({
});

// update visited page history to not expire
RocketChat.models.LivechatPageVisited.keepHistoryForToken(token);
RocketChat.models.Messages.keepHistoryForToken(token);

return {
userId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Meteor.methods({
throw new Meteor.Error('error-invalid-room', 'Invalid room');
}

const messages = RocketChat.models.Messages.findVisibleByRoomId(rid, { sort: { 'ts' : 1 }});
const messages = RocketChat.models.Messages.findVisibleByRoomIdNotContainingTypes(rid, ['livechat_navigation_history'], { sort: { 'ts' : 1 }});
const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || '');
const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || '');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Meteor.methods({
});

// update visited page history to not expire
RocketChat.models.LivechatPageVisited.keepHistoryForToken(token);
RocketChat.models.Messages.keepHistoryForToken(token);

return true;
}
Expand Down
27 changes: 27 additions & 0 deletions packages/rocketchat-livechat/server/models/Messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
RocketChat.models.Messages.keepHistoryForToken = function(token) {
return this.update({
'navigation.token': token,
expireAt: {
$exists: true
}
}, {
$unset: {
expireAt: 1
}
}, {
multi: true
});
};

RocketChat.models.Messages.setRoomIdByToken = function(token, rid) {
return this.update({
'navigation.token': token,
rid: null
}, {
$set: {
rid
}
}, {
multi: true
});
};
Loading