refactor: `LivechatDepartments` - 1/2 (#28664)

pull/28671/head^2
Kevin Aleman 3 years ago committed by GitHub
parent 51bb96162f
commit d4c57c3bdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      apps/meteor/app/apps/server/bridges/livechat.ts
  2. 5
      apps/meteor/app/apps/server/converters/departments.js
  3. 6
      apps/meteor/app/apps/server/converters/rooms.js
  4. 6
      apps/meteor/app/livechat/imports/server/rest/inquiries.ts
  5. 11
      apps/meteor/app/livechat/imports/server/rest/sms.js
  6. 35
      apps/meteor/app/livechat/server/api/lib/livechat.ts
  7. 2
      apps/meteor/app/livechat/server/api/v1/offlineMessage.ts
  8. 7
      apps/meteor/app/livechat/server/hooks/offlineMessageToChannel.js
  9. 6
      apps/meteor/app/livechat/server/lib/Helper.js
  10. 32
      apps/meteor/app/livechat/server/lib/Livechat.js
  11. 4
      apps/meteor/app/livechat/server/methods/sendOfflineMessage.ts
  12. 107
      apps/meteor/app/models/server/models/LivechatDepartment.js
  13. 4
      apps/meteor/ee/app/canned-responses/server/methods/saveCannedResponse.ts
  14. 7
      apps/meteor/ee/app/livechat-enterprise/server/hooks/addDepartmentAncestors.ts
  15. 7
      apps/meteor/ee/app/livechat-enterprise/server/hooks/afterForwardChatToDepartment.ts
  16. 7
      apps/meteor/ee/app/livechat-enterprise/server/hooks/applySimultaneousChatsRestrictions.ts
  17. 6
      apps/meteor/ee/app/livechat-enterprise/server/hooks/beforeForwardRoomToDepartment.ts
  18. 9
      apps/meteor/ee/app/livechat-enterprise/server/hooks/onLoadForwardDepartmentRestrictions.ts
  19. 2
      apps/meteor/lib/callbacks.ts
  20. 13
      packages/model-typings/src/models/ILivechatDepartmentModel.ts

@ -11,11 +11,11 @@ import type { IUser } from '@rocket.chat/apps-engine/definition/users';
import type { IMessage } from '@rocket.chat/apps-engine/definition/messages';
import type { IExtraRoomParams } from '@rocket.chat/apps-engine/definition/accessors/ILivechatCreator';
import { OmnichannelSourceType } from '@rocket.chat/core-typings';
import { LivechatVisitors, LivechatRooms } from '@rocket.chat/models';
import { LivechatVisitors, LivechatRooms, LivechatDepartment } from '@rocket.chat/models';
import { getRoom } from '../../../livechat/server/api/lib/livechat';
import { Livechat } from '../../../livechat/server/lib/Livechat';
import { Users, LivechatDepartment } from '../../../models/server';
import { Users } from '../../../models/server';
import type { AppServerOrchestrator } from '../../../../ee/server/apps/orchestrator';
import { Livechat as LivechatTyped } from '../../../livechat/server/lib/LivechatTyped';
@ -263,7 +263,10 @@ export class AppLivechatBridge extends LivechatBridge {
protected async findDepartmentByIdOrName(value: string, appId: string): Promise<IDepartment | undefined> {
this.orch.debugLog(`The App ${appId} is looking for livechat departments.`);
return this.orch.getConverters()?.get('departments').convertDepartment(LivechatDepartment.findOneByIdOrName(value, {}));
return this.orch
.getConverters()
?.get('departments')
.convertDepartment(await LivechatDepartment.findOneByIdOrName(value, {}));
}
protected async findDepartmentsEnabledWithAgents(appId: string): Promise<Array<IDepartment>> {
@ -272,7 +275,7 @@ export class AppLivechatBridge extends LivechatBridge {
const converter = this.orch.getConverters()?.get('departments');
const boundConverter = converter.convertDepartment.bind(converter);
return Promise.all(LivechatDepartment.findEnabledWithAgents().map(boundConverter));
return Promise.all((await LivechatDepartment.findEnabledWithAgents().toArray()).map(boundConverter));
}
protected async _fetchLivechatRoomMessages(appId: string, roomId: string): Promise<Array<IMessage>> {

@ -1,4 +1,5 @@
import LivechatDepartment from '../../../models/server/models/LivechatDepartment';
import { LivechatDepartment } from '@rocket.chat/models';
import { transformMappedData } from '../../../../ee/lib/misc/transformMappedData';
export class AppDepartmentsConverter {
@ -7,7 +8,7 @@ export class AppDepartmentsConverter {
}
async convertById(id) {
const department = LivechatDepartment.findOneById(id);
const department = await LivechatDepartment.findOneById(id);
return this.convertDepartment(department);
}

@ -1,7 +1,7 @@
import { RoomType } from '@rocket.chat/apps-engine/definition/rooms';
import { LivechatVisitors, Rooms } from '@rocket.chat/models';
import { LivechatVisitors, Rooms, LivechatDepartment } from '@rocket.chat/models';
import { Users, LivechatDepartment } from '../../../models/server';
import { Users } from '../../../models/server';
import { transformMappedData } from '../../../../ee/lib/misc/transformMappedData';
export class AppRoomsConverter {
@ -48,7 +48,7 @@ export class AppRoomsConverter {
let departmentId;
if (room.department) {
const department = LivechatDepartment.findOneById(room.department.id);
const department = await LivechatDepartment.findOneById(room.department.id);
departmentId = department._id;
}

@ -7,10 +7,10 @@ import {
} from '@rocket.chat/rest-typings';
import { Meteor } from 'meteor/meteor';
import { LivechatInquiryStatus } from '@rocket.chat/core-typings';
import { LivechatInquiry } from '@rocket.chat/models';
import { LivechatInquiry, LivechatDepartment } from '@rocket.chat/models';
import { API } from '../../../../api/server';
import { Users, LivechatDepartment } from '../../../../models/server';
import { Users } from '../../../../models/server';
import { findInquiries, findOneInquiryByRoomId } from '../../../server/api/lib/inquiries';
import { deprecationWarning } from '../../../../api/server/helpers/deprecationWarning';
import { getPaginationItems } from '../../../../api/server/helpers/getPaginationItems';
@ -25,7 +25,7 @@ API.v1.addRoute(
const { department } = this.queryParams;
const ourQuery: { status: string; department?: string } = { status: 'queued' };
if (department) {
const departmentFromDB = LivechatDepartment.findOneByIdOrName(department);
const departmentFromDB = await LivechatDepartment.findOneByIdOrName(department);
if (departmentFromDB) {
ourQuery.department = departmentFromDB._id;
}

@ -1,11 +1,10 @@
import { Meteor } from 'meteor/meteor';
import { Random } from '@rocket.chat/random';
import { OmnichannelSourceType } from '@rocket.chat/core-typings';
import { LivechatVisitors, LivechatRooms } from '@rocket.chat/models';
import { LivechatVisitors, LivechatRooms, LivechatDepartment } from '@rocket.chat/models';
import { OmnichannelIntegration } from '@rocket.chat/core-services';
import { FileUpload } from '../../../../file-upload/server';
import { LivechatDepartment } from '../../../../models/server';
import { API } from '../../../../api/server';
import { fetch } from '../../../../../server/lib/http/fetch';
import { Livechat } from '../../../server/lib/Livechat';
@ -27,12 +26,12 @@ const getUploadFile = async (details, fileUrl) => {
return fileStore.insertSync({ ...details, size: contentSize }, content);
};
const defineDepartment = (idOrName) => {
const defineDepartment = async (idOrName) => {
if (!idOrName || idOrName === '') {
return;
}
const department = LivechatDepartment.findOneByIdOrName(idOrName);
const department = await LivechatDepartment.findOneByIdOrName(idOrName);
return department && department._id;
};
@ -81,9 +80,9 @@ API.v1.addRoute('livechat/sms-incoming/:service', {
const SMSService = await OmnichannelIntegration.getSmsService(this.urlParams.service);
const sms = SMSService.parse(this.bodyParams);
const { department } = this.queryParams;
let targetDepartment = defineDepartment(department || smsDepartment);
let targetDepartment = await defineDepartment(department || smsDepartment);
if (!targetDepartment) {
targetDepartment = defineDepartment(smsDepartment);
targetDepartment = await defineDepartment(smsDepartment);
}
const visitor = await defineVisitor(sms.from, targetDepartment);

@ -1,7 +1,7 @@
import { Meteor } from 'meteor/meteor';
import { Random } from '@rocket.chat/random';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { EmojiCustom, LivechatTrigger, LivechatVisitors, LivechatRooms } from '@rocket.chat/models';
import { EmojiCustom, LivechatTrigger, LivechatVisitors, LivechatRooms, LivechatDepartment } from '@rocket.chat/models';
import type {
ILivechatAgent,
ILivechatDepartment,
@ -11,7 +11,6 @@ import type {
OmnichannelSourceType,
} from '@rocket.chat/core-typings';
import { LivechatDepartment } from '../../../../models/server';
import { Livechat } from '../../lib/Livechat';
import { callbacks } from '../../../../../lib/callbacks';
import { normalizeAgent } from '../../lib/Helper';
@ -30,21 +29,23 @@ async function findTriggers(): Promise<Pick<ILivechatTrigger, '_id' | 'actions'
}));
}
function findDepartments(businessUnit?: string): Promise<ILivechatDepartment[]> {
async function findDepartments(
businessUnit?: string,
): Promise<Pick<ILivechatDepartment, '_id' | 'name' | 'showOnRegistration' | 'showOnOfflineForm'>[]> {
// TODO: check this function usage
return LivechatDepartment.findEnabledWithAgentsAndBusinessUnit(businessUnit, {
_id: 1,
name: 1,
showOnRegistration: 1,
showOnOfflineForm: 1,
})
.fetch()
.map(({ _id, name, showOnRegistration, showOnOfflineForm }: ILivechatDepartment) => ({
_id,
name,
showOnRegistration,
showOnOfflineForm,
}));
return (
await LivechatDepartment.findEnabledWithAgentsAndBusinessUnit(businessUnit, {
_id: 1,
name: 1,
showOnRegistration: 1,
showOnOfflineForm: 1,
}).toArray()
).map(({ _id, name, showOnRegistration, showOnOfflineForm }) => ({
_id,
name,
showOnRegistration,
showOnOfflineForm,
}));
}
export function findGuest(token: string): Promise<ILivechatVisitor | null> {
@ -136,7 +137,7 @@ export async function settings({ businessUnit = '' }: { businessUnit?: string }
// Putting this ugly conversion while we type the livechat service
const initSettings = (await Livechat.getInitSettings()) as unknown as Record<string, string | number | any>;
const triggers = await findTriggers();
const departments = findDepartments(businessUnit);
const departments = await findDepartments(businessUnit);
const sound = `${Meteor.absoluteUrl()}sounds/chime.mp3`;
const emojis = await EmojiCustom.find().toArray();
return {

@ -10,7 +10,7 @@ API.v1.addRoute(
{
async post() {
const { name, email, message, department, host } = this.bodyParams;
if (!Livechat.sendOfflineMessage({ name, email, message, department, host })) {
if (!(await Livechat.sendOfflineMessage({ name, email, message, department, host }))) {
return API.v1.failure({ message: TAPi18n.__('Error_sending_livechat_offline_message') });
}

@ -1,9 +1,10 @@
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { LivechatDepartment } from '@rocket.chat/models';
import { callbacks } from '../../../../lib/callbacks';
import { settings } from '../../../settings/server';
import { sendMessage } from '../../../lib/server';
import { LivechatDepartment, Rooms, Users } from '../../../models/server';
import { Rooms, Users } from '../../../models/server';
callbacks.add(
'livechat.offlineMessage',
@ -16,8 +17,8 @@ callbacks.add(
let departmentName;
const { name, email, department, message: text, host } = data;
if (department && department !== '') {
const dept = LivechatDepartment.findOneById(department, {
fields: { name: 1, offlineMessageChannelName: 1 },
const dept = await LivechatDepartment.findOneById(department, {
projection: { name: 1, offlineMessageChannelName: 1 },
});
departmentName = dept?.name;
if (dept?.offlineMessageChannelName) {

@ -5,10 +5,10 @@ import { LivechatTransferEventType } from '@rocket.chat/apps-engine/definition/l
import { OmnichannelSourceType, DEFAULT_SLA_CONFIG } from '@rocket.chat/core-typings';
import { LivechatPriorityWeight } from '@rocket.chat/core-typings/src/ILivechatPriority';
import { api } from '@rocket.chat/core-services';
import { LivechatDepartmentAgents, Users as UsersRaw, LivechatInquiry, LivechatRooms } from '@rocket.chat/models';
import { LivechatDepartmentAgents, Users as UsersRaw, LivechatInquiry, LivechatRooms, LivechatDepartment } from '@rocket.chat/models';
import { hasRoleAsync } from '../../../authorization/server/functions/hasRole';
import { Messages, Rooms, Subscriptions, Users, LivechatDepartment } from '../../../models/server';
import { Messages, Rooms, Subscriptions, Users } from '../../../models/server';
import { Livechat } from './Livechat';
import { RoutingManager } from './RoutingManager';
import { callbacks } from '../../../../lib/callbacks';
@ -476,7 +476,7 @@ export const forwardRoomToDepartment = async (room, guest, transferData) => {
const { servedBy, chatQueued } = roomTaken;
if (!chatQueued && oldServedBy && servedBy && oldServedBy._id === servedBy._id) {
const department = LivechatDepartment.findOneById(departmentId);
const department = await LivechatDepartment.findOneById(departmentId);
if (!department?.fallbackForwardDepartment) {
logger.debug(`Cannot forward room ${room._id}. Chat assigned to agent ${servedBy._id} (Previous was ${oldServedBy._id})`);
return false;

@ -29,7 +29,7 @@ import { RoutingManager } from './RoutingManager';
import { Analytics } from './Analytics';
import { settings } from '../../../settings/server';
import { callbacks } from '../../../../lib/callbacks';
import { Users, Messages, Subscriptions, LivechatDepartment } from '../../../models/server';
import { Users, Messages, Subscriptions } from '../../../models/server';
import { Logger } from '../../../logger/server';
import { hasRoleAsync } from '../../../authorization/server/functions/hasRole';
import { canAccessRoomAsync, roomAccessAttributes } from '../../../authorization/server';
@ -126,7 +126,7 @@ export const Livechat = {
return onlineForDep;
}
const dep = LivechatDepartment.findOneById(department);
const dep = await LivechatDepartmentRaw.findOneById(department);
if (!dep?.fallbackForwardDepartment) {
return onlineForDep;
}
@ -146,9 +146,9 @@ export const Livechat = {
},
async getRequiredDepartment(onlineRequired = true) {
const departments = LivechatDepartment.findEnabledWithAgents();
const departments = await LivechatDepartmentRaw.findEnabledWithAgents();
for await (const dept of departments.fetch()) {
for await (const dept of departments) {
if (!dept.showOnRegistration) {
continue;
}
@ -177,7 +177,7 @@ export const Livechat = {
room = null;
}
if (guest.department && !LivechatDepartment.findOneById(guest.department)) {
if (guest.department && !(await LivechatDepartmentRaw.findOneById(guest.department))) {
await LivechatVisitors.removeDepartmentById(guest._id);
guest = await LivechatVisitors.findOneById(guest._id);
}
@ -315,7 +315,7 @@ export const Livechat = {
if (department) {
Livechat.logger.debug(`Attempt to find a department with id/name ${department}`);
const dep = LivechatDepartment.findOneByIdOrName(department);
const dep = await LivechatDepartmentRaw.findOneByIdOrName(department);
if (!dep) {
Livechat.logger.debug('Invalid department provided');
throw new Meteor.Error('error-invalid-department', 'The provided department is invalid', {
@ -383,7 +383,7 @@ export const Livechat = {
},
};
const dep = LivechatDepartment.findOneById(department);
const dep = await LivechatDepartmentRaw.findOneById(department);
if (!dep) {
throw new Meteor.Error('invalid-department', 'Provided department does not exists', {
method: 'setDepartmentForGuest',
@ -713,8 +713,8 @@ export const Livechat = {
}
if (transferData.departmentId) {
transferData.department = LivechatDepartment.findOneById(transferData.departmentId, {
fields: { name: 1 },
transferData.department = await LivechatDepartmentRaw.findOneById(transferData.departmentId, {
projection: { name: 1 },
});
Livechat.logger.debug(`Transfering room ${room._id} to department ${transferData.department?._id}`);
}
@ -1009,7 +1009,7 @@ export const Livechat = {
]),
});
const department = LivechatDepartment.findOneById(_id);
const department = await LivechatDepartmentRaw.findOneById(_id);
if (!department) {
throw new Meteor.Error('error-department-not-found', 'Department not found', {
method: 'livechat:saveDepartmentAgents',
@ -1032,7 +1032,7 @@ export const Livechat = {
}
Users.setLivechatData(_id, agentData);
await LivechatDepartment.saveDepartmentsByAgent(user, agentDepartments);
await LivechatDepartmentRaw.saveDepartmentsByAgent(user, agentDepartments);
return true;
},
@ -1051,17 +1051,17 @@ export const Livechat = {
});
}
const department = LivechatDepartment.findOneById(_id, { projection: { _id: 1 } });
const department = await LivechatDepartmentRaw.findOneById(_id, { projection: { _id: 1 } });
if (!department) {
throw new Meteor.Error('department-not-found', 'Department not found', {
method: 'livechat:removeDepartment',
});
}
const ret = LivechatDepartment.removeById(_id);
const ret = (await LivechatDepartmentRaw.removeById(_id)).deletedCount;
const agentsIds = (await LivechatDepartmentAgents.findByDepartmentId(_id).toArray()).map((agent) => agent.agentId);
await LivechatDepartmentAgents.removeByDepartmentId(_id);
LivechatDepartment.unsetFallbackDepartmentByDepartmentId(_id);
await LivechatDepartmentRaw.unsetFallbackDepartmentByDepartmentId(_id);
if (ret) {
Meteor.defer(() => {
callbacks.run('livechat.afterRemoveDepartment', { department, agentsIds });
@ -1181,7 +1181,7 @@ export const Livechat = {
await LivechatRooms.updateVisitorStatus(token, status);
},
sendOfflineMessage(data = {}) {
async sendOfflineMessage(data = {}) {
if (!settings.get('Livechat_display_offline_form')) {
return false;
}
@ -1220,7 +1220,7 @@ export const Livechat = {
let emailTo = settings.get('Livechat_offline_email');
if (department && department !== '') {
const dep = LivechatDepartment.findOneByIdOrName(department);
const dep = await LivechatDepartmentRaw.findOneByIdOrName(department);
emailTo = dep.email || emailTo;
}

@ -9,12 +9,12 @@ import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarn
declare module '@rocket.chat/ui-contexts' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
'livechat:sendOfflineMessage'(data: { name: string; email: string; message: string }): boolean;
'livechat:sendOfflineMessage'(data: { name: string; email: string; message: string }): Promise<boolean>;
}
}
Meteor.methods<ServerMethods>({
'livechat:sendOfflineMessage'(data) {
async 'livechat:sendOfflineMessage'(data) {
methodDeprecationLogger.warn('livechat:sendOfflineMessage will be deprecated in future versions of Rocket.Chat');
check(data, {

@ -1,6 +1,3 @@
import _ from 'underscore';
import { LivechatDepartmentAgents } from '@rocket.chat/models';
import { Base } from './_Base';
/**
* Livechat Department model
@ -21,86 +18,7 @@ export class LivechatDepartment extends Base {
this.tryEnsureIndex({ ancestors: 1 }, { sparse: true });
}
// FIND
findOneById(_id, options) {
const query = { _id };
return this.findOne(query, options);
}
// This is the same as the above :)
findByDepartmentId(_id, options) {
const query = { _id };
return this.find(query, options);
}
// migrated
createOrUpdateDepartment(_id, data = {}) {
const oldData = _id && this.findOneById(_id);
const record = {
...data,
};
if (_id) {
this.update({ _id }, { $set: record });
} else {
_id = this.insert(record);
}
if (oldData && oldData.enabled !== data.enabled) {
Promise.await(LivechatDepartmentAgents.setDepartmentEnabledByDepartmentId(_id, data.enabled));
}
return _.extend(record, { _id });
}
saveDepartmentsByAgent(agent, departments = []) {
const { _id: agentId, username } = agent;
const savedDepartments = Promise.await(LivechatDepartmentAgents.findByAgentId(agentId).toArray()).map((d) => d.departmentId);
const incNumAgents = (_id, numAgents) => this.update(_id, { $inc: { numAgents } });
// remove other departments
_.difference(savedDepartments, departments).forEach((departmentId) => {
Promise.await(LivechatDepartmentAgents.removeByDepartmentIdAndAgentId(departmentId, agentId));
incNumAgents(departmentId, -1);
});
departments.forEach((departmentId) => {
const { enabled: departmentEnabled } = this.findOneById(departmentId, {
fields: { enabled: 1 },
});
const saveResult = Promise.await(
LivechatDepartmentAgents.saveAgent({
agentId,
departmentId,
username,
departmentEnabled,
count: 0,
order: 0,
}),
);
if (saveResult.insertedId) {
incNumAgents(departmentId, 1);
}
});
}
updateById(_id, update) {
return this.update({ _id }, update);
}
updateNumAgentsById(_id, numAgents) {
return this.update({ _id }, { $set: { numAgents } });
}
// REMOVE
removeById(_id) {
const query = { _id };
return this.remove(query);
}
// Still in use by EE model
findEnabledWithAgents(fields = undefined) {
const query = {
numAgents: { $gt: 0 },
@ -109,29 +27,6 @@ export class LivechatDepartment extends Base {
return this.find(query, fields && { fields });
}
findEnabledWithAgentsAndBusinessUnit(_, fields) {
const query = {
numAgents: { $gt: 0 },
enabled: true,
};
return this.find(query, fields && { fields });
}
findOneByIdOrName(_idOrName, options) {
const query = {
$or: [
{
_id: _idOrName,
},
{
name: _idOrName,
},
],
};
return this.findOne(query, options);
}
findByUnitIds(unitIds, options) {
const query = {
parentId: {

@ -1,10 +1,10 @@
import { Meteor } from 'meteor/meteor';
import { Match, check } from 'meteor/check';
import type { ServerMethods } from '@rocket.chat/ui-contexts';
import { LivechatDepartment } from '@rocket.chat/models';
import { hasPermissionAsync } from '../../../../../app/authorization/server/functions/hasPermission';
import CannedResponse from '../../../models/server/models/CannedResponse';
import LivechatDepartment from '../../../../../app/models/server/models/LivechatDepartment';
import { Users } from '../../../../../app/models/server';
import notifications from '../../../../../app/notifications/server/lib/Notifications';
@ -77,7 +77,7 @@ Meteor.methods<ServerMethods>({
});
}
if (responseData.departmentId && !LivechatDepartment.findOneById(responseData.departmentId)) {
if (responseData.departmentId && !(await LivechatDepartment.findOneById(responseData.departmentId))) {
throw new Meteor.Error('error-invalid-department', 'Invalid department', {
method: 'saveCannedResponse',
});

@ -1,7 +1,6 @@
import { LivechatRooms } from '@rocket.chat/models';
import { LivechatRooms, LivechatDepartment } from '@rocket.chat/models';
import { callbacks } from '../../../../../lib/callbacks';
import LivechatDepartment from '../../../../../app/models/server/models/LivechatDepartment';
callbacks.add(
'livechat.newRoom',
@ -10,8 +9,8 @@ callbacks.add(
return room;
}
const department = LivechatDepartment.findOneById(room.departmentId, {
fields: { ancestors: 1 },
const department = await LivechatDepartment.findOneById(room.departmentId, {
projection: { ancestors: 1 },
});
if (!department?.ancestors) {

@ -1,7 +1,6 @@
import { LivechatRooms } from '@rocket.chat/models';
import { LivechatRooms, LivechatDepartment } from '@rocket.chat/models';
import { callbacks } from '../../../../../lib/callbacks';
import LivechatDepartment from '../../../../../app/models/server/models/LivechatDepartment';
import { cbLogger } from '../lib/logger';
callbacks.add(
@ -16,8 +15,8 @@ callbacks.add(
}
await LivechatRooms.unsetPredictedVisitorAbandonmentByRoomId(room._id);
const department = LivechatDepartment.findOneById(newDepartmentId, {
fields: { ancestors: 1 },
const department = await LivechatDepartment.findOneById(newDepartmentId, {
projection: { ancestors: 1 },
});
if (!department) {
cbLogger.debug('Skipping callback. No department found');

@ -1,13 +1,14 @@
import { LivechatDepartment } from '@rocket.chat/models';
import { callbacks } from '../../../../../lib/callbacks';
import { LivechatDepartment } from '../../../../../app/models/server';
import { settings } from '../../../../../app/settings/server';
import { cbLogger } from '../lib/logger';
callbacks.add(
'livechat.applySimultaneousChatRestrictions',
(_: any, { departmentId }: { departmentId?: string } = {}) => {
async (_: any, { departmentId }: { departmentId?: string } = {}) => {
if (departmentId) {
const departmentLimit = LivechatDepartment.findOneById(departmentId)?.maxNumberSimultaneousChat || 0;
const departmentLimit = (await LivechatDepartment.findOneById(departmentId))?.maxNumberSimultaneousChat || 0;
if (departmentLimit > 0) {
cbLogger.debug(`Applying department filters. Max chats per department ${departmentLimit}`);
return { $match: { 'queueInfo.chats': { $gte: Number(departmentLimit) } } };

@ -1,12 +1,12 @@
import { Meteor } from 'meteor/meteor';
import { LivechatDepartment } from '@rocket.chat/models';
import { callbacks } from '../../../../../lib/callbacks';
import { LivechatDepartment } from '../../../../../app/models/server';
import { cbLogger } from '../lib/logger';
callbacks.add(
'livechat.beforeForwardRoomToDepartment',
(options) => {
async (options) => {
const { room, transferData } = options;
if (!room || !transferData) {
cbLogger.debug('Skipping callback. No room provided');
@ -18,7 +18,7 @@ callbacks.add(
return options;
}
const { department: departmentToTransfer } = transferData;
const currentDepartment = LivechatDepartment.findOneById(departmentId);
const currentDepartment = await LivechatDepartment.findOneById(departmentId);
if (!currentDepartment) {
cbLogger.debug('Skipping callback. Current department does not exists');
return options;

@ -1,17 +1,18 @@
import { LivechatDepartment } from '@rocket.chat/models';
import { callbacks } from '../../../../../lib/callbacks';
import { LivechatDepartment } from '../../../../../app/models/server';
import { cbLogger } from '../lib/logger';
callbacks.add(
'livechat.onLoadForwardDepartmentRestrictions',
(options) => {
async (options) => {
const { departmentId } = options;
if (!departmentId) {
cbLogger.debug('Skipping callback. No departmentId provided');
return options;
}
const department = LivechatDepartment.findOneById(departmentId, {
fields: { departmentsAllowedToForward: 1 },
const department = await LivechatDepartment.findOneById(departmentId, {
projection: { departmentsAllowedToForward: 1 },
});
if (!department) {
cbLogger.debug('Skipping callback. Invalid department provided');

@ -103,7 +103,7 @@ type ChainedCallbackSignatures = {
'livechat.beforeForwardRoomToDepartment': <T extends { room: IOmnichannelRoom; transferData?: { department: { _id: string } } }>(
options: T,
) => T;
) => Promise<T>;
'livechat.beforeRouteChat': (inquiry: ILivechatInquiryRecord, agent?: { agentId: string; username: string }) => ILivechatInquiryRecord;
'livechat.checkDefaultAgentOnNewRoom': (

@ -35,9 +35,12 @@ export interface ILivechatDepartmentModel extends IBaseModel<ILivechatDepartment
saveDepartmentsByAgent(agent: { _id: string; username: string }, departments: string[]): Promise<void>;
updateById(_id: string, update: Partial<ILivechatDepartment>): Promise<Document | UpdateResult>;
updateNumAgentsById(_id: string, numAgents: number): Promise<Document | UpdateResult>;
findEnabledWithAgents(projection: FindOptions<ILivechatDepartment>['projection']): FindCursor<ILivechatDepartment>;
findEnabledWithAgentsAndBusinessUnit(_: any, projection: FindOptions<ILivechatDepartment>['projection']): FindCursor<ILivechatDepartment>;
findOneByIdOrName(_idOrName: string, options: FindOptions<ILivechatDepartment>): Promise<ILivechatDepartment | null>;
findByUnitIds(unitIds: string[], options: FindOptions<ILivechatDepartment>): FindCursor<ILivechatDepartment>;
findActiveByUnitIds(unitIds: string[], options: FindOptions<ILivechatDepartment>): FindCursor<ILivechatDepartment>;
findEnabledWithAgents(projection?: FindOptions<ILivechatDepartment>['projection']): FindCursor<ILivechatDepartment>;
findEnabledWithAgentsAndBusinessUnit(
_: any,
projection?: FindOptions<ILivechatDepartment>['projection'],
): FindCursor<ILivechatDepartment>;
findOneByIdOrName(_idOrName: string, options?: FindOptions<ILivechatDepartment>): Promise<ILivechatDepartment | null>;
findByUnitIds(unitIds: string[], options?: FindOptions<ILivechatDepartment>): FindCursor<ILivechatDepartment>;
findActiveByUnitIds(unitIds: string[], options?: FindOptions<ILivechatDepartment>): FindCursor<ILivechatDepartment>;
}

Loading…
Cancel
Save