Skip to main content
Version: Latest

9. Templates

9.1 Template Send Structure

A template message (WhatsAppTemplateMessageRequestDto) references a Meta-approved template by name and language, plus zero or more components that fill in the template's variable placeholders:

{
"to": "966501112222",
"templateName": "send_document_invoice",
"languageCode": "ar",
"components": [
{ "type": "body", "parameters": [
{ "type": "text", "text": "Ahmed" },
{ "type": "text", "text": "12500.00" },
{ "type": "text", "text": "INV-2026-00451" }
] }
]
}

Templates, their approved languages, and their variable count/order are all defined and approved on Meta's side (via the Meta Business Manager) — Shumoul never creates or modifies a template definition through this integration. Sending a template name Meta hasn't approved for the sender's number, or supplying the wrong number/type of parameters, results in a Meta-side rejection surfaced through the response's ErrorCode/ErrorMessage.

9.2 Variables and Components

Component typePurposeNotes
bodyThe template's main text, with {{1}}, {{2}}, … positional placeholdersParameters supplied in array order
headerOptional header — text or media (ImageUrl/DocumentUrl/VideoUrl on the parameter)Media headers reference a public URL, not an uploaded binary — see §3.2
buttonOptional interactive button (e.g. a URL button reusing an OTP code)Requires SubType (url/quick_reply) and Index

WhatsAppTemplateComponentParameterDto.Type defaults to "text"; ImageUrl/DocumentUrl/VideoUrl/ Payload are used for media or button-specific parameter types.

9.3 Approved Templates in Use

Template (Arabic / English)Used byBody parameters
otp_verification_ar / otp_verification_enWhatsAppOtpMessageService1 — the OTP code (plus an optional URL button reusing the code, if WhatsAppTenantOtpIncludeUrlButton is true)
welcome_activation_ar / welcome_activation_enWhatsAppActivationMessageService2 — customer name, organization name
{DefaultTemplatePrefix}_{documentType} (default prefix send_document)CommunicationService/TenantWhatsAppSender (business documents — invoices, quotes, receipts)Varies by document type — resolved via Data object passed to Send/Document
Notification Framework per-event templates (AppNotificationTemplate.WhatsAppTemplateName)MetaWhatsAppProvider (template name/language/params resolved and rendered by NotificationDispatchService before the provider is called)Defined per template via WhatsAppBodyParams (a JSON array of Scriban expressions) — see the Notification Framework's WhatsApp channel docs

Template names, languages, and defaults are all configurable per tenant via WhatsAppOperationalSettings and SaaSNotificationSettings — see §4 Configuration.

9.4 OTP Template

Sent with exactly one body parameter (the OTP code). If WhatsAppTenantOtpIncludeUrlButton is true, a second button component of SubType: "url" reuses the same code as its Payload. The OTP code is never logged anywhere in the send pipeline — TenantNotificationLog records only the literal string "Template:{templateName}" as the message body.

9.5 Activation Template

Sent with two body parameters — customer name and organization name — resolved via WhatsAppActivationMessageService.SendTenantActivationMessageAsync. Only sent when WhatsAppOperationalSettings.EnableWhatsAppActivationForFreeSubscriptions allows it for free-tier tenants, or unconditionally for paid activations.

9.6 Invoice / Business Document Template

Resolved dynamically: {DefaultTemplatePrefix}_{documentType in lowercase} combined with the tenant's TemplateLanguageStrategy (ByRecipientLanguage by default). The Data object passed to Send/Document or Send/WhatsApp supplies the values that fill the resolved template's body parameters — the exact mapping is template-specific and configured per tenant, not hardcoded in the ERP.

9.7 Error Cases

CauseSurfaced as
Template name not approved for the sender's number/languageMeta error code/message in WhatsAppTemplateMessageResponseDto.ErrorCode/ErrorMessage, or in the Result<Guid>.FailureAsync message for Communication-module sends
Wrong number of body parametersSame as above — Meta rejects the request
Recipient phone fails normalization (WhatsAppPhoneHelper.TryNormalizePhone returns false)Dispatch skipped before any Meta call; failure message states the recipient phone is invalid
Tenant's WhatsApp sending disabled (EnableSending == false)Result<Guid>.FailureAsync — a configuration failure, not a Meta error
24-hour customer-service window expired (Inbox free-text reply only — does not apply to template sends)See §6.3 SendReply — templates are exempt from this window by Meta's own rules