Adding SMS automation

This commit is contained in:
2026-09-13 19:11:47 +03:30
parent bd63d2ab76
commit 45b0d46cfe
26 changed files with 1724 additions and 31 deletions
@@ -0,0 +1,66 @@
export type MessageDelayUnit = 'minutes' | 'hours' | 'days';
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;
return n * 86_400_000;
}
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 = new Date(now.getTime() + delayMs(startValue, startUnit));
const gap = delayMs(Math.max(1, intervalValue), intervalUnit);
return Array.from({ length: count }, (_, i) => new Date(first.getTime() + i * gap));
}
export function applyMessageTemplate(text: string, title: string): string {
return text.replace(/\{title\}/g, title).replace(/\{عنوان\}/g, title);
}
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 [];
}