Summary
Implement the Twilio WhatsApp provider for sending rich ticket confirmations via WhatsApp. Uses the same Twilio API as SMS but with WhatsApp-specific formatting and approved message templates.
API Reference
- Docs: https://www.twilio.com/docs/whatsapp/api
- Endpoint: Same as SMS —
POST /2010-04-01/Accounts/{SID}/Messages.json
- Auth: Same as SMS — Account SID + Auth Token
- From:
whatsapp:+14155238886 (Twilio sandbox) or approved business number
Key Difference from SMS
The only API difference is the From and To format:
From: "whatsapp:+14155238886" (instead of plain phone number)
To: "whatsapp:+2348012345678" (prefix with "whatsapp:")
WhatsApp Message Templates
WhatsApp Business API requires pre-approved templates for outbound messages. For the sandbox, freeform messages work.
Ticket Confirmation (Rich Message)
🎟️ *Ticket Confirmed!*
*Event:* Lagos Tech Summit 2026
*Date:* May 15, 2026 at 9:00 AM
*Venue:* Eko Convention Center, Lagos
*Ticket:* VIP
*Reference:* HOSTIT_TKT_A3F2B9C1
Your QR code is attached below. Show it at the entrance for entry.
View your ticket: https://hostit.ng/tickets/HOSTIT_TKT_A3F2B9C1
WhatsApp supports:
- Bold text
- Italic text
- Media attachments (QR code image)
- Links (auto-previewed)
Sending Media (QR Code)
await this.client.messages.create({
to: 'whatsapp:+2348012345678',
from: 'whatsapp:+14155238886',
body: 'Your ticket for Lagos Tech Summit is confirmed! Show this QR at entry.',
mediaUrl: ['https://cdn.hostit.ng/qr/A3F2B9C1.png'], // must be publicly accessible URL
});
Implementation
// src/notifications/providers/twilio-whatsapp.provider.ts
@Injectable()
export class TwilioWhatsappProvider {
private client: twilio.Twilio;
constructor(private configService: ConfigService) {
this.client = twilio(
this.configService.get('TWILIO_ACCOUNT_SID'),
this.configService.get('TWILIO_AUTH_TOKEN'),
);
}
async send(params: {
to: string; // +234XXXXXXXXXX (will be prefixed with whatsapp:)
body: string;
mediaUrl?: string[]; // QR code URL
}): Promise<void> {
await this.client.messages.create({
to: `whatsapp:${params.to}`,
from: `whatsapp:${this.configService.get('TWILIO_WHATSAPP_NUMBER')}`,
body: params.body,
mediaUrl: params.mediaUrl,
});
}
}
Tasks
WhatsApp Business API Limitations
| Limitation |
Detail |
| Template messages |
Outbound messages must use approved templates (except sandbox) |
| 24-hour window |
Free-form replies only within 24h of user's last message |
| Media URLs |
Must be publicly accessible HTTPS URLs |
| Rate limits |
Varies by tier (1K-100K messages/day) |
For initial development, use the Twilio WhatsApp Sandbox which allows freeform messages. Production requires approved templates via WhatsApp Business API.
Acceptance Criteria
- WhatsApp messages sent via Twilio API
- Phone numbers correctly prefixed with
whatsapp:
- QR code sent as media attachment (publicly accessible URL)
- Rich formatting used (bold event name, structured layout)
- Twilio errors handled gracefully
- Dev mode: messages logged to console
- Works with Twilio sandbox for development
Summary
Implement the Twilio WhatsApp provider for sending rich ticket confirmations via WhatsApp. Uses the same Twilio API as SMS but with WhatsApp-specific formatting and approved message templates.
API Reference
POST /2010-04-01/Accounts/{SID}/Messages.jsonwhatsapp:+14155238886(Twilio sandbox) or approved business numberKey Difference from SMS
The only API difference is the
FromandToformat:WhatsApp Message Templates
WhatsApp Business API requires pre-approved templates for outbound messages. For the sandbox, freeform messages work.
Ticket Confirmation (Rich Message)
WhatsApp supports:
Sending Media (QR Code)
Implementation
Tasks
src/notifications/providers/twilio-whatsapp.provider.ts:whatsapp:to From and To numbersrenderWhatsappTemplate(type, data) → { body, mediaUrl? }TWILIO_WHATSAPP_NUMBERto env configWhatsApp Business API Limitations
For initial development, use the Twilio WhatsApp Sandbox which allows freeform messages. Production requires approved templates via WhatsApp Business API.
Acceptance Criteria
whatsapp: