Passa al contenuto principale

UC-029 — Report Campagna Completo

CampoValore
IDUC-029
ObiettivoCreare una campagna, monitorarne le statistiche e scaricare il report completo in CSV
CanaleSMS (applicabile a tutti i canali)
Complessità⭐⭐⭐ Avanzato
Tempo stimato25 minuti
API coinvoltePOST /api/partner-gateway/v1/campaigns, POST /api/partner-gateway/v1/campaigns/{id}/calculateGoal, PUT /api/partner-gateway/v1/campaigns/{id}/confirm, GET /api/partner-gateway/v1/campaigns/{id}, POST /api/partner-gateway/v1/exports/delivery-reports, GET /api/partner-gateway/v1/exports, GET /api/partner-gateway/v1/exports/{exportId}

Scenari reali​

  • FashionOutlet — Analisi ROI Black Friday: Dopo la campagna Black Friday, il team marketing vuole un report dettagliato con tassi di consegna per operatore, costi totali e confronto con l'anno precedente.
  • TelcoMobile — Report settimanale per il management: Ogni lunedi, il responsabile comunicazione genera un report aggregato delle campagne della settimana per la direzione.
  • BancaAdriatica — Audit consegne cliente enterprise: Il team compliance deve documentare il tasso di consegna delle notifiche transazionali per un audit interno trimestrale.
Use case composito

Questo UC combina i flussi di UC-006 — Campagna Bulk SMS e UC-011 — Export Delivery Reports in un workflow end-to-end completo.

Flusso completo​

Il diagramma illustra il workflow completo: dalla creazione della campagna al download del report CSV per l'analisi.

Step 1 — Crea la campagna​

Crea una nuova campagna SMS indirizzata a una lista di contatti (destinationType: 0). Con readyToSend: true la configurazione è definitiva e la campagna può essere confermata:

curl -X POST "https://api.qlara.ai/api/partner-gateway/v1/campaigns" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Black Friday 2026 - SMS Promo",
"sendingMode": "SMS",
"destinationType": 0,
"contactListIds": [3415],
"smsSender": "FashionOut",
"smsBody": "Ciao {firstName}! Black Friday FashionOutlet: -50% su tutto solo oggi! Usa il codice BF2026 su https://fashionoutlet.it/bf Rispondi STOP per opt-out.",
"scheduledDate": "2026-11-27 09:00:00.000+0100",
"readyToSend": true
}'

Response — Campagna creata​

{
"id": 4512,
"name": "Black Friday 2026 - SMS Promo",
"status": "READY_TO_SEND",
"sendingMode": "SMS",
"smsSender": "FashionOut",
"destinationType": 0,
"contactListIds": [3415],
"scheduledDate": "2026-11-27 08:00:00.000+0000",
"readyToSend": true
}
Salva l'ID campagna

Il campo id della campagna e necessario per tutti gli step successivi: conferma, monitoraggio e collegamento al report.

Step 2 — Conferma l'invio della campagna​

Nulla viene inviato finché la campagna non è confermata. Ricalcola prima il costo, poi conferma:

curl -X POST "https://api.qlara.ai/api/partner-gateway/v1/campaigns/4512/calculateGoal" \
-H "X-Api-Key: YOUR_API_KEY"

curl -X PUT "https://api.qlara.ai/api/partner-gateway/v1/campaigns/4512/confirm" \
-H "X-Api-Key: YOUR_API_KEY"

Response — Campagna confermata​

202 Accepted, senza body: la campagna è in coda e viene inviata alla sua scheduledDate.

Dietro le quinte — Cosa succede dopo la conferma
  1. Validazione: Il sistema verifica lista contatti, mittente e credito.
  2. Scheduling: Se la scheduledDate e futura, la campagna resta in coda.
  3. Throttling: L'invio avviene in batch (15.000 SMS in ~30-45 minuti).
  4. Credito: Addebitato all'invio effettivo, non alla conferma.

Step 3 — Monitora le statistiche della campagna​

Durante e dopo l'invio, controlla i contatori di delivery della campagna:

curl -X GET "https://api.qlara.ai/api/partner-gateway/v1/campaigns/4512" \
-H "X-Api-Key: YOUR_API_KEY"

Response — Statistiche campagna completata​

{
"id": 4512,
"name": "Black Friday 2026 - SMS Promo",
"status": "ENDED",
"sendingMode": "SMS",
"startDate": "2026-11-27 08:00:02.000+0000",
"endDate": "2026-11-27 08:38:22.000+0000",
"totalDestinations": 15420,
"totalPrice": 53970000000,
"totalSent": 15420,
"totalSuccess": 14650,
"totalFailed": 458,
"smsSent": 15420,
"smsPending": 312,
"smsSuccess": 14650,
"smsFailed": 458
}

14.650 messaggi consegnati su 15.420 corrispondono a un tasso di consegna del 95,01%.

Polling delle statistiche

I contatori si aggiornano durante l'invio. Puoi interrogare l'endpoint ogni 30-60 secondi per monitorare il progresso. Lo status diventa ENDED quando l'invio è terminato; le ricevute di consegna ancora in arrivo restano contate in smsPending finché non arrivano. GET /campaigns/stats restituisce contatori simili per tutte le tue campagne insieme, aggregati per intervallo di tempo (hour, day, week, month) e modalità di invio: usalo per gli andamenti, non per una singola campagna.

Step 4 — Esporta il delivery report​

Richiedi l'export CSV con il dettaglio di ogni singolo messaggio. Passa solo il campaignId: è un'alternativa all'intervallo di date, e l'export copre tutti i canali della campagna:

curl -X POST "https://api.qlara.ai/api/partner-gateway/v1/exports/delivery-reports" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"campaignId": 4512,
"exportFormat": "CSV"
}'

Response — Export in coda​

202 Accepted, senza body: il job di export è in coda. La risposta non contiene l'ID dell'export: lo trovi nella lista dello Step 5.

Step 5 — Scarica il CSV​

Interroga la lista degli export con GET /exports finché l'export della tua campagna (detail.campaignId) non mostra isAvailableForDownload: true:

curl -X GET "https://api.qlara.ai/api/partner-gateway/v1/exports?page=0&limit=10" \
-H "X-Api-Key: YOUR_API_KEY"
{
"data": [
{
"id": 57,
"type": "DELIVERY_REPORT",
"detail": {
"type": "DELIVERY_REPORT",
"campaignId": 4512,
"exportFormat": "CSV"
},
"status": "COMPLETED",
"createdAt": "2026-11-28 09:00:00.000+0000",
"expiresAt": "2026-12-05 09:00:00.000+0000",
"isAvailableForDownload": true
}
],
"page": 0,
"limit": 10,
"totalCount": 1,
"totalPages": 1
}

Poi ottieni l'URL di download di quell'export con GET /exports/{exportId}:

curl -X GET "https://api.qlara.ai/api/partner-gateway/v1/exports/57" \
-H "X-Api-Key: YOUR_API_KEY"
{
"url": "https://storage.example.com/exports/57.csv?token=f3a9c1d27b&expires=1796461200"
}
curl -o "report_blackfriday_2026.csv" \
"https://storage.example.com/exports/57.csv?token=f3a9c1d27b&expires=1796461200"
Dietro le quinte — Struttura del CSV

Il CSV contiene una riga per messaggio (una per parte per gli SMS concatenati) con colonne come DateTime, Originator, Destination, Sent type (SMS, RCS o WHATSAPP), Delivery result, SMS cost, Customer ID, Part number e Total parts. L'export asincrono e necessario per dataset di grandi dimensioni.

Risultato atteso​

StepAzioneRisultato
1POST /campaignsCampagna creata, status: "READY_TO_SEND"
2POST /campaigns/{id}/calculateGoal + PUT /campaigns/{id}/confirm202 Accepted, invio schedulato
3GET /campaigns/{id}status: "ENDED", totalSuccess: 14650 su 15.420 (95,01%)
4POST /exports/delivery-reports202 Accepted, export in coda
5GET /exports + GET /exports/{exportId}url di download del CSV con dettaglio 15.420 messaggi

Esempio completo end-to-end​

#!/bin/bash
API_KEY="YOUR_API_KEY"
BASE_URL="https://api.qlara.ai/api/partner-gateway/v1"

# 1. Crea e conferma campagna
CMP_ID=$(curl -s -X POST "${BASE_URL}/campaigns" \
-H "X-Api-Key: ${API_KEY}" -H "Content-Type: application/json" \
-d '{"name":"Black Friday 2026","sendingMode":"SMS","destinationType":0,"contactListIds":[3415],"smsSender":"FashionOut","smsBody":"Ciao {firstName}! -50% su tutto! Codice BF2026","readyToSend":true}' | jq -r '.id')

curl -s -X POST "${BASE_URL}/campaigns/${CMP_ID}/calculateGoal" -H "X-Api-Key: ${API_KEY}" > /dev/null
curl -s -X PUT "${BASE_URL}/campaigns/${CMP_ID}/confirm" -H "X-Api-Key: ${API_KEY}" > /dev/null

# 2. Monitora fino al completamento
while true; do
CMP_STATUS=$(curl -s -X GET "${BASE_URL}/campaigns/${CMP_ID}" \
-H "X-Api-Key: ${API_KEY}" | jq -r '.status')
echo "Stato: ${CMP_STATUS}"
[[ "$CMP_STATUS" == "ENDED" || "$CMP_STATUS" == "ARCHIVED" ]] && break
sleep 60
done

# 3. Esporta, attendi il file e scaricalo
curl -s -X POST "${BASE_URL}/exports/delivery-reports" \
-H "X-Api-Key: ${API_KEY}" -H "Content-Type: application/json" \
-d '{"campaignId":'"${CMP_ID}"',"exportFormat":"CSV"}'

EXP_ID=""
while [[ -z "$EXP_ID" ]]; do
sleep 10
EXP_ID=$(curl -s -X GET "${BASE_URL}/exports?page=0&limit=10" -H "X-Api-Key: ${API_KEY}" \
| jq -r --argjson c "$CMP_ID" '[.data[] | select(.detail.campaignId == $c and .isAvailableForDownload)][0].id // empty')
done
DL_URL=$(curl -s -X GET "${BASE_URL}/exports/${EXP_ID}" -H "X-Api-Key: ${API_KEY}" | jq -r '.url')
curl -o "report_blackfriday_2026.csv" "$DL_URL"

Varianti​

Report multi-canale​

La richiesta di export non ha un filtro per canale: l'export di una campagna multi-canale (per esempio sendingMode: "WHATSAPP_SMS") include SMS, RCS e WhatsApp nello stesso CSV, distinti dalla colonna Sent type.

Report aggregato per periodo​

Per un report settimanale che include tutte le campagne, ometti campaignId e specifica invece startDateTime/endDateTime (formato yyyy-MM-dd HH:mm:ss.SSSZ, per esempio 2026-11-23 00:00:00.000+0100).

Errori comuni​

404 Not Found — Campagna non esistente​

{ "status": "fail", "data": { "error": "Campaign not found" } }

Soluzione: Verifica l'ID campagna. Usa GET /campaigns per elencare le campagne disponibili.

400 Bad Request — Campagna e intervallo di date insieme​

{ "status": "fail", "data": { "error": "Provide either campaignId or startDateTime/endDateTime, not both" } }

Soluzione: campaignId e l'intervallo di date si escludono a vicenda: passa campaignId per una singola campagna, startDateTime/endDateTime per un periodo.

Prossimi passi​

Riferimenti​