Passa al contenuto principale

UC-018 — Gestire l'Inbox

CampoValore
IDUC-018
ObiettivoGestire conversazioni in ingresso: triage, lettura, archiviazione
CanaleTutti (SMS, RCS, WhatsApp, Messenger)
ComplessitàIntermedia
Tempo stimato15 minuti
API coinvolteGET /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
  1. Aggregazione: L'inbox aggrega messaggi provenienti da tutti i canali attivi (SMS, RCS, WhatsApp, Messenger) in un'unica vista unificata.
  2. 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.
  3. Ordinamento: Le conversazioni sono ordinate per timestamp dell'ultimo messaggio (più recente prima).
  4. Paginazione: L'endpoint supporta limit e offset per la paginazione. Il campo hasMore indica 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
  1. Archiviazione: La conversazione viene spostata nell'archivio e non compare più nella lista attiva. I messaggi restano accessibili.
  2. Ripristino: Usa PATCH /conversations/{chatId}/unarchive per riportare una conversazione nell'inbox attiva.
  3. Nuovo messaggio: Se un contatto con conversazione archiviata invia un nuovo messaggio, la conversazione viene automaticamente ripristinata nell'inbox attiva.
  4. 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
  1. Proprietà esclusiva: Solo un membro del team può possedere una conversazione alla volta. Riassegnare sostituisce silenziosamente il proprietario precedente.
  2. Notifiche: Il nuovo assegnatario riceve una notifica real-time dell'assegnazione e di ogni messaggio in ingresso successivo su quella conversazione.
  3. Rilascio idempotente: DELETE .../assignee restituisce 204 sia che ci fosse un assegnatario precedente sia che non ce ne fosse, quindi la logica di retry è sicura.
  4. Protezione cross-company: Lo userId nella 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

StepAzioneRisultato
1GET /inbox/conversationsLista conversazioni con anteprima e conteggio non lette
2GET /inbox/conversations/{chatId}/messagesStorico completo dei messaggi del thread
3PATCH /{chatId}/read + PATCH /{chatId}/archiveConversazione letta e archiviata
4POST /{chatId}/assignee + DELETE /{chatId}/assigneeConversazione 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

Riferimenti