-
Notifications
You must be signed in to change notification settings - Fork 13.1k
[NEW] Livechat analytics #15230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NEW] Livechat analytics #15230
Conversation
app/livechat/server/lib/Livechat.js
Outdated
| }, | ||
|
|
||
| saveTransferHistory(room, transferData) { | ||
| const transferedToDepartment = Boolean(transferData.departmentId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would use destructuring assignment here:
| const transferedToDepartment = Boolean(transferData.departmentId); | |
| const { departmentId: previousDepartment, servedBy: { _id: previousAgent } = {} } = room; | |
| const { departmentId: nextDepartment, userId: nextAgent, transferedBy } = transferData; | |
| const transferedToDepartment = Boolean(transferData.departmentId); |
renatobecker-zz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few typo fixes.
| const transferData = { | ||
| roomId, | ||
| departmentId, | ||
| transferedBy: visitor._id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| transferedBy: visitor._id, | |
| transferredBy: visitor._id, |
app/livechat/server/lib/Livechat.js
Outdated
| scope: nextDepartment ? 'department' : 'agent', | ||
| ...previousDepartment && { previousDepartment }, | ||
| ...nextDepartment && { nextDepartment }, | ||
| ...transferedTo && { transferedTo }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ...transferedTo && { transferedTo }, | |
| ...transferredTo && { transferredTo }, |
|
|
||
| const guest = LivechatVisitors.findOneById(room.v && room.v._id); | ||
| const user = Meteor.user(); | ||
| transferData.transferedBy = { _id: user._id, username: user.username }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| transferData.transferedBy = { _id: user._id, username: user.username }; | |
| const { _id, username } = user || {}; | |
| transferData.transferredBy = { _id, username }; |
app/livechat/server/lib/Livechat.js
Outdated
|
|
||
| saveTransferHistory(room, transferData) { | ||
| const { departmentId: previousDepartment } = room; | ||
| const { departmentId: nextDepartment, transferedBy, transferedTo } = transferData; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const { departmentId: nextDepartment, transferedBy, transferedTo } = transferData; | |
| const { departmentId: nextDepartment, transferredBy, transferedTo } = transferData; |
app/livechat/server/api/v1/room.js
Outdated
| Messages.keepHistoryForToken(token); | ||
|
|
||
| if (!Promise.await(Livechat.transfer(room, guest, { roomId: rid, departmentId: department }))) { | ||
| const transferedBy = { _id: room.servedBy._id, username: room.servedBy.username }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Through this endpoint, the transfer process is requested from the visitor, not the current room agent.
| const transferData = { | ||
| roomId, | ||
| departmentId, | ||
| transferedBy: visitor._id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the transferedBy prop is an object, right?
| const update = { | ||
| $inc: { availableTime }, | ||
| $set: { | ||
| lastStopedAt, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| lastStopedAt, | |
| lastStoppedAt, |
| return this.update(query, update); | ||
| } | ||
|
|
||
| updateServiceHistory({ agentId, date, historyObject }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| updateServiceHistory({ agentId, date, historyObject }) { | |
| updateServiceHistory({ agentId, date, serviceHistory }) { |
| }; | ||
| const update = { | ||
| $addToSet: { | ||
| serviceHistory: historyObject, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| serviceHistory: historyObject, | |
| serviceHistory, |
| return this.remove(query); | ||
| } | ||
|
|
||
| updateTransferHistoryByRoomId(roomId, transfer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| updateTransferHistoryByRoomId(roomId, transfer) { | |
| updateTransferHistoryByRoomId(roomId, transferHistory) { |
| }; | ||
| const update = { | ||
| $addToSet: { | ||
| transferHistory: transfer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| transferHistory: transfer, | |
| transferHistory, |
renatobecker-zz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to define when the user who is transferring is the visitor.
app/livechat/server/api/v1/room.js
Outdated
| import { API } from '../../../../api'; | ||
| import { findGuest, findRoom, getRoom, settings, findAgent } from '../lib/livechat'; | ||
| import { Livechat } from '../../lib/Livechat'; | ||
| import { getTransferredData } from '../../lib/Helper'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| import { getTransferredData } from '../../lib/Helper'; | |
| import { normalizeTransferredByData } from '../../lib/Helper'; |
app/livechat/server/api/v1/room.js
Outdated
| Messages.keepHistoryForToken(token); | ||
|
|
||
| if (!Promise.await(Livechat.transfer(room, guest, { roomId: rid, departmentId: department }))) { | ||
| const transferredBy = getTransferredData(guest, room); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const transferredBy = getTransferredData(guest, room); | |
| const data = { _id, username, type: 'visitor' } = guest; | |
| const transferredBy = normalizeTransferredByData(data, room); |
app/livechat/server/lib/Helper.js
Outdated
| return true; | ||
| }; | ||
|
|
||
| export const getTransferredData = (transferredBy, room) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| export const getTransferredData = (transferredBy, room) => { | |
| export const normalizeTransferredByData = (transferredBy, room) => { |
| if (!transferredBy || !room) { | ||
| throw new Error('You must provide "transferredBy" and "room" params to "getTransferredByData"'); | ||
| } | ||
| return { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return { | |
| const { servedBy: { _id: agentId } = {} } = room; | |
| const { _id, username, type: transferType } = transferredBy; | |
| const type = transferType || (_id === agentId ? 'agent' : 'user'); | |
| return { | |
| _id, | |
| username, | |
| type, |
|
|
||
| import { LivechatRooms, Messages, LivechatVisitors } from '../../../models'; | ||
| import { Livechat } from '../lib/Livechat'; | ||
| import { getTransferredData } from '../lib/Helper'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| import { getTransferredData } from '../lib/Helper'; | |
| import { normalizeTransferredByData } from '../lib/Helper'; |
| const transferData = { | ||
| roomId, | ||
| departmentId, | ||
| transferredBy: getTransferredData(visitor, room), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| transferredBy: getTransferredData(visitor, room), | |
| transferredBy: normalizeTransferredByData(data, room), |
| import { LivechatRooms, Subscriptions, LivechatVisitors } from '../../../models'; | ||
| import { LivechatRooms, Subscriptions, LivechatVisitors, Users } from '../../../models'; | ||
| import { Livechat } from '../lib/Livechat'; | ||
| import { getTransferredData } from '../lib/Helper'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| import { getTransferredData } from '../lib/Helper'; | |
| import { normalizeTransferredByData } from '../lib/Helper'; |
| } | ||
|
|
||
| const guest = LivechatVisitors.findOneById(room.v && room.v._id); | ||
| transferData.transferredBy = getTransferredData(Meteor.user() || {}, room); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| transferData.transferredBy = getTransferredData(Meteor.user() || {}, room); | |
| transferData.transferredBy = normalizeTransferredByData(Meteor.user() || {}, room); |
app/livechat/server/lib/Livechat.js
Outdated
| status, | ||
| }); | ||
| }); | ||
| callbacks.runAsync('livechat.agentStatusChanged', { userId, status }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This callback doesn't depend on the 'Livechat_show_agent_info setting, so I suggest to run the callback at the beginning of the method, before testing the Livechat_show_agent_info setting.
app/livechat/server/lib/Livechat.js
Outdated
| if (!result) { | ||
| return false; | ||
| } | ||
| this.saveTransferHistory(room, transferData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| this.saveTransferHistory(room, transferData); | |
| return this.saveTransferHistory(room, transferData); |
app/livechat/server/lib/Livechat.js
Outdated
| ...nextDepartment && { nextDepartment }, | ||
| ...transferredTo && { transferredTo }, | ||
| }; | ||
| LivechatRooms.updateTransferHistoryByRoomId(room._id, transfer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| LivechatRooms.updateTransferHistoryByRoomId(room._id, transfer); | |
| return LivechatRooms.updateTransferHistoryByRoomId(room._id, transfer); |
| } | ||
|
|
||
| start() { | ||
| this._setupListeners(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would not it be good to have a property to store when the monitor starts? Otherwise, in case the start() is called again, new callbacks will be assigned and duplicated, right?
|
This pull request introduces 4 alerts when merging 0aa93f0 into a8ad42b - view on LGTM.com new alerts:
|
|
This pull request introduces 2 alerts when merging 2421b94 into a8ad42b - view on LGTM.com new alerts:
|
app/apps/server/bridges/livechat.js
Outdated
| this.orch.getConverters().get('rooms').convertAppRoom(currentRoom), | ||
| this.orch.getConverters().get('visitors').convertAppVisitor(visitor), | ||
| { userId: targetAgent.id, departmentId } | ||
| { userId: targetAgent.id, department: LivechatDepartment.findOneById(departmentId) }, |
There was a problem hiding this comment.
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 read the model here, you can do it inside the Livechat.transfer.
app/livechat/server/api/v1/room.js
Outdated
| if (!Promise.await(Livechat.transfer(room, guest, { roomId: rid, departmentId: department }))) { | ||
| const { _id, username, name } = guest; | ||
| const transferredBy = normalizeTransferredByData({ _id, username, name, userType: 'visitor' }, room); | ||
| const department = LivechatDepartment.findOneById(departmentId); |
There was a problem hiding this comment.
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 read the model here, you can do it inside the Livechat.transfer.
app/livechat/server/lib/Livechat.js
Outdated
| const user = Users.findOneById(userId); | ||
| const { _id, username, name } = user; | ||
| const transferredBy = normalizeTransferredByData({ _id, username, name }, room); | ||
| this.transfer(room, guest, { roomId: room._id, transferredBy, department: LivechatDepartment.findOneById(guest.department) }); |
There was a problem hiding this comment.
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 read the model here, you can do it inside the Livechat.transfer.
|
|
||
| const guest = LivechatVisitors.findOneById(room.v && room.v._id); | ||
| transferData.transferredBy = normalizeTransferredByData(Meteor.user() || {}, room); | ||
| transferData.department = LivechatDepartment.findOneById(transferData.departmentId); |
There was a problem hiding this comment.
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 read the model here, you can do it inside the Livechat.transfer.
| if (!room.open) { | ||
| throw new Meteor.Error('room-closed', 'Room closed', { method: 'livechat:returnAsInquiry' }); | ||
| } | ||
| const transferredBy = normalizeTransferredByData(Meteor.user() || {}, room); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you already pass all the information you need through the Livechat.returnRoomAsInquiry, why not processing the transferData inside the Livechat.returnRoomAsInquiry?
IMO it would reduce the complexity of the algorithm.
| return this.remove(query); | ||
| } | ||
|
|
||
| updateTransferHistoryByRoomId(roomId, transferHistory) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need this method anymore.
renatobecker-zz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changes may fixe the problem related to the order of the events when forwarding and returning the chat to the queue, what do you think?
| } | ||
|
|
||
| this.saveTransferHistory(room, transferData); | ||
| return RoutingManager.unassignAgent(inquiry, departmentId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return RoutingManager.unassignAgent(inquiry, departmentId); | |
| return RoutingManager.unassignAgent(inquiry, departmentId) && this.saveTransferHistory(room, transferData); |
|
|
||
| async transfer(room, guest, transferData) { | ||
| return RoutingManager.transferRoom(room, guest, transferData); | ||
| const result = await RoutingManager.transferRoom(room, guest, transferData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const result = await RoutingManager.transferRoom(room, guest, transferData); | |
| const result = await RoutingManager.transferRoom(room, guest, transferData) && this.saveTransferHistory(room, transferData); |
No description provided.