All files / lib/communication/whatsapp payload-builder.ts

100% Statements 12/12
90% Branches 9/10
100% Functions 4/4
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59                                              12x 2x             10x                                 15x 13x 15x 1x   15x 1x   12x    
// Builds Meta WhatsApp Cloud API payloads. Extracted from whatsapp.adapter
// so that both the transactional send path AND the campaign broadcast
// orchestrator build payloads identically (DRY). Any change to the
// Meta payload shape must land here.
import type { WhatsAppContent } from "../types";
import type { WhatsAppTemplateComponent } from "../../whatsapp/types";
 
export type WhatsAppPayload = {
	messaging_product: "whatsapp";
	to: string;
	type: "text" | "template";
	text?: { body: string };
	template?: {
		name: string;
		language: { code: string; policy: "deterministic" };
		components?: WhatsAppTemplateComponent[];
	};
};
 
export function buildWhatsAppPayload(
	to: string,
	content: WhatsAppContent,
): WhatsAppPayload {
	if (content.textBody) {
		return {
			messaging_product: "whatsapp",
			to,
			type: "text",
			text: { body: content.textBody },
		};
	}
	return {
		messaging_product: "whatsapp",
		to,
		type: "template",
		template: {
			name: content.templateName,
			language: { code: content.languageCode, policy: "deterministic" },
			components: content.components,
		},
	};
}
 
/**
 * Readable preview text used for admin UIs and audit logs. Never used to
 * format actual outbound messages.
 */
export function buildWhatsAppPreviewText(content: WhatsAppContent): string {
	if (content.textBody) return content.textBody;
	const body = content.components?.find((c) => c.type === "body");
	const params = body?.parameters
		?.map((p) => ("text" in p ? p.text : ""))
		.filter(Boolean);
	if (params && params.length > 0) {
		return `Template ${content.templateName}: ${params.join(" ")}`;
	}
	return `Template ${content.templateName}`;
}