|
|
|
|
@ -1,73 +1,61 @@ |
|
|
|
|
import { Meteor } from 'meteor/meteor'; |
|
|
|
|
import type { ILivechatDepartment, ILivechatInquiryRecord, IOmnichannelAgent } from '@rocket.chat/core-typings'; |
|
|
|
|
|
|
|
|
|
import { APIClient, getUserPreference } from '../../../../utils/client'; |
|
|
|
|
import { APIClient } from '../../../../utils/client'; |
|
|
|
|
import { LivechatInquiry } from '../../collections/LivechatInquiry'; |
|
|
|
|
import { inquiryDataStream } from './inquiry'; |
|
|
|
|
import { callWithErrorHandling } from '../../../../../client/lib/utils/callWithErrorHandling'; |
|
|
|
|
import { CustomSounds } from '../../../../custom-sounds/client/lib/CustomSounds'; |
|
|
|
|
|
|
|
|
|
const departments = new Set(); |
|
|
|
|
|
|
|
|
|
const newInquirySound = () => { |
|
|
|
|
const userId = Meteor.userId(); |
|
|
|
|
const audioVolume = getUserPreference(userId, 'notificationsSoundVolume'); |
|
|
|
|
const newRoomNotification = getUserPreference(userId, 'newRoomNotification'); |
|
|
|
|
|
|
|
|
|
if (newRoomNotification !== 'none') { |
|
|
|
|
CustomSounds.play(newRoomNotification, { |
|
|
|
|
volume: Number((audioVolume / 100).toPrecision(2)), |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
type ILivechatInquiryWithType = ILivechatInquiryRecord & { type?: 'added' | 'removed' | 'changed' }; |
|
|
|
|
|
|
|
|
|
const events = { |
|
|
|
|
added: (inquiry) => { |
|
|
|
|
added: (inquiry: ILivechatInquiryWithType) => { |
|
|
|
|
delete inquiry.type; |
|
|
|
|
departments.has(inquiry.department) && LivechatInquiry.insert({ ...inquiry, alert: true, _updatedAt: new Date(inquiry._updatedAt) }); |
|
|
|
|
newInquirySound(); |
|
|
|
|
}, |
|
|
|
|
changed: (inquiry) => { |
|
|
|
|
changed: (inquiry: ILivechatInquiryWithType) => { |
|
|
|
|
if (inquiry.status !== 'queued' || (inquiry.department && !departments.has(inquiry.department))) { |
|
|
|
|
return LivechatInquiry.remove(inquiry._id); |
|
|
|
|
} |
|
|
|
|
delete inquiry.type; |
|
|
|
|
const saveResult = LivechatInquiry.upsert({ _id: inquiry._id }, { ...inquiry, alert: true, _updatedAt: new Date(inquiry._updatedAt) }); |
|
|
|
|
if (saveResult?.insertedId) { |
|
|
|
|
newInquirySound(); |
|
|
|
|
} |
|
|
|
|
LivechatInquiry.upsert({ _id: inquiry._id }, { ...inquiry, alert: true, _updatedAt: new Date(inquiry._updatedAt) }); |
|
|
|
|
}, |
|
|
|
|
removed: (inquiry) => LivechatInquiry.remove(inquiry._id), |
|
|
|
|
removed: (inquiry: ILivechatInquiryWithType) => LivechatInquiry.remove(inquiry._id), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const updateCollection = (inquiry) => { |
|
|
|
|
const updateCollection = (inquiry: ILivechatInquiryWithType) => { |
|
|
|
|
if (!inquiry.type) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
events[inquiry.type](inquiry); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const getInquiriesFromAPI = async () => { |
|
|
|
|
const { inquiries } = await APIClient.get('/v1/livechat/inquiries.queuedForUser'); |
|
|
|
|
const { inquiries } = await APIClient.get('/v1/livechat/inquiries.queuedForUser', {}); |
|
|
|
|
return inquiries; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const removeListenerOfDepartment = (departmentId) => { |
|
|
|
|
const removeListenerOfDepartment = (departmentId: ILivechatDepartment['_id']) => { |
|
|
|
|
inquiryDataStream.removeListener(`department/${departmentId}`, updateCollection); |
|
|
|
|
departments.delete(departmentId); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const appendListenerToDepartment = (departmentId) => { |
|
|
|
|
const appendListenerToDepartment = (departmentId: ILivechatDepartment['_id']) => { |
|
|
|
|
departments.add(departmentId); |
|
|
|
|
inquiryDataStream.on(`department/${departmentId}`, updateCollection); |
|
|
|
|
return () => removeListenerOfDepartment(departmentId); |
|
|
|
|
}; |
|
|
|
|
const addListenerForeachDepartment = (departments = []) => { |
|
|
|
|
const addListenerForeachDepartment = (departments: ILivechatDepartment['_id'][] = []) => { |
|
|
|
|
const cleanupFunctions = departments.map((department) => appendListenerToDepartment(department)); |
|
|
|
|
return () => cleanupFunctions.forEach((cleanup) => cleanup()); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const updateInquiries = async (inquiries = []) => |
|
|
|
|
const updateInquiries = async (inquiries: ILivechatInquiryRecord[] = []) => |
|
|
|
|
inquiries.forEach((inquiry) => LivechatInquiry.upsert({ _id: inquiry._id }, { ...inquiry, _updatedAt: new Date(inquiry._updatedAt) })); |
|
|
|
|
|
|
|
|
|
const getAgentsDepartments = async (userId) => { |
|
|
|
|
const { departments } = await APIClient.get(`/v1/livechat/agents/${userId}/departments`, { enabledDepartmentsOnly: true }); |
|
|
|
|
const getAgentsDepartments = async (userId: IOmnichannelAgent['_id']) => { |
|
|
|
|
const { departments } = await APIClient.get(`/v1/livechat/agents/${userId}/departments`, { enabledDepartmentsOnly: 'true' }); |
|
|
|
|
return departments; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
@ -78,9 +66,9 @@ const addGlobalListener = () => { |
|
|
|
|
return removeGlobalListener; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const subscribe = async (userId) => { |
|
|
|
|
const subscribe = async (userId: IOmnichannelAgent['_id']) => { |
|
|
|
|
const config = await callWithErrorHandling('livechat:getRoutingConfig'); |
|
|
|
|
if (config && config.autoAssignAgent) { |
|
|
|
|
if (config?.autoAssignAgent) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -89,23 +77,24 @@ const subscribe = async (userId) => { |
|
|
|
|
// Register to all depts + public queue always to match the inquiry list returned by backend
|
|
|
|
|
const cleanDepartmentListeners = addListenerForeachDepartment(agentDepartments); |
|
|
|
|
const globalCleanup = addGlobalListener(); |
|
|
|
|
const inquiriesFromAPI = (await getInquiriesFromAPI()) as unknown as ILivechatInquiryRecord[]; |
|
|
|
|
|
|
|
|
|
updateInquiries(await getInquiriesFromAPI()); |
|
|
|
|
await updateInquiries(inquiriesFromAPI); |
|
|
|
|
|
|
|
|
|
return () => { |
|
|
|
|
LivechatInquiry.remove({}); |
|
|
|
|
removeGlobalListener(); |
|
|
|
|
cleanDepartmentListeners && cleanDepartmentListeners(); |
|
|
|
|
globalCleanup && globalCleanup(); |
|
|
|
|
cleanDepartmentListeners?.(); |
|
|
|
|
globalCleanup?.(); |
|
|
|
|
departments.clear(); |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export const initializeLivechatInquiryStream = (() => { |
|
|
|
|
let cleanUp; |
|
|
|
|
let cleanUp: (() => void) | undefined; |
|
|
|
|
|
|
|
|
|
return async (...args) => { |
|
|
|
|
cleanUp && cleanUp(); |
|
|
|
|
cleanUp = await subscribe(...args); |
|
|
|
|
return async (...args: any[]) => { |
|
|
|
|
cleanUp?.(); |
|
|
|
|
cleanUp = await subscribe(...(args as [IOmnichannelAgent['_id']])); |
|
|
|
|
}; |
|
|
|
|
})(); |