Skip to content
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

refactor: Move callbacks to ts 1X #28710

Merged
merged 20 commits into from
Apr 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { settings } from '../../../settings/server';

callbacks.add(
'livechat.beforeDelegateAgent',
async (agent, { department }) => {
async (agent, { department } = {}) => {
if (agent) {
return agent;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { LivechatVisitors } from '@rocket.chat/models';
import { isOmnichannelRoom } from '@rocket.chat/core-typings';
import type { IMessage, IOmnichannelRoom } from '@rocket.chat/core-typings';
import { isEditedMessage, isOmnichannelRoom } from '@rocket.chat/core-typings';

import { callbacks } from '../../../../lib/callbacks';
import { settings } from '../../../settings/server';
import { isTruthy } from '../../../../lib/isTruthy';

function validateMessage(message, room) {
function validateMessage(message: IMessage, room: IOmnichannelRoom) {
// skips this callback if the message was edited
if (message.editedAt) {
if (isEditedMessage(message)) {
return false;
}

Expand Down Expand Up @@ -39,12 +41,11 @@ callbacks.add(
return message;
}

const phoneRegexp = new RegExp(settings.get('Livechat_lead_phone_regex'), 'g');
const msgPhones = message.msg.match(phoneRegexp);

const emailRegexp = new RegExp(settings.get('Livechat_lead_email_regex'), 'gi');
const msgEmails = message.msg.match(emailRegexp);
const phoneRegexp = new RegExp(settings.get<string>('Livechat_lead_phone_regex'), 'g');
const msgPhones = message.msg.match(phoneRegexp)?.filter(isTruthy) || [];

const emailRegexp = new RegExp(settings.get<string>('Livechat_lead_email_regex'), 'gi');
const msgEmails = message.msg.match(emailRegexp)?.filter(isTruthy) || [];
if (msgEmails || msgPhones) {
await LivechatVisitors.saveGuestEmailPhoneById(room.v._id, msgEmails, msgPhones);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { isOmnichannelRoom, isEditedMessage } from '@rocket.chat/core-typings';
import { LivechatRooms } from '@rocket.chat/models';

import { callbacks } from '../../../../lib/callbacks';

callbacks.add(
'afterSaveMessage',
async function (message, room) {
if (!isOmnichannelRoom(room)) {
return message;
}

// skips this callback if the message was edited
if (!message || message.editedAt) {
if (!message || isEditedMessage(message)) {
return message;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { isOmnichannelRoom, isEditedMessage } from '@rocket.chat/core-typings';
import { LivechatRooms } from '@rocket.chat/models';

import { callbacks } from '../../../../lib/callbacks';

callbacks.add(
'afterSaveMessage',
async function (message, room) {
if (!isOmnichannelRoom(room)) {
return message;
}

// skips this callback if the message was edited
if (!message || message.editedAt) {
if (!message || isEditedMessage(message)) {
return message;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ callbacks.add(
return data;
}

const lng = settings.get('Language') || 'en';
const lng = settings.get<string>('Language') || 'en';

let msg = `${TAPi18n.__('New_Livechat_offline_message_has_been_sent', { lng })}: \n`;
if (host && host !== '') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import moment from 'moment';
import { LivechatBusinessHours, LivechatDepartment, Messages, LivechatRooms } from '@rocket.chat/models';
import type { IOmnichannelRoom, IMessage, IBusinessHourWorkHour } from '@rocket.chat/core-typings';
import { isOmnichannelRoom } from '@rocket.chat/core-typings';

import { settings } from '../../../settings/server';
import { callbacks } from '../../../../lib/callbacks';
import { businessHourManager } from '../business-hour';

const getSecondsWhenOfficeHoursIsDisabled = (room, agentLastMessage) =>
moment(new Date(room.closedAt)).diff(moment(new Date(agentLastMessage.ts)), 'seconds');
const parseDays = (acc, day) => {
const getSecondsWhenOfficeHoursIsDisabled = (room: IOmnichannelRoom, agentLastMessage: IMessage) =>
moment(new Date(room.closedAt || new Date())).diff(moment(new Date(agentLastMessage.ts)), 'seconds');

const parseDays = (
acc: Record<string, { start: { day: string; time: string }; finish: { day: string; time: string }; open: boolean }>,
day: IBusinessHourWorkHour,
) => {
acc[day.day] = {
start: { day: day.start.utc.dayOfWeek, time: day.start.utc.time },
finish: { day: day.finish.utc.dayOfWeek, time: day.finish.utc.time },
Expand All @@ -16,20 +22,29 @@ const parseDays = (acc, day) => {
return acc;
};

const getSecondsSinceLastAgentResponse = async (room, agentLastMessage) => {
const getSecondsSinceLastAgentResponse = async (room: IOmnichannelRoom, agentLastMessage: IMessage) => {
if (!settings.get('Livechat_enable_business_hours')) {
return getSecondsWhenOfficeHoursIsDisabled(room, agentLastMessage);
}
let officeDays;
const department = room.departmentId && (await LivechatDepartment.findOneById(room.departmentId));
if (department && department.businessHourId) {
const department = room.departmentId ? await LivechatDepartment.findOneById(room.departmentId) : null;
if (department?.businessHourId) {
const businessHour = await LivechatBusinessHours.findOneById(department.businessHourId);
officeDays = (await businessHourManager.getBusinessHour(businessHour._id, businessHour.type)).workHours.reduce(parseDays, {});
if (!businessHour) {
return getSecondsWhenOfficeHoursIsDisabled(room, agentLastMessage);
}

officeDays = (await businessHourManager.getBusinessHour(businessHour._id, businessHour.type))?.workHours.reduce(parseDays, {});
} else {
officeDays = (await businessHourManager.getBusinessHour()).workHours.reduce(parseDays, {});
officeDays = (await businessHourManager.getBusinessHour())?.workHours.reduce(parseDays, {});
}

if (!officeDays) {
return getSecondsWhenOfficeHoursIsDisabled(room, agentLastMessage);
}

let totalSeconds = 0;
const endOfConversation = moment(new Date(room.closedAt));
const endOfConversation = moment(new Date(room.closedAt || new Date()));
const startOfInactivity = moment(new Date(agentLastMessage.ts));
const daysOfInactivity = endOfConversation.clone().startOf('day').diff(startOfInactivity.clone().startOf('day'), 'days');
const inactivityDay = moment(new Date(agentLastMessage.ts));
Expand Down Expand Up @@ -60,11 +75,20 @@ callbacks.add(
async function (params) {
const { room } = params;

if (!isOmnichannelRoom(room)) {
return params;
}

const closedByAgent = room.closer !== 'visitor';
const wasTheLastMessageSentByAgent = room.lastMessage && !room.lastMessage.token;
if (!closedByAgent || !wasTheLastMessageSentByAgent) {
return params;
}

if (!room.v?.lastMessageTs) {
return params;
}

const agentLastMessage = await Messages.findAgentLastMessageByVisitorLastMessageTs(room._id, room.v.lastMessageTs);
if (!agentLastMessage) {
return params;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isOmnichannelRoom } from '@rocket.chat/core-typings';
import { isEditedMessage, isOmnichannelRoom } from '@rocket.chat/core-typings';
import { LivechatRooms } from '@rocket.chat/models';

import { callbacks } from '../../../../lib/callbacks';
Expand All @@ -15,7 +15,7 @@ callbacks.add(
}

// skips this callback if the message was edited
if (!message || message.editedAt) {
if (!message || isEditedMessage(message)) {
return message;
}

Expand All @@ -35,25 +35,26 @@ callbacks.add(
const now = new Date();
let analyticsData;

const visitorLastQuery = room.metrics && room.metrics.v ? room.metrics.v.lq : room.ts;
const agentLastReply = room.metrics && room.metrics.servedBy ? room.metrics.servedBy.lr : room.ts;
const agentJoinTime = room.servedBy && room.servedBy.ts ? room.servedBy.ts : room.ts;
const visitorLastQuery = room.metrics?.v ? room.metrics.v.lq : room.ts;
const agentLastReply = room.metrics?.servedBy ? room.metrics.servedBy.lr : room.ts;
const agentJoinTime = room.servedBy?.ts ? room.servedBy.ts : room.ts;

const isResponseTt = room.metrics && room.metrics.response && room.metrics.response.tt;
const isResponseTotal = room.metrics && room.metrics.response && room.metrics.response.total;
const isResponseTt = room.metrics?.response?.tt;
const isResponseTotal = room.metrics?.response?.total;

if (agentLastReply === room.ts) {
callbackLogger.debug('Calculating: first message from agent');
// first response
const firstResponseDate = now;
const firstResponseTime = (now.getTime() - visitorLastQuery) / 1000;
const responseTime = (now.getTime() - visitorLastQuery) / 1000;
const firstResponseTime = (now.getTime() - new Date(visitorLastQuery).getTime()) / 1000;
const responseTime = (now.getTime() - new Date(visitorLastQuery).getTime()) / 1000;
const avgResponseTime =
((isResponseTt ? room.metrics.response.tt : 0) + responseTime) / ((isResponseTotal ? room.metrics.response.total : 0) + 1);
((isResponseTt ? room.metrics?.response?.tt : 0) || 0 + responseTime) /
((isResponseTotal ? room.metrics?.response?.total : 0) || 0 + 1);

const firstReactionDate = now;
const firstReactionTime = (now.getTime() - agentJoinTime) / 1000;
const reactionTime = (now.getTime() - agentJoinTime) / 1000;
const firstReactionTime = (now.getTime() - new Date(agentJoinTime).getTime()) / 1000;
const reactionTime = (now.getTime() - new Date(agentJoinTime).getTime()) / 1000;

analyticsData = {
firstResponseDate,
Expand All @@ -67,11 +68,12 @@ callbacks.add(
} else if (visitorLastQuery > agentLastReply) {
callbackLogger.debug('Calculating: visitor sent a message after agent');
// response, not first
const responseTime = (now.getTime() - visitorLastQuery) / 1000;
const responseTime = (now.getTime() - new Date(visitorLastQuery).getTime()) / 1000;
const avgResponseTime =
((isResponseTt ? room.metrics.response.tt : 0) + responseTime) / ((isResponseTotal ? room.metrics.response.total : 0) + 1);
((isResponseTt ? room.metrics?.response?.tt : 0) || 0 + responseTime) /
((isResponseTotal ? room.metrics?.response?.total : 0) || 0 + 1);

const reactionTime = (now.getTime() - visitorLastQuery) / 1000;
const reactionTime = (now.getTime() - new Date(visitorLastQuery).getTime()) / 1000;

analyticsData = {
responseTime,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { isOmnichannelRoom } from '@rocket.chat/core-typings';

import { callbacks } from '../../../../lib/callbacks';
import { Livechat } from '../lib/Livechat';

callbacks.add(
'livechat.newRoom',
async (room) => {
if (!isOmnichannelRoom(room)) {
return room;
}

const {
_id,
v: { _id: guestId },
Expand Down
Loading