UC-003 — Invio WhatsApp con Template
| Campo | Valore |
|---|---|
| ID | UC-003 |
| Obiettivo | Inviare un messaggio WhatsApp Business tramite template approvato da Meta |
| Canale | |
| Complessità | Base |
| Tempo stimato | 15 minuti |
| API coinvolte | POST /api/message-server/whatsapp/send, GET /api/partner-gateway/v1/messages/status/{customerMessageId} |
Scenari reali
- OTP verification: BancaSicura invia un codice di verifica per confermare l'identita del cliente durante l'accesso all'home banking.
- Appointment reminder: Studio Medico Verdi invia un promemoria appuntamento 24 ore prima, con data, ora e indirizzo della struttura.
- Order update: FashionStore notifica il cliente che l'ordine e stato spedito, con link al tracking del corriere.
Ciclo di vita del template
Il template deve essere approvato da Meta prima di poterlo usare per l'invio. L'approvazione avviene una sola volta e puo richiedere da pochi minuti a 24 ore.
Step 1 — Identifica il template ID
Prima di inviare, devi conoscere l'id del template approvato. Puoi trovarlo nel pannello della piattaforma oppure via API:
curl -X GET "https://lora-api.agiletelecom.com/api/message-server/whatsapp/templates?status=APPROVED&phoneNumberId=5&limit=10" \
-H "X-Api-Key: YOUR_API_KEY"
Response — Lista template approvati
{
"data": [
{
"id": 42,
"name": "order_shipped",
"language": "it",
"category": "UTILITY",
"status": "APPROVED",
"components": [
{
"type": "HEADER",
"format": "IMAGE"
},
{
"type": "BODY",
"text": "Ciao {{1}}, il tuo ordine {{2}} e stato spedito! Tracking: {{3}}"
},
{
"type": "FOOTER",
"text": "FashionStore - Assistenza clienti"
},
{
"type": "BUTTONS",
"buttons": [
{
"type": "URL",
"text": "Traccia spedizione",
"url": "https://fashionstore.it/tracking/{{1}}"
}
]
}
]
},
{
"id": 58,
"name": "appointment_reminder",
"language": "it",
"category": "UTILITY",
"status": "APPROVED",
"components": [
{
"type": "BODY",
"text": "Gentile {{1}}, le ricordiamo l'appuntamento del {{2}} alle ore {{3}} presso {{4}}."
}
]
}
]
}
Dietro le quinte — Categorie template Meta
Meta classifica i template in tre categorie con regole e costi diversi:
| Categoria | Uso | Esempi |
|---|---|---|
| UTILITY | Messaggi transazionali richiesti dall'utente | Conferme ordine, aggiornamenti spedizione, promemoria |
| AUTHENTICATION | Codici OTP e verifica identita | Codici di accesso, verifica in due fattori |
| MARKETING | Comunicazioni promozionali | Offerte, newsletter, inviti ad eventi |
I template AUTHENTICATION hanno una struttura speciale con il bottone "Copia codice" integrato. I template MARKETING richiedono che l'utente abbia dato il consenso esplicito (opt-in).
Step 2 — Invia il messaggio con placeholder
Usa il template order_shipped (id: 42) con i placeholder valorizzati e un'immagine header:
curl -X POST https://lora-api.agiletelecom.com/api/message-server/whatsapp/send \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"destination": "+393401234567",
"phoneNumberId": 5,
"template": {
"id": 42,
"mediaUrl": "https://cdn.fashionstore.it/orders/box-shipped.jpg"
},
"placeholders": {
"1": "Marco",
"2": "#ORD-20260409",
"3": "https://corriere.it/track/BRT789456123"
},
"enableNotification": true
}'
Response — Messaggio accettato
{
"messageId": "b83c2f1a-9d4e-4b12-8c7f-3e5a1d2b4c6e",
"simulation": false,
"results": {
"whatsapp": {
"accepted": true
},
"rcs": null,
"sms": null
}
}
Dietro le quinte — Come vengono risolti i placeholder
I placeholder nel template Meta usano la sintassi {{1}}, {{2}}, ecc. Nella request API, li mappi con chiavi numeriche:
"1": "Marco"sostituisce{{1}}nel body del template"2": "#ORD-20260409"sostituisce{{2}}"3": "https://corriere.it/track/BRT789456123"sostituisce{{3}}
Se il template ha un bottone con URL dinamico (es. https://fashionstore.it/tracking/{{1}}), il placeholder del bottone usa lo stesso sistema numerico ma con scope separato.
Il campo mediaUrl nel template object viene usato per sostituire l'header IMAGE del template. L'immagine deve essere accessibile pubblicamente via HTTPS.
:::warning Finestra delle 24 ore
I messaggi template possono essere inviati in qualsiasi momento. I messaggi free-form (body) possono essere inviati solo entro 24 ore dall'ultimo messaggio ricevuto dall'utente. Fuori dalla finestra, usa sempre un template.
:::
Step 3 — Verifica la consegna
curl -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/messages/status/b83c2f1a-9d4e-4b12-8c7f-3e5a1d2b4c6e?channel=WHATSAPP" \
-H "X-Api-Key: YOUR_API_KEY"
Response — Consegnato e letto
{
"customerMessageId": "b83c2f1a-9d4e-4b12-8c7f-3e5a1d2b4c6e",
"channel": "WHATSAPP",
"destination": "+393401234567",
"deliveryStatus": "DELIVERED",
"deliveryStatusDescription": "Message delivered",
"sendDate": "2026-04-09T14:00:00+02:00",
"deliveryDate": "2026-04-09T14:00:01+02:00",
"readDate": "2026-04-09T14:02:30+02:00"
}
Dietro le quinte — Webhook WhatsApp
Per WhatsApp ricevi gli stessi tipi di callback di RCS:
DELIVERY:
{
"channel": "WHATSAPP",
"eventType": "DELIVERY",
"messageId": "b83c2f1a-9d4e-4b12-8c7f-3e5a1d2b4c6e",
"destination": "+393401234567",
"statusCode": 3,
"description": "delivered",
"eventDate": "2026-04-09T14:00:01Z"
}
READ:
{
"channel": "WHATSAPP",
"eventType": "READ",
"messageId": "b83c2f1a-9d4e-4b12-8c7f-3e5a1d2b4c6e",
"destination": "+393401234567",
"eventDate": "2026-04-09T14:02:30Z"
}
Configura il tuo endpoint nella guida Webhook.
Varianti
Template con bottoni tracked
Per tracciare i click sui bottoni URL del template, usa il placeholder shortLinkT1 che genera un link tracciato:
curl -X POST https://lora-api.agiletelecom.com/api/message-server/whatsapp/send \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"destination": "+393401234567",
"phoneNumberId": 5,
"template": {
"id": 42
},
"placeholders": {
"1": "Giulia",
"2": "#ORD-20260410",
"3": "https://corriere.it/track/BRT111222333",
"shortLinkT1": "https://fashionstore.it/tracking/BRT111222333"
},
"enableNotification": true
}'
Template con header image
Se il template ha un header di tipo IMAGE, passa la mediaUrl dentro l'oggetto template:
curl -X POST https://lora-api.agiletelecom.com/api/message-server/whatsapp/send \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"destination": "+393471234567",
"phoneNumberId": 5,
"template": {
"id": 58,
"mediaUrl": "https://cdn.studiomedico.it/logo-reminder.png"
},
"placeholders": {
"1": "Sig. Rossi",
"2": "10 aprile 2026",
"3": "15:30",
"4": "Studio Medico Verdi - Via Garibaldi 25, Roma"
},
"enableNotification": true
}'
Invio con fallback SMS
Se il destinatario non ha WhatsApp, il messaggio puo cadere automaticamente su SMS:
curl -X POST https://lora-api.agiletelecom.com/api/message-server/whatsapp/send \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"destination": "+393401234567",
"phoneNumberId": 5,
"template": {
"id": 42
},
"placeholders": {
"1": "Marco",
"2": "#ORD-20260409",
"3": "https://corriere.it/track/BRT789456123"
},
"fallbackSms": {
"sender": "FStore",
"text": "Ciao Marco, il tuo ordine #ORD-20260409 e stato spedito! Tracking: https://corriere.it/track/BRT789456123"
},
"enableNotification": true
}'
Response — Fallback SMS attivato
{
"messageId": "c4d5e6f7-8901-2345-6789-abcdef012345",
"simulation": false,
"results": {
"whatsapp": {
"accepted": false,
"reasons": ["WhatsApp not available"]
},
"rcs": null,
"sms": {
"accepted": true,
"unicode": false,
"parts": 1,
"reasons": []
}
}
}
Errori comuni
Template non approvato
{
"status": "fail",
"data": {
"template": "Template 42 is not in APPROVED status"
}
}
Soluzione: Verifica che il template sia in stato APPROVED tramite il pannello o la API GET /whatsapp/templates?status=APPROVED.
phoneNumberId non valido
{
"status": "fail",
"data": {
"phoneNumberId": "Phone number not found or not associated with your account"
}
}
Soluzione: Usa GET /whatsapp/phone-numbers per ottenere gli ID dei numeri WhatsApp Business associati al tuo account.
Placeholder mancanti
Se il template richiede placeholder che non sono stati forniti, il messaggio viene rifiutato. Verifica la struttura del template e fornisci tutti i valori necessari.
Risultato atteso
| Step | Azione | Risultato |
|---|---|---|
| 1 | GET /whatsapp/templates | Template id e struttura placeholder |
| 2 | POST /whatsapp/send | messageId restituito, accepted: true |
| 3 | GET /messages/status/{id} | deliveryStatus: "DELIVERED", readDate presente |
Prossimi passi
- UC-001 — Invio SMS Singolo: Scenario base con canale SMS
- UC-002 — Invio RCS Rich Card: Rich card con media e bottoni interattivi
- UC-004 — Verifica Delivery Status: Polling batch e confronto webhook
- Guida WhatsApp: Documentazione completa del canale WhatsApp
- Guida Template WhatsApp: Crea e gestisci template WhatsApp