UC-027 — Re-engagement Workflow (Retry su Canale Diverso)
| Campo | Valore |
|---|---|
| ID | UC-027 |
| Obiettivo | Reinviare un messaggio su un canale alternativo se il primo tentativo fallisce |
| Canale | WhatsApp → SMS (fallback manuale) |
| Complessità | ⭐⭐⭐ Avanzato |
| Tempo stimato | 20 minuti |
| API coinvolte | POST /api/message-server/whatsapp/send, GET /api/partner-gateway/v1/messages/status/{customerMessageId}, POST /api/message-server/sms/send |
Scenari reali
- FashionOutlet — Promo non consegnata: Il messaggio promozionale WhatsApp per i saldi invernali non viene consegnato (utente senza WhatsApp). Il sistema rileva il fallimento e invia automaticamente un SMS con lo stesso contenuto.
- ClinicaSalute — Reminder appuntamento: Il promemoria inviato via WhatsApp resta in stato SENT per oltre 2 ore. L'applicazione decide di inviare un SMS di backup per assicurare che il paziente riceva l'avviso.
- BancaSicura — Notifica scadenza pagamento: L'avviso di scadenza rata inviato su WhatsApp fallisce. Il sistema scala su SMS entro 30 minuti per garantire la ricezione nei tempi utili.
:::info Differenza da UC-005 (Multi-Channel Fallback) Nel UC-005 il fallback e automatico: il gateway gestisce la catena WhatsApp → RCS → SMS in modo trasparente. In questo UC-027, il fallback e manuale e controllato dalla tua applicazione: sei tu a decidere quando, come e su quale canale ritentare. Questo approccio e utile quando vuoi applicare logica personalizzata (attese diverse, contenuti adattati per canale, limiti di budget). :::
Flusso del re-engagement
Il diagramma illustra il flusso decisionale: la tua applicazione invia su WhatsApp, attende il risultato, e in caso di fallimento adatta il contenuto e ritenta su SMS.
Step 1 — Invia il messaggio primario su WhatsApp
Invia il messaggio promozionale su WhatsApp:
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",
"sender": "+393801234567",
"content": {
"templateName": "promo_saldi_inverno",
"language": "it",
"components": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "Marco" },
{ "type": "text", "text": "30%" },
{ "type": "text", "text": "15 aprile" }
]
}
]
},
"enableNotification": true
}'
Response — Messaggio accettato
{
"messageId": "b8f3a21c-7d44-4e19-9a1b-3c5d7e9f0a12",
"simulation": false,
"results": {
"whatsapp": {
"accepted": true,
"reasons": []
}
}
}
:::tip Salva il messageId e il timestamp
Salva messageId e l'ora di invio nel tuo database. Ti serviranno per il polling e per calcolare il timeout di attesa prima del retry.
:::
Step 2 — Attendi e verifica lo stato di consegna
Dopo un intervallo ragionevole (es. 2 ore per messaggi promozionali, 30 minuti per notifiche urgenti), verifica lo stato:
curl -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/messages/status/b8f3a21c-7d44-4e19-9a1b-3c5d7e9f0a12?channel=WHATSAPP" \
-H "X-Api-Key: YOUR_API_KEY"
Response — Messaggio non consegnato
{
"customerMessageId": "b8f3a21c-7d44-4e19-9a1b-3c5d7e9f0a12",
"channel": "WHATSAPP",
"destination": "+393471234567",
"deliveryStatus": "SENT",
"deliveryStatusDescription": "Message sent but not delivered to device",
"sendDate": "2026-04-09T10:00:00+02:00",
"deliveryDate": null
}
Dietro le quinte — Quando attivare il fallback
La decisione di quando attivare il retry dipende dal tipo di messaggio:
| Tipo messaggio | Timeout suggerito | Motivazione |
|---|---|---|
| Promozionale | 2-4 ore | L'utente potrebbe leggere più tardi, non urgente |
| Reminder appuntamento | 30-60 minuti | Deve arrivare in tempo utile |
| Notifica sicurezza | 10-15 minuti | Critico, necessita consegna immediata |
| Billing/scadenza | 1-2 ore | Importante ma non critico nell'immediato |
Gli stati che indicano fallimento sono:
ERROR(statusCode 6): errore definitivo, retry immediatoEXPIRED(statusCode 8): TTL superato, retry immediatoSENTdopo il timeout: messaggio inviato ma non consegnato, probabile assenza di WhatsApp
Step 3 — Invia il fallback su SMS
Se lo stato non e DELIVERED o READ dopo il timeout, adatta il contenuto e invia via SMS:
curl -X POST https://lora-api.agiletelecom.com/api/message-server/sms/send \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"destination": "+393471234567",
"sender": "FashionOut",
"body": "Ciao Marco! Saldi invernali FashionOutlet: -30% su tutto fino al 15 aprile. Scopri le offerte: https://fashionoutlet.it/saldi Rispondi STOP per non ricevere più messaggi.",
"campaignId": "saldi-inverno-2026-retry",
"enableNotification": true
}'
Response — SMS accettato
{ "messageId": "c9a4b32d-8e55-4f20-ab2c-4d6e8f0a1b23", "simulation": false, "results": { "sms": { "accepted": true, "parts": 1 } } }
:::note Adatta il contenuto per il canale Il testo SMS ha limiti diversi da WhatsApp. Rimuovi formattazioni ricche, accorcia i link e includi sempre l'opzione di opt-out. :::
Step 4 — Verifica la consegna finale
Controlla lo stato dell'SMS di fallback:
curl -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/messages/status/c9a4b32d-8e55-4f20-ab2c-4d6e8f0a1b23?channel=SMS" \
-H "X-Api-Key: YOUR_API_KEY"
Response — Consegnato
{ "customerMessageId": "c9a4b32d-8e55-4f20-ab2c-4d6e8f0a1b23", "channel": "SMS", "deliveryStatus": "DELIVERED", "deliveryDate": "2026-04-09T12:05:02+02:00" }
Risultato atteso
| Step | Azione | Risultato |
|---|---|---|
| 1 | POST /whatsapp/send | messageId restituito, accepted: true |
| 2 | GET /messages/status/{id} | deliveryStatus: "SENT" (non consegnato dopo timeout) |
| 3 | POST /sms/send | Nuovo messageId, accepted: true |
| 4 | GET /messages/status/{id} | deliveryStatus: "DELIVERED" su SMS |
Esempio completo end-to-end
#!/bin/bash
# Re-engagement workflow: WhatsApp → SMS fallback
API_KEY="YOUR_API_KEY"
BASE_URL="https://lora-api.agiletelecom.com"
TIMEOUT_SECONDS=7200 # 2 ore per messaggi promozionali
# 1. Invio WhatsApp
WA_ID=$(curl -s -X POST "${BASE_URL}/api/message-server/whatsapp/send" \
-H "Content-Type: application/json" -H "X-Api-Key: ${API_KEY}" \
-d '{"destination":"+393471234567","sender":"+393801234567","content":{"templateName":"promo_saldi_inverno","language":"it","components":[{"type":"body","parameters":[{"type":"text","text":"Marco"},{"type":"text","text":"30%"},{"type":"text","text":"15 aprile"}]}]},"enableNotification":true}' | jq -r '.messageId')
# 2. Attendi e verifica
sleep ${TIMEOUT_SECONDS}
STATUS=$(curl -s -X GET "${BASE_URL}/api/partner-gateway/v1/messages/status/${WA_ID}?channel=WHATSAPP" \
-H "X-Api-Key: ${API_KEY}" | jq -r '.deliveryStatus')
# 3. Se non consegnato, retry su SMS
if [[ "$STATUS" != "DELIVERED" && "$STATUS" != "READ" ]]; then
SMS_ID=$(curl -s -X POST "${BASE_URL}/api/message-server/sms/send" \
-H "Content-Type: application/json" -H "X-Api-Key: ${API_KEY}" \
-d '{"destination":"+393471234567","sender":"FashionOut","body":"Ciao Marco! Saldi invernali: -30% fino al 15 aprile. https://fashionoutlet.it/saldi","campaignId":"saldi-inverno-2026-retry"}' | jq -r '.messageId')
echo "Retry SMS inviato: ${SMS_ID}"
fi
Varianti
Retry con escalation a tre canali
Aggiungi RCS come livello intermedio: WhatsApp → RCS → SMS. Dopo il fallimento WhatsApp, prova POST /rcs/send prima di ricadere su SMS.
Retry con contenuto differenziato per urgenza
Per notifiche critiche (es. sicurezza bancaria), riduci il timeout a 10 minuti e usa un testo SMS con tono urgente.
Errori comuni
WhatsApp — Template non approvato
{ "results": { "whatsapp": { "accepted": false, "reasons": ["Template not approved or not found"] } } }
Soluzione: Verifica che il template sia stato approvato da Meta (vedi UC-013).
Doppia consegna
Se il messaggio WhatsApp viene consegnato dopo il retry SMS, l'utente ricevera il messaggio su entrambi i canali. Usa timeout adeguati al tipo di messaggio (vedi tabella nello Step 2).
Prossimi passi
- UC-005 — Multi-Channel Fallback Automatico: Confronta con il fallback gestito dal gateway
- UC-004 — Verifica Delivery Status: Approfondisci polling e status codes
- UC-008 — Tracking Delivery via Webhook: Usa i webhook per decisioni real-time
- Guida SMS Universal: Documentazione completa del canale SMS