6.2 WhatsAppController
Route: api/v1/WhatsApp (no class-level [Route] override — base VersionedApiController pattern) ·
4 endpoints · Manual test endpoints for platform administrators to verify the platform's own WhatsApp
number end-to-end, without going through any business flow.
All four actions use PermissionConstants.WhatsApp.* — the one permission family not shared with the Inbox
system.
POST SendTestText
Purpose: send a manual free-text WhatsApp message for connectivity testing.
Permission: WhatsApp.SendText
Request (WhatsAppTextMessageRequestDto):
{ "to": "966501112222", "body": "This is a test message from Shumoul", "previewUrl": false }
Response (raw WhatsAppTextMessageResponseDto, not wrapped in Result<T>):
{ "success": true, "messageId": "wamid.HBgL...", "errorCode": null, "errorMessage": null, "rawResponse": "{...}" }
Error cases: invalid to format → Meta returns an error code, surfaced as success: false with
errorCode/errorMessage populated (not an HTTP error).
Backend service: IWhatsAppService.SendTextAsync. Calls Meta API: Yes.
Angular: admin diagnostics screen only — never expose to end users. Flutter: not applicable (admin-only, web-only tooling).
POST SendTestTemplate
Purpose: send a manual approved-template WhatsApp message for connectivity/template testing.
Permission: WhatsApp.SendTemplate
Request (WhatsAppTemplateMessageRequestDto):
{
"to": "966501112222",
"templateName": "hello_world",
"languageCode": "en",
"components": [{ "type": "body", "parameters": [{ "type": "text", "text": "Test" }] }]
}
Response (raw WhatsAppTemplateMessageResponseDto):
{ "success": true, "messageId": "wamid.HBgL...", "errorCode": null, "errorMessage": null, "rawResponse": "{...}" }
Error cases: unapproved/unknown templateName → Meta error surfaced via errorCode/errorMessage.
Backend service: IWhatsAppService.SendTemplateAsync. Calls Meta API: Yes.
Angular/Flutter: admin diagnostics only.
POST SendActivationTest
Purpose: manually test the tenant-activation WhatsApp template against any phone number, without
waiting for a real subscription activation event.
Permission: WhatsApp.SendTemplate
Request (WhatsAppActivationTestRequest):
{ "to": "966501112222", "customerName": "Ahmed Al-Otaibi", "organizationName": "Al-Otaibi Trading Co.", "languageCode": "ar" }
Response: { "message": "Activation test message sent successfully" }
Error cases: template not approved for the tenant's language → error message returned in the same shape.
Backend service: IWhatsAppActivationMessageService.SendTenantActivationMessageAsync →
IWhatsAppService.SendTemplateAsync. Calls Meta API: Yes.
Angular/Flutter: admin diagnostics only.
POST SendOtpTest
Purpose: manually test the OTP WhatsApp template against any phone number.
Permission: WhatsApp.SendTemplate
Request (WhatsAppOtpTestRequest):
{ "to": "966501112222", "otpCode": "482913", "languageCode": "ar" }
Response: { "message": "OTP test message sent successfully" }
Error cases: same shape as above. The OTP code in the request is never logged server-side.
Backend service: IWhatsAppOtpMessageService.SendTenantOtpMessageAsync →
IWhatsAppService.SendTemplateAsync. Calls Meta API: Yes.
Angular/Flutter: admin diagnostics only — never wire this endpoint into a real OTP flow; it exists purely
for manual verification.
