Passa al contenuto principale

UC-027 — Re-engagement Workflow (Retry su Canale Diverso)

CampoValore
IDUC-027
ObiettivoReinviare un messaggio su un canale alternativo se il primo tentativo fallisce
CanaleWhatsApp → SMS (fallback manuale)
Complessità⭐⭐⭐ Avanzato
Tempo stimato20 minuti
API coinvoltePOST /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 UNKNOWN (ancora in transito, senza ricevuta di consegna) 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.
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. La lettura non è uno stato: il messaggio resta DELIVERED e la lettura si rileva tramite l'evento webhook READ o tramite readDate, che WhatsApp valorizza.

Step 1 — Invia il messaggio primario su WhatsApp​

Invia il messaggio promozionale su WhatsApp:

curl -X POST https://api.qlara.ai/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": []
}
}
}
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://api.qlara.ai/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": "UNKNOWN",
"deliveryStatusDescription": "unknown",
"sendDate": "2026-04-09T10:00:00+02:00",
"deliveryDate": null,
"readDate": null
}
Dietro le quinte — Quando attivare il fallback

La decisione di quando attivare il retry dipende dal tipo di messaggio:

Tipo messaggioTimeout suggeritoMotivazione
Promozionale2-4 oreL'utente potrebbe leggere più tardi, non urgente
Reminder appuntamento30-60 minutiDeve arrivare in tempo utile
Notifica sicurezza10-15 minutiCritico, necessita consegna immediata
Billing/scadenza1-2 oreImportante ma non critico nell'immediato

Gli stati che indicano fallimento su WhatsApp sono:

  • ERROR (statusCode 9): consegna fallita, retry immediato
  • EXPIRED (statusCode 4): finestra di validità scaduta, retry immediato
  • DISABLED (statusCode 10): il destinatario ha WhatsApp disattivato, retry immediato
  • UNSUPPORTED (statusCode 11): il numero non supporta WhatsApp, retry immediato
  • CONVERSATION_CLOSED (statusCode 12): la finestra di assistenza clienti di 24 ore era chiusa, retry immediato
  • UNKNOWN dopo il timeout: il messaggio è ancora in transito senza ricevuta di consegna (WhatsApp non ha uno stato intermedio), probabile assenza di WhatsApp

Step 3 — Invia il fallback su SMS​

Se lo stato non è DELIVERED dopo il timeout (un messaggio letto mantiene lo stato DELIVERED), adatta il contenuto e invia via SMS:

curl -X POST https://api.qlara.ai/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 } } }
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://api.qlara.ai/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​

StepAzioneRisultato
1POST /whatsapp/sendmessageId restituito, accepted: true
2GET /messages/status/{id}?channel=WHATSAPPdeliveryStatus: "UNKNOWN" (non consegnato dopo timeout)
3POST /sms/sendNuovo messageId, accepted: true
4GET /messages/status/{id}?channel=SMSdeliveryStatus: "DELIVERED" su SMS

Esempio completo end-to-end​

#!/bin/bash
# Re-engagement workflow: WhatsApp → SMS fallback
API_KEY="YOUR_API_KEY"
BASE_URL="https://api.qlara.ai"
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" ]]; then # un messaggio letto resta DELIVERED
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​

Riferimenti​