Canali WhatsApp
A partire dalla v3.5.0 Queria espone un'astrazione di canale per consentire ai bot aziendali di ricevere e rispondere a messaggi su piattaforme di messaging esterne. La prima implementazione disponibile e Twilio for WhatsApp.
L'astrazione e progettata per accogliere in versioni successive Telegram, SMS, Slack senza refactor del core.
Lato utente
Per la guida utente (abbinamento numero, comandi, esempi d'uso) vedi Chat WhatsApp.
Modello operativo V1
| Aspetto | V1 |
|---|---|
| Provider | Twilio (only) |
| Canale | WhatsApp (only) |
| Numero in prod | Numero Meta-approvato shared, di proprieta Queria |
| Numero in dev | Sandbox Twilio (whatsapp:+14155238886) |
| Modello tenant | Account Twilio condiviso, fromAddress opzionalmente tenant-specifico |
| Inbound | Solo testo (immagini/audio rifiutati con messaggio cortese) |
| Outbound | Solo risposte a inbound (no notifiche proattive in V1) |
| Pairing | Codice via web app, comando /pair <CODICE> da WhatsApp |
| Rate limit | 10 messaggi inbound / 60s per numero |
Architettura
WhatsApp (utente)
| inbound (Twilio webhook)
v
+------------------+ +------------------+ +------------------+
| Twilio Webhook | ---> | Channel Inbound | ---> | runCanvasChat |
| Verify signature | | Service | | (canvas CHAT |
| Dedup | | - Pair commands | | whatsapp-default)|
| Rate limit | | - Resolve user | +------------------+
+------------------+ | - Active conv | |
+------------------+ | response text
v
+------------------+
| TwilioChannel |
| Adapter.send |
| - Format WA MD |
| - Split 1500 ch |
| - REST send |
+------------------+
|
v
WhatsApp (utente)Il canvas CHAT che viene eseguito sul messaggio inbound e lo stesso usato per la web app, con il flag sys.channel = 'whatsapp' propagato. I componenti LLM possono leggerlo e adattare l'output (es. linguaggio piu compatto, omissione di blocchi tabellari).
Configurazione globale (SYSTEM_ADMIN)
Variabili .env richieste:
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=********
TWILIO_DEFAULT_FROM=whatsapp:+14155238886 # sandbox in dev
TWILIO_WEBHOOK_URL=https://admin.queria.pro/api/webhooks/twilio
# Pairing
CHANNEL_PAIR_CODE_TTL_MS=600000 # 10 minuti
CHANNEL_PAIR_RATE_LIMIT=3 # max 3 codici/ora per utente
# Inbound rate limit
CHANNEL_INBOUND_RPS_BUCKET=10 # messaggi
CHANNEL_INBOUND_RPS_WINDOW=60 # secondiConfigurare nel pannello provider Twilio:
- Messaging > WhatsApp Senders > Sandbox (dev) o Numero approvato (prod).
- Webhook URL =
https://admin.queria.pro/api/webhooks/twiliocon metodoPOST. - Genera
AUTH_TOKENe configuralo nel.env(mai committare).
Configurazione per tenant
Pannello admin > DSL e Pipeline > Canali WhatsApp.
| Campo | Default | Configurabile da |
|---|---|---|
| Enabled | false | SYSTEM_ADMIN |
| fromAddress | Default Queria | SYSTEM_ADMIN |
| Canvas pipeline | whatsapp-default | COMPANY_ADMIN (selezione) |
| Auto-provision webhook | true | SYSTEM_ADMIN |
Per assegnare un numero dedicato a un tenant (Meta-approvato):
- Acquista il numero su Twilio Console.
- Inserisci
whatsapp:+<numero>nel campofromAddressdel tenant. - Il backend chiama Twilio
IncomingPhoneNumbersAPI per puntareSmsUrlal webhook Queria. - Una cron giornaliera rinfresca questa configurazione (TTL 30 giorni).
Solo SYSTEM_ADMIN puo scrivere fromAddress
COMPANY_ADMIN vede il numero in sola lettura nella scheda azienda. Gli end user vedono il numero nel proprio profilo per sapere a chi mandare i messaggi.
Pairing utenti
Un utente esegue il pairing una volta sola dal proprio profilo (vedi Chat WhatsApp - lato utente).
Internamente:
ChannelPairCode-- tabella codici generati (8 char, alfabeto 32 chars, TTL 10 min).ChannelBinding-- riga finale per(channel, address)-> User. Globalmente unica.WebhookDedup-- dedup perproviderMessageIdper evitare doppi processi su retry Twilio.
Dal pannello admin DSL e Pipeline > Canali WhatsApp > Bindings:
- Tabella di tutti gli abbinamenti del tenant (utente, numero, ultimo messaggio, conteggio messaggi totali).
- Filtri per utente, range data, stato.
- Possibilita di forzare unbind per
/stoplato admin (es. dipendente uscito).
Comandi gestiti
Vengono intercettati prima dell'esecuzione del canvas:
| Comando | Effetto backend |
|---|---|
/pair <CODICE> | Lookup ChannelPairCode, validazione TTL/usato, creazione ChannelBinding |
/reset | Chiude la Conversation attiva (closedAt = now()), il messaggio successivo apre una nuova |
/stop | Cancella ChannelBinding. Liberato il numero. Messaggi successivi rifiutati con "non riconosciuto" |
/help | Risponde con elenco comandi |
Tutto cio che non e un comando passa al canvas.
Output formatting
Il TwilioChannelAdapter post-processa la risposta del canvas:
- Converte Markdown standard in WhatsApp-flavored markdown (
*bold*,_italic_,~strike~,`per code). - Aggiunge un footer fonti:
*Fonti:* 1) Contratto Manutenzione 2026.pdf 2) Allegato Tecnico A.docx - Suddivide hard a 1500 caratteri per chunk (limite Twilio).
- Invia in sequenza via
messages.create.
Logging e monitoring
Ogni messaggio inbound/outbound genera record in:
ChannelMessageLog(Postgres) --providerMessageId,direction,latencyMs,statusCode.IngestionCallLogper i fallimenti Twilio (es. numero non opt-in).- Metrica Prometheus (se enabled):
queria_channel_messages_total{provider,channel,direction,status}.
Pagina admin Canali > Monitoring: grafici di volume, latenza, tasso di errore, top utenti per messaggi.
Privacy e conformita
- I messaggi inbound sono cifrati E2E da WhatsApp fino al gateway Twilio. Da Twilio a Queria viaggia HTTPS.
- Le risposte sono soggette alla finestra 24h customer service di Meta: oltre 24h dall'ultima interazione, serve un template HSM (V2).
/stope il diritto all'opt-out lato utente. CancellaChannelBinding. La cronologiaConversationresta a meno di esplicita richiesta di rimozione (GDPR right to erasure).- I dati Twilio (Account SID, Auth Token) sono conservati cifrati nelle env vars; il pannello UI non li espone in chiaro.
Limiti e roadmap
V1:
- Provider Twilio only. Telegram/SMS/Slack supportati a livello di adapter, non implementati.
- Solo testo inbound.
- Solo conversazioni avviate dall'utente (no push proattivo).
- Solo un'active conversation per (User, channel).
V2 (roadmap):
- Template HSM per messaggi proattivi.
- Multi-tenant credentials Twilio (account separato per tenant).
- Telegram adapter come secondo provider.
- Multimedia inbound (immagini su un sink documenti).
Troubleshooting
"Codice scaduto" -- l'utente ha aspettato piu di 10 minuti. Generane uno nuovo.
"Numero gia abbinato" -- l'utente target deve fare /stop prima di ri-abbinarsi.
Webhook 403 -- verifica TWILIO_AUTH_TOKEN. Le firme HMAC-SHA1 devono coincidere.
Messaggio non risposto -- controlla:
WebhookDedup(e' uno duplicato?).- Rate limit (>10 msg/60s?).
- Errore canvas (vedi
IngestionCallLog).
"Per ora accetto solo messaggi testuali" -- l'utente ha inviato media. V1 e text-only.
Queria v3.5.0 -- Channels (Twilio WhatsApp V1)