118 lines
3.1 KiB
TypeScript
118 lines
3.1 KiB
TypeScript
/**
|
||
* SMS message templates with dynamic variable interpolation.
|
||
*
|
||
* SMS messages avoid markdown (no *bold*) and rich emojis to keep
|
||
* carrier compatibility and minimise character count (1 SMS = 160 chars
|
||
* GSM-7, 70 chars UCS-2). Templates are kept short by design.
|
||
*
|
||
* Variables disponibles :
|
||
* {{nom}} – Nom du patient
|
||
* {{ticket}} – Numéro de ticket
|
||
* {{position}} – Position dans la file
|
||
* {{attente}} – Temps d'attente estimé (en minutes)
|
||
* {{cabinet}} – Nom du cabinet
|
||
*/
|
||
|
||
import {
|
||
type TemplateContext,
|
||
type TemplateType,
|
||
interpolateTemplate,
|
||
} from "./whatsappTemplates.js";
|
||
|
||
export type { TemplateContext, TemplateType };
|
||
|
||
// ─── Default SMS templates (French, plain-text, short) ───────────────────────
|
||
|
||
export const DEFAULT_SMS_TEMPLATES: Record<TemplateType, string> = {
|
||
joined:
|
||
`QueueMed - {{cabinet}}\n` +
|
||
`Ticket {{ticket}} | Position {{position}} | ~{{attente}}min\n` +
|
||
`Restez a proximite, vous serez prevenu(e) avant votre tour.`,
|
||
|
||
soon:
|
||
`QueueMed - {{cabinet}}\n` +
|
||
`Votre tour approche! Ticket {{ticket}}, ~{{attente}}min.\n` +
|
||
`Merci de venir en salle d'attente maintenant.`,
|
||
|
||
called:
|
||
`QueueMed - {{cabinet}}\n` +
|
||
`C'est votre tour! Ticket {{ticket}}.\n` +
|
||
`Veuillez vous presenter au cabinet.`,
|
||
|
||
withdrawn:
|
||
`QueueMed - {{cabinet}}\n` +
|
||
`Desistement enregistre. Ticket {{ticket}} annule. A bientot!`,
|
||
};
|
||
|
||
/**
|
||
* Get the effective SMS template: custom if set, otherwise default.
|
||
*/
|
||
export function getEffectiveSmsTemplate(
|
||
type: TemplateType,
|
||
customTemplates?: Partial<Record<TemplateType, string | null>>
|
||
): string {
|
||
const custom = customTemplates?.[type];
|
||
if (custom && custom.trim().length > 0) return custom;
|
||
return DEFAULT_SMS_TEMPLATES[type];
|
||
}
|
||
|
||
/**
|
||
* Build a final SMS message with template + interpolated variables.
|
||
*/
|
||
export function buildSmsMessage(
|
||
type: TemplateType,
|
||
context: TemplateContext,
|
||
customTemplates?: Partial<Record<TemplateType, string | null>>
|
||
): string {
|
||
const template = getEffectiveSmsTemplate(type, customTemplates);
|
||
return interpolateTemplate(template, context);
|
||
}
|
||
|
||
export function buildSmsJoinMessage(
|
||
clinicName: string,
|
||
ticketNumber: number,
|
||
position: number,
|
||
estimatedWait: number
|
||
): string {
|
||
return buildSmsMessage("joined", {
|
||
nom: "",
|
||
ticket: ticketNumber,
|
||
position,
|
||
attente: estimatedWait,
|
||
cabinet: clinicName,
|
||
});
|
||
}
|
||
|
||
export function buildSmsSoonMessage(
|
||
clinicName: string,
|
||
ticketNumber: number,
|
||
minutesLeft: number
|
||
): string {
|
||
return buildSmsMessage("soon", {
|
||
nom: "",
|
||
ticket: ticketNumber,
|
||
position: 0,
|
||
attente: minutesLeft,
|
||
cabinet: clinicName,
|
||
});
|
||
}
|
||
|
||
export function buildSmsCalledMessage(clinicName: string, ticketNumber: number): string {
|
||
return buildSmsMessage("called", {
|
||
nom: "",
|
||
ticket: ticketNumber,
|
||
position: 0,
|
||
attente: 0,
|
||
cabinet: clinicName,
|
||
});
|
||
}
|
||
|
||
export function buildSmsWithdrawnMessage(clinicName: string, ticketNumber: number): string {
|
||
return buildSmsMessage("withdrawn", {
|
||
nom: "",
|
||
ticket: ticketNumber,
|
||
position: 0,
|
||
attente: 0,
|
||
cabinet: clinicName,
|
||
});
|
||
}
|