queue-med/shared/smsTemplates.ts

118 lines
3.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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,
});
}