RocketChat/Rocket.Chat

View on GitHub
apps/meteor/ee/app/livechat-enterprise/server/hooks/beforeRoutingChat.ts

Summary

Maintainability
A
1 hr
Test Coverage
import type { ILivechatDepartment } from '@rocket.chat/core-typings';
import { LivechatDepartment, LivechatInquiry, LivechatRooms } from '@rocket.chat/models';

import { online } from '../../../../../app/livechat/server/api/lib/livechat';
import { allowAgentSkipQueue } from '../../../../../app/livechat/server/lib/Helper';
import { Livechat } from '../../../../../app/livechat/server/lib/LivechatTyped';
import { saveQueueInquiry } from '../../../../../app/livechat/server/lib/QueueManager';
import { getInquirySortMechanismSetting } from '../../../../../app/livechat/server/lib/settings';
import { settings } from '../../../../../app/settings/server';
import { callbacks } from '../../../../../lib/callbacks';
import { dispatchInquiryPosition } from '../lib/Helper';
import { cbLogger } from '../lib/logger';

callbacks.add(
    'livechat.beforeRouteChat',
    async (inquiry, agent) => {
        // check here if department has fallback before queueing
        if (inquiry?.department && !(await online(inquiry.department, true, true))) {
            const department = await LivechatDepartment.findOneById<Pick<ILivechatDepartment, '_id' | 'fallbackForwardDepartment'>>(
                inquiry.department,
                {
                    projection: { fallbackForwardDepartment: 1 },
                },
            );

            if (!department) {
                return inquiry;
            }
            if (department.fallbackForwardDepartment) {
                cbLogger.info(
                    `Inquiry ${inquiry._id} will be moved from department ${department._id} to fallback department ${department.fallbackForwardDepartment}`,
                );
                // update visitor
                await Livechat.setDepartmentForGuest({
                    token: inquiry?.v?.token,
                    department: department.fallbackForwardDepartment,
                });
                // update inquiry
                inquiry = (await LivechatInquiry.setDepartmentByInquiryId(inquiry._id, department.fallbackForwardDepartment)) ?? inquiry;
                // update room
                await LivechatRooms.setDepartmentByRoomId(inquiry.rid, department.fallbackForwardDepartment);
            }
        }

        if (!settings.get('Livechat_waiting_queue')) {
            return inquiry;
        }

        if (!inquiry) {
            return inquiry;
        }

        const { _id, status, department } = inquiry;

        if (status !== 'ready') {
            return inquiry;
        }

        if (agent && (await allowAgentSkipQueue(agent))) {
            return inquiry;
        }

        await saveQueueInquiry(inquiry);

        if (settings.get('Omnichannel_calculate_dispatch_service_queue_statistics')) {
            const [inq] = await LivechatInquiry.getCurrentSortedQueueAsync({
                inquiryId: _id,
                department,
                queueSortBy: getInquirySortMechanismSetting(),
            });
            if (inq) {
                await dispatchInquiryPosition(inq);
            }
        }

        return LivechatInquiry.findOneById(_id);
    },
    callbacks.priority.HIGH,
    'livechat-before-routing-chat',
);