diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json
index 6ae6a4c42f0f..4c04064432c9 100644
--- a/packages/rocketchat-i18n/i18n/en.i18n.json
+++ b/packages/rocketchat-i18n/i18n/en.i18n.json
@@ -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",
@@ -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",
@@ -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 \"%s\" was found!",
"No_channels_yet": "You aren't part of any channel yet",
diff --git a/packages/rocketchat-i18n/i18n/pt-BR.i18n.json b/packages/rocketchat-i18n/i18n/pt-BR.i18n.json
index dc3e0d9f01e4..ed5812e037ac 100644
--- a/packages/rocketchat-i18n/i18n/pt-BR.i18n.json
+++ b/packages/rocketchat-i18n/i18n/pt-BR.i18n.json
@@ -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",
@@ -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 \"%s\" foi encontrado!",
"No_channels_yet": "Você não faz parte de nenhum canal ainda.",
@@ -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 ...",
@@ -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"
-}
\ No newline at end of file
+}
diff --git a/packages/rocketchat-lib/server/models/Messages.js b/packages/rocketchat-lib/server/models/Messages.js
index 80792259960a..763f62a3b9fd 100644
--- a/packages/rocketchat-lib/server/models/Messages.js
+++ b/packages/rocketchat-lib/server/models/Messages.js
@@ -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
@@ -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);
diff --git a/packages/rocketchat-livechat/.app/client/lib/hooks.js b/packages/rocketchat-livechat/.app/client/lib/hooks.js
index 3a525c34cf5d..89436156dc19 100644
--- a/packages/rocketchat-livechat/.app/client/lib/hooks.js
+++ b/packages/rocketchat-livechat/.app/client/lib/hooks.js
@@ -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) {
diff --git a/packages/rocketchat-livechat/.app/client/views/messages.js b/packages/rocketchat-livechat/.app/client/views/messages.js
index f27e7d00f2d3..3f48ab191fe0 100644
--- a/packages/rocketchat-livechat/.app/client/views/messages.js
+++ b/packages/rocketchat-livechat/.app/client/views/messages.js
@@ -7,7 +7,7 @@ Template.messages.helpers({
return ChatMessage.find({
rid: visitor.getRoom(),
t: {
- '$ne': 't'
+ '$nin': ['t', 'livechat_navigation_history']
}
}, {
sort: {
diff --git a/packages/rocketchat-livechat/.app/imports/client/visitor.js b/packages/rocketchat-livechat/.app/imports/client/visitor.js
index 75e45843e7bd..76bd78956f18 100644
--- a/packages/rocketchat-livechat/.app/imports/client/visitor.js
+++ b/packages/rocketchat-livechat/.app/imports/client/visitor.js
@@ -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') {
diff --git a/packages/rocketchat-livechat/client/views/app/tabbar/visitorNavigation.html b/packages/rocketchat-livechat/client/views/app/tabbar/visitorNavigation.html
index b6fc919ce506..be44263dd093 100644
--- a/packages/rocketchat-livechat/client/views/app/tabbar/visitorNavigation.html
+++ b/packages/rocketchat-livechat/client/views/app/tabbar/visitorNavigation.html
@@ -8,8 +8,8 @@
{{_ "Navigation_History"}}
{{else}}
diff --git a/packages/rocketchat-livechat/client/views/app/tabbar/visitorNavigation.js b/packages/rocketchat-livechat/client/views/app/tabbar/visitorNavigation.js
index 06a62d8a7d0d..3679a2d1b7ce 100644
--- a/packages/rocketchat-livechat/client/views/app/tabbar/visitorNavigation.js
+++ b/packages/rocketchat-livechat/client/views/app/tabbar/visitorNavigation.js
@@ -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() {
diff --git a/packages/rocketchat-livechat/config.js b/packages/rocketchat-livechat/config.js
index 242351f2b909..236da5c59013 100644
--- a/packages/rocketchat-livechat/config.js
+++ b/packages/rocketchat-livechat/config.js
@@ -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',
@@ -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',
diff --git a/packages/rocketchat-livechat/messageTypes.js b/packages/rocketchat-livechat/messageTypes.js
index 670ae5b5b8c2..631ecc47166f 100644
--- a/packages/rocketchat-livechat/messageTypes.js
+++ b/packages/rocketchat-livechat/messageTypes.js
@@ -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,
diff --git a/packages/rocketchat-livechat/package.js b/packages/rocketchat-livechat/package.js
index 374874fd56e2..537db759cac5 100644
--- a/packages/rocketchat-livechat/package.js
+++ b/packages/rocketchat-livechat/package.js
@@ -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');
diff --git a/packages/rocketchat-livechat/server/hooks/sendToCRM.js b/packages/rocketchat-livechat/server/hooks/sendToCRM.js
index 46e48dcc70fe..fe4f68218063 100644
--- a/packages/rocketchat-livechat/server/hooks/sendToCRM.js
+++ b/packages/rocketchat-livechat/server/hooks/sendToCRM.js
@@ -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);
@@ -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 = {
@@ -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);
});
}
@@ -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;
}
diff --git a/packages/rocketchat-livechat/server/lib/Livechat.js b/packages/rocketchat-livechat/server/lib/Livechat.js
index 2a98b4ace411..c8e19915cb74 100644
--- a/packages/rocketchat-livechat/server/lib/Livechat.js
+++ b/packages/rocketchat-livechat/server/lib/Livechat.js
@@ -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 }) {
@@ -315,9 +319,31 @@ RocketChat.Livechat = {
});
},
- savePageHistory(token, pageInfo) {
+ savePageHistory(token, roomId, pageInfo) {
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;
diff --git a/packages/rocketchat-livechat/server/methods/pageVisited.js b/packages/rocketchat-livechat/server/methods/pageVisited.js
index 25027f03d597..0097ac4aab5b 100644
--- a/packages/rocketchat-livechat/server/methods/pageVisited.js
+++ b/packages/rocketchat-livechat/server/methods/pageVisited.js
@@ -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);
}
});
diff --git a/packages/rocketchat-livechat/server/methods/registerGuest.js b/packages/rocketchat-livechat/server/methods/registerGuest.js
index 5cef4e7c19a4..0e021d5e6bcb 100644
--- a/packages/rocketchat-livechat/server/methods/registerGuest.js
+++ b/packages/rocketchat-livechat/server/methods/registerGuest.js
@@ -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
diff --git a/packages/rocketchat-livechat/server/methods/sendTranscript.js b/packages/rocketchat-livechat/server/methods/sendTranscript.js
index 949642ab232e..a53e271d4380 100644
--- a/packages/rocketchat-livechat/server/methods/sendTranscript.js
+++ b/packages/rocketchat-livechat/server/methods/sendTranscript.js
@@ -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') || '');
diff --git a/packages/rocketchat-livechat/server/methods/setDepartmentForVisitor.js b/packages/rocketchat-livechat/server/methods/setDepartmentForVisitor.js
index da77d2c2305c..0c4f40598477 100644
--- a/packages/rocketchat-livechat/server/methods/setDepartmentForVisitor.js
+++ b/packages/rocketchat-livechat/server/methods/setDepartmentForVisitor.js
@@ -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;
}
diff --git a/packages/rocketchat-livechat/server/models/Messages.js b/packages/rocketchat-livechat/server/models/Messages.js
new file mode 100644
index 000000000000..da2046be7426
--- /dev/null
+++ b/packages/rocketchat-livechat/server/models/Messages.js
@@ -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
+ });
+};
diff --git a/packages/rocketchat-livechat/server/models/Rooms.js b/packages/rocketchat-livechat/server/models/Rooms.js
index 6786e71f3ac1..7ac8f0445caf 100644
--- a/packages/rocketchat-livechat/server/models/Rooms.js
+++ b/packages/rocketchat-livechat/server/models/Rooms.js
@@ -63,6 +63,21 @@ RocketChat.models.Rooms.findLivechatById = function(_id, fields) {
return this.findOne(query, options);
};
+RocketChat.models.Rooms.findLivechatById = function(_id, fields) {
+ const options = {};
+
+ if (fields) {
+ options.fields = fields;
+ }
+
+ const query = {
+ t: 'l',
+ _id
+ };
+
+ return this.findOne(query, options);
+};
+
/**
* Get the next visitor name
* @return {string} The next visitor name
diff --git a/packages/rocketchat-livechat/server/publications/visitorPageVisited.js b/packages/rocketchat-livechat/server/publications/visitorPageVisited.js
index 8420694b8138..72d7b42df3b1 100644
--- a/packages/rocketchat-livechat/server/publications/visitorPageVisited.js
+++ b/packages/rocketchat-livechat/server/publications/visitorPageVisited.js
@@ -1,4 +1,5 @@
Meteor.publish('livechat:visitorPageVisited', function({ rid: roomId }) {
+
if (!this.userId) {
return this.error(new Meteor.Error('error-not-authorized', 'Not authorized', { publish: 'livechat:visitorPageVisited' }));
}
@@ -7,11 +8,28 @@ Meteor.publish('livechat:visitorPageVisited', function({ rid: roomId }) {
return this.error(new Meteor.Error('error-not-authorized', 'Not authorized', { publish: 'livechat:visitorPageVisited' }));
}
+ const self = this;
const room = RocketChat.models.Rooms.findOneById(roomId);
- if (room && room.v && room.v.token) {
- return RocketChat.models.LivechatPageVisited.findByToken(room.v.token);
+ if (room) {
+ const handle = RocketChat.models.Messages.findByRoomIdAndType(room._id, 'livechat_navigation_history').observeChanges({
+ added(id, fields) {
+ self.added('visitor_navigation_history', id, fields);
+ },
+ changed(id, fields) {
+ self.changed('visitor_navigation_history', id, fields);
+ },
+ removed(id) {
+ self.removed('visitor_navigation_history', id);
+ }
+ });
+
+ self.ready();
+
+ self.onStop(function() {
+ handle.stop();
+ });
} else {
- return this.ready();
+ self.ready();
}
});
diff --git a/packages/rocketchat-theme/client/imports/general/base_old.css b/packages/rocketchat-theme/client/imports/general/base_old.css
index 7005727ff8a3..78602ce7ecab 100644
--- a/packages/rocketchat-theme/client/imports/general/base_old.css
+++ b/packages/rocketchat-theme/client/imports/general/base_old.css
@@ -3271,6 +3271,12 @@
font-weight: 400;
}
+
+ &.livechat_navigation_history {
+ & .thumb, & .user, & .info {
+ display: none;
+ }
+ }
}
.rc-old .image-labels {
diff --git a/server/startup/migrations/v123.js b/server/startup/migrations/v123.js
new file mode 100644
index 000000000000..e1e0b7b4fe1e
--- /dev/null
+++ b/server/startup/migrations/v123.js
@@ -0,0 +1,89 @@
+let pageVisitedCollection;
+let messageCollection;
+let roomCollection;
+
+const roomIdByToken = {};
+
+const batchSize = 5000;
+
+async function migrateHistory(total, current) {
+ console.log(`Livechat history migration ${ current }/${ total }`);
+
+ const items = await pageVisitedCollection.find({}).limit(batchSize).toArray();
+
+ const tokens = items.filter((item) => item.token && !roomIdByToken[item.token]).map((item) => item.token);
+ const rooms = await roomCollection.find({
+ 'v.token': {
+ $in: tokens
+ }
+ }, {
+ fields: {
+ 'v.token': 1
+ }
+ }).toArray();
+
+ rooms.forEach((room) => {
+ roomIdByToken[room.v.token] = room._id;
+ });
+
+ const actions = items.reduce((result, item) => {
+ const msg = {
+ t: 'livechat_navigation_history',
+ rid: roomIdByToken[item.token] || null, // prevent from being `undefined`
+ ts: item.ts,
+ msg: `${ item.page.title } - ${ item.page.location.href }`,
+ u: {
+ _id : 'rocket.cat',
+ username : 'rocket.cat'
+ },
+ groupable : false,
+ navigation : {
+ page: item.page,
+ token: item.token
+ }
+ };
+ if (!roomIdByToken[item.token] && item.expireAt) {
+ msg.expireAt = item.expireAt;
+ }
+ result.insert.push(msg);
+ result.remove.push(item._id);
+
+ return result;
+ }, { insert: [], remove: [] });
+
+ const batch = Promise.all([
+ messageCollection.insertMany(actions.insert),
+ pageVisitedCollection.removeMany({ _id: { $in: actions.remove } })
+ ]);
+ if (actions.remove.length === batchSize) {
+ await batch;
+ return migrateHistory(total, current + batchSize);
+ }
+
+ return batch;
+}
+
+
+RocketChat.Migrations.add({
+ version: 123,
+ up() {
+ pageVisitedCollection = RocketChat.models.LivechatPageVisited.model.rawCollection();
+ messageCollection = RocketChat.models.Messages.model.rawCollection();
+ roomCollection = RocketChat.models.Rooms.model.rawCollection();
+
+ /*
+ * Move visitor navigation history to messages
+ */
+ Meteor.setTimeout(async() => {
+ const pages = pageVisitedCollection.find({});
+ const total = await pages.count();
+ await pages.close();
+
+ console.log('Migrating livechat visitors navigation history to livechat messages. This might take a long time ...');
+
+ await migrateHistory(total, 0);
+
+ console.log('Livechat visitors navigation history migration finished.');
+ }, 1000);
+ }
+});