Files
CRM_Montzar/apps/api/src/message-automations/message-automation.util.ts
T

112 lines
3.0 KiB
TypeScript

export type MessageDelayUnit = 'minutes' | 'hours' | 'days' | 'weeks' | 'months';
export const MESSAGE_AUTOMATION_TRIGGERS = [
'person_created',
'lead_submitted',
'deal_created',
'deal_stage_changed',
'deal_won',
'deal_lost',
'ticket_created',
'ticket_resolved',
'invoice_issued',
'invoice_paid',
'activity_created',
'activity_done',
] as const;
export const MAX_MESSAGE_REPEAT = 10;
export const MAX_MESSAGE_SMS = 160;
export function delayMs(value: number, unit: MessageDelayUnit): number {
const n = Math.max(0, Math.trunc(Number(value) || 0));
if (unit === 'minutes') return n * 60_000;
if (unit === 'hours') return n * 3_600_000;
if (unit === 'days') return n * 86_400_000;
if (unit === 'weeks') return n * 7 * 86_400_000;
return n * 30 * 86_400_000;
}
export function addDelay(
from: Date,
value: number,
unit: MessageDelayUnit,
): Date {
const n = Math.max(0, Math.trunc(Number(value) || 0));
if (unit === 'months') {
const next = new Date(from.getTime());
next.setMonth(next.getMonth() + n);
return next;
}
return new Date(from.getTime() + delayMs(n, unit));
}
export function buildSendAts(
now: Date,
startValue: number,
startUnit: MessageDelayUnit,
repeatCount: number,
intervalValue: number,
intervalUnit: MessageDelayUnit,
): Date[] {
const count = Math.min(
MAX_MESSAGE_REPEAT,
Math.max(1, Math.trunc(Number(repeatCount) || 1)),
);
const first = addDelay(now, startValue, startUnit);
const times = [first];
let cursor = first;
for (let i = 1; i < count; i += 1) {
cursor = addDelay(cursor, Math.max(1, intervalValue), intervalUnit);
times.push(cursor);
}
return times;
}
export function applyMessageTemplate(
text: string,
vars: {
title?: string;
name?: string;
phone?: string;
date?: string;
company?: string;
},
): string {
const map: Record<string, string> = {
title: vars.title ?? '',
عنوان: vars.title ?? '',
نام: vars.name ?? '',
name: vars.name ?? '',
شماره: vars.phone ?? '',
phone: vars.phone ?? '',
تاریخ: vars.date ?? '',
date: vars.date ?? '',
شرکت: vars.company ?? '',
company: vars.company ?? '',
};
return text.replace(/\{([^}]+)\}/g, (full, key: string) => {
const next = map[key.trim()];
return next === undefined ? full : next;
});
}
export function clipSms(text: string): string {
const trimmed = text.trim();
if (trimmed.length <= MAX_MESSAGE_SMS) return trimmed;
return `${trimmed.slice(0, MAX_MESSAGE_SMS - 1)}…`;
}
/** When this event happens, cancel leftover messages of these earlier triggers. */
export function cancelTriggersFor(
trigger: (typeof MESSAGE_AUTOMATION_TRIGGERS)[number],
): (typeof MESSAGE_AUTOMATION_TRIGGERS)[number][] {
if (trigger === 'invoice_paid') return ['invoice_issued'];
if (trigger === 'ticket_resolved') return ['ticket_created'];
if (trigger === 'deal_won' || trigger === 'deal_lost') {
return ['deal_created', 'deal_stage_changed'];
}
if (trigger === 'activity_done') return ['activity_created'];
return [];
}