UC-018 — Gestire l'Inbox
| Campo | Valore |
|---|---|
| ID | UC-018 |
| Obiettivo | Gestire conversazioni in ingresso: triage, lettura, archiviazione |
| Canale | Tutti (SMS, RCS, WhatsApp, Messenger) |
| Complessità | Intermedia |
| Tempo stimato | 15 minuti |
| API coinvolte | GET /api/partner-gateway/v1/inbox/conversations, GET /api/partner-gateway/v1/inbox/conversations/{chatId}, GET /api/partner-gateway/v1/inbox/conversations/{chatId}/messages, PATCH /api/partner-gateway/v1/inbox/conversations/{chatId}/archive, PATCH /api/partner-gateway/v1/inbox/conversations/{chatId}/unarchive, PATCH /api/partner-gateway/v1/inbox/conversations/{chatId}/read, POST /api/partner-gateway/v1/inbox/conversations/{chatId}/assignee, DELETE /api/partner-gateway/v1/inbox/conversations/{chatId}/assignee, GET /api/partner-gateway/v1/inbox/conversations/assignable-users |
Scenari reali
- Customer support triage: Il team support di ShopOnline usa l'API per alimentare la propria dashboard interna e assegnare le conversazioni agli operatori disponibili.
- Archiviare risolte: Dopo aver chiuso un ticket, l'operatore archivia la conversazione per mantenere l'inbox pulita e focalizzata sui casi aperti.
- Monitorare non lette: Il supervisore controlla quante conversazioni non lette ci sono per valutare il carico di lavoro del team.
- Distribuzione del carico: Il supervisore elenca i membri del team assegnabili e assegna ogni conversazione a un agente specifico via API; l'agente riceve notifica del nuovo lavoro e l'assegnazione compare nella sua vista personalizzata dell'inbox.
Flusso di gestione inbox
Il diagramma mostra il workflow tipico: lista, lettura, marcatura, archiviazione e, opzionalmente, assegnazione della conversazione a un membro del team.
Prerequisiti
- API Key attiva con permessi di gestione inbox
- Almeno un canale attivo con messaggi in ingresso configurato
- Webhook di ricezione configurato (opzionale, per notifiche real-time)
Step 1 — Recupera le conversazioni attive
Elenca le conversazioni nell'inbox, con filtri per stato e canale.
curl -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations?status=active&limit=20" \
-H "X-Api-Key: YOUR_API_KEY"
Response — Lista conversazioni
{
"conversations": [
{
"chatId": "chat_abc123",
"channel": "WHATSAPP",
"contact": {
"phoneNumber": "+393471234567",
"name": "Marco Rossi"
},
"lastMessage": {
"body": "Buongiorno, vorrei informazioni sulla spedizione del mio ordine",
"direction": "INBOUND",
"timestamp": "2026-04-09T14:30:00+02:00"
},
"unreadCount": 3,
"status": "ACTIVE",
"createdAt": "2026-04-09T14:25:00+02:00"
},
{
"chatId": "chat_def456",
"channel": "SMS",
"contact": {
"phoneNumber": "+393489876543",
"name": "Giulia Bianchi"
},
"lastMessage": {
"body": "STOP",
"direction": "INBOUND",
"timestamp": "2026-04-09T13:45:00+02:00"
},
"unreadCount": 1,
"status": "ACTIVE",
"createdAt": "2026-04-09T13:45:00+02:00"
}
],
"total": 2,
"hasMore": false
}
:::tip Filtra per non lette
Aggiungi &unreadOnly=true alla query per visualizzare solo le conversazioni con messaggi non letti, utile per il triage.
:::
Dietro le quinte — Come funziona l'inbox
- Aggregazione: L'inbox aggrega messaggi provenienti da tutti i canali attivi (SMS, RCS, WhatsApp, Messenger) in un'unica vista unificata.
- Threading: I messaggi vengono raggruppati in conversazioni basate sul numero di telefono del contatto. Un cambio di canale dallo stesso numero crea una nuova conversazione.
- Ordinamento: Le conversazioni sono ordinate per timestamp dell'ultimo messaggio (più recente prima).
- Paginazione: L'endpoint supporta
limiteoffsetper la paginazione. Il campohasMoreindica se ci sono ulteriori risultati.
Step 2 — Leggi i messaggi di una conversazione
Recupera lo storico completo dei messaggi di una specifica conversazione.
curl -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/chat_abc123/messages?limit=50" \
-H "X-Api-Key: YOUR_API_KEY"
Response — Messaggi del thread
{
"chatId": "chat_abc123",
"messages": [
{
"messageId": "msg_001",
"direction": "INBOUND",
"body": "Buongiorno, vorrei informazioni sulla spedizione del mio ordine",
"timestamp": "2026-04-09T14:25:00+02:00",
"status": "RECEIVED"
},
{
"messageId": "msg_002",
"direction": "INBOUND",
"body": "Il numero ordine e #ORD-20260405",
"timestamp": "2026-04-09T14:26:00+02:00",
"status": "RECEIVED"
},
{
"messageId": "msg_003",
"direction": "INBOUND",
"body": "Potete aiutarmi?",
"timestamp": "2026-04-09T14:30:00+02:00",
"status": "RECEIVED"
}
],
"total": 3,
"hasMore": false
}
Step 3 — Marca come letto e archivia
Dopo aver gestito la conversazione, marcala come letta e poi archiviala.
# Marca come letto
curl -X PATCH https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/chat_abc123/read \
-H "X-Api-Key: YOUR_API_KEY"
Response — Marcato come letto
{
"chatId": "chat_abc123",
"unreadCount": 0,
"updatedAt": "2026-04-09T15:00:00+02:00"
}
# Archivia la conversazione risolta
curl -X PATCH https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/chat_abc123/archive \
-H "X-Api-Key: YOUR_API_KEY"
Response — Conversazione archiviata
{
"chatId": "chat_abc123",
"status": "ARCHIVED",
"archivedAt": "2026-04-09T15:01:00+02:00"
}
Dietro le quinte — Archiviazione e ripristino
- Archiviazione: La conversazione viene spostata nell'archivio e non compare più nella lista attiva. I messaggi restano accessibili.
- Ripristino: Usa
PATCH /conversations/{chatId}/unarchiveper riportare una conversazione nell'inbox attiva. - Nuovo messaggio: Se un contatto con conversazione archiviata invia un nuovo messaggio, la conversazione viene automaticamente ripristinata nell'inbox attiva.
- Retention: Le conversazioni archiviate vengono conservate per 12 mesi, poi spostate nello storico a lungo termine.
Step 4 — Assegna o rilascia una conversazione
Distribuisci il carico dell'inbox assegnando una conversazione a uno specifico membro del team, oppure rilasciala nella coda non assegnata.
Elenca i membri del team assegnabili
curl -X GET https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/assignable-users \
-H "X-Api-Key: YOUR_API_KEY"
Response — Membri del team
[
{
"id": 4521,
"fullName": "Anna Bianchi",
"profilePicture": "https://cdn.example.com/users/4521/avatar.png"
},
{
"id": 4522,
"fullName": "Luca Verdi",
"profilePicture": "https://cdn.example.com/users/4522/avatar.png"
},
{
"id": 4523,
"fullName": "Marco Rossi",
"profilePicture": null
}
]
Assegna la conversazione a un utente
curl -X POST https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/98765/assignee \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"userId": 4521}'
Response
204 No Content — la conversazione è ora di proprietà dell'utente 4521. Una successiva GET /inbox/conversations/98765 mostrerà il nuovo assignedUserId.
Rilascia la conversazione
curl -X DELETE https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/98765/assignee \
-H "X-Api-Key: YOUR_API_KEY"
Response
204 No Content — la conversazione torna senza assegnatario. L'operazione è idempotente: chiamarla su una conversazione già non assegnata restituisce comunque 204.
:::tip Un solo assegnatario alla volta
Ogni conversazione può avere al massimo un assegnatario. Un nuovo POST .../assignee sostituisce la precedente assegnazione senza bisogno di un DELETE esplicito.
:::
Dietro le quinte — Ciclo di vita dell'assegnazione
- Proprietà esclusiva: Solo un membro del team può possedere una conversazione alla volta. Riassegnare sostituisce silenziosamente il proprietario precedente.
- Notifiche: Il nuovo assegnatario riceve una notifica real-time dell'assegnazione e di ogni messaggio in ingresso successivo su quella conversazione.
- Rilascio idempotente:
DELETE .../assigneerestituisce 204 sia che ci fosse un assegnatario precedente sia che non ce ne fosse, quindi la logica di retry è sicura. - Protezione cross-company: Lo
userIdnella richiesta di assegnazione deve appartenere alla tua azienda. Tentativi di assegnare a un utente di un altro account restituiscono 404, non 403, per non rivelare l'esistenza di utenti di altri tenant.
Risultato atteso
| Step | Azione | Risultato |
|---|---|---|
| 1 | GET /inbox/conversations | Lista conversazioni con anteprima e conteggio non lette |
| 2 | GET /inbox/conversations/{chatId}/messages | Storico completo dei messaggi del thread |
| 3 | PATCH /{chatId}/read + PATCH /{chatId}/archive | Conversazione letta e archiviata |
| 4 | POST /{chatId}/assignee + DELETE /{chatId}/assignee | Conversazione assegnata a un collega e poi rilasciata |
Esempio completo end-to-end
Scenario ShopOnline: triage automatico delle conversazioni non lette.
# 1. Recupera conversazioni non lette
echo "=== Conversazioni non lette ==="
CHATS=$(curl -s -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations?status=active&unreadOnly=true" \
-H "X-Api-Key: YOUR_API_KEY")
echo "$CHATS" | jq '.conversations[] | {chatId, channel: .channel, contact: .contact.name, unread: .unreadCount}'
# 2. Leggi i messaggi della prima conversazione
FIRST_CHAT=$(echo "$CHATS" | jq -r '.conversations[0].chatId')
echo "=== Messaggi di $FIRST_CHAT ==="
curl -s -X GET "https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/${FIRST_CHAT}/messages" \
-H "X-Api-Key: YOUR_API_KEY" | jq '.messages[] | {direction, body, timestamp}'
# 3. Marca come letto
curl -s -X PATCH "https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/${FIRST_CHAT}/read" \
-H "X-Api-Key: YOUR_API_KEY" | jq .
Varianti
Ripristinare una conversazione archiviata
Se una conversazione e stata archiviata per errore, ripristinala:
curl -X PATCH https://lora-api.agiletelecom.com/api/partner-gateway/v1/inbox/conversations/chat_abc123/unarchive \
-H "X-Api-Key: YOUR_API_KEY"
Errori comuni
404 Not Found — Conversazione inesistente
{
"status": "fail",
"data": {
"conversation": "Conversation not found: chat_invalid_id"
}
}
Soluzione: Verifica che il chatId sia corretto. Usa GET /inbox/conversations per ottenere la lista degli ID validi.
404 Not Found — Utente non appartenente alla tua azienda
{
"status": "fail",
"data": {
"user": "User 9999 does not belong to your company"
}
}
Soluzione: Lo userId che hai tentato di assegnare non esiste nel tuo team. Chiama GET /inbox/conversations/assignable-users per elencare gli ID validi prima di riprovare.
409 Conflict — Conversazione già archiviata
{
"status": "fail",
"data": {
"conversation": "Conversation is already archived"
}
}
Soluzione: La conversazione e già nell'archivio. Se vuoi ripristinarla, usa l'endpoint unarchive.
Prossimi passi
- UC-009 — Conversazione Bidirezionale: Rispondi ai messaggi ricevuti nell'inbox
- UC-019 — Analizzare Storico Messaggi: Analizza lo storico per report e audit
- UC-008 — Tracking Delivery con Webhook: Configura webhook per notifiche real-time