Passa al contenuto principale

Webhook

Ricevi notifiche in tempo reale quando lo stato del messaggio cambia. I webhook sono più veloci e affidabili del polling.

Webhook vs Polling

MetodoVelocitàAffidabilitàCaso d'Uso
WebhookIstantaneoAlto (il tuo endpoint riceve eventi)Sistemi in produzione, elaborazione in tempo reale
PollingRitardato (verifica ogni N secondi)Dipende dalla frequenzaIntegrazioni a basso volume, semplici

Consiglio: Usa webhook per la produzione.

Configurazione Webhook

Registra un Endpoint Webhook

Puoi gestire i webhook tramite l'API o la dashboard.

Endpoint API: POST /webhooks/delivery-status

Registra il tuo webhook:

curl -X POST https://lora-api.agiletelecom.com/api/webhooks/delivery-status \
-H "X-Api-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-domain.com/webhook",
"method": "POST"
}'

Limitazione Importante

Un webhook attivo per account. Se registri un nuovo webhook, il precedente è sostituito.

Payload Webhook

Quando lo stato di un messaggio cambia, Qlara invia una richiesta POST al tuo endpoint:

{
"messageId": "msg_1234567890",
"customerMessageId": "your_reference_id",
"phoneNumber": "+393901234567",
"status": "DELIVERED",
"timestamp": "2025-04-08T14:30:00Z",
"channel": "sms",
"error": null
}

Campi del Payload

CampoTipoDescrizione
messageIdstringID messaggio Qlara univoco
customerMessageIdstringIl tuo ID di riferimento (se fornito)
phoneNumberstringNumero di telefono del destinatario
statusstringStato del messaggio (vedi sotto)
timestampISO 8601Quando lo stato è cambiato
channelstringCanale utilizzato (sms, rcs, whatsapp)
errorstring o nullMessaggio di errore se lo stato è ERROR

Valori di Stato

StatoSignificato
SENTIl messaggio ha lasciato i nostri server ed è in elaborazione
DELIVEREDConsegnato con successo al destinatario
ERRORLa consegna è fallita (vedi campo di errore)
EXPIREDIl messaggio non è stato consegnato entro il periodo di conservazione

Implementare un Ricevitore Webhook

Il tuo endpoint deve:

  1. Ascoltare richieste POST
  2. Restituire HTTP 200 entro 5 secondi
  3. Elaborare il payload in modo asincrono (non bloccare la risposta)
  4. Essere idempotente (gestire gli eventi duplicati correttamente)
  5. Validare che la richiesta provenga da Qlara

Esempio di Ricevitore Webhook

from flask import Flask, request, jsonify
import json

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
# Restituisci 200 immediatamente
payload = request.get_json()

# Elabora in modo asincrono (metti in coda a un worker in background)
process_delivery_event.delay(payload)

return jsonify({"status": "received"}), 200

def process_delivery_event(payload):
"""Elabora il payload webhook in modo asincrono"""
message_id = payload.get('messageId')
status = payload.get('status')
phone = payload.get('phoneNumber')

# Aggiorna il tuo database
Message.objects(messageId=message_id).update(
status=status,
delivered_at=payload.get('timestamp')
)

# Attiva azioni downstream
if status == 'DELIVERED':
send_confirmation_email(phone)
elif status == 'ERROR':
log_delivery_error(message_id, payload.get('error'))

if __name__ == '__main__':
app.run(port=5000)

Requisiti del Ricevitore Webhook

HTTPS Richiesto

L'URL del tuo webhook deve utilizzare HTTPS. HTTP non crittografato non è supportato.

Risposta Veloce

Restituisci HTTP 200 entro 5 secondi. Non elaborare il payload del webhook prima di rispondere.

# BENE: Restituisci immediatamente, elabora dopo
@app.route('/webhook', methods=['POST'])
def webhook():
queue.enqueue(process_event, request.get_json())
return jsonify({"status": "received"}), 200

# MALE: Blocca prima di restituire
@app.route('/webhook', methods=['POST'])
def webhook():
process_event(request.get_json()) # Impiega 10 secondi
return jsonify({"status": "processed"}), 200

Idempotenza

Elabora gli eventi in modo idempotente. Potresti ricevere lo stesso evento due volte. Usa il messageId per deduplicare:

def process_delivery_event(payload):
message_id = payload['messageId']

# Controlla se già elaborato
if Message.objects(messageId=message_id).first():
return # Salta il duplicato

# Elabora l'evento
Message.create(messageId=message_id, status=payload['status'])

Alternativa di Polling

Se non puoi usare i webhook, fai polling dell'endpoint di stato:

Endpoint: GET /messages/status/{customerMessageId}

curl -X GET https://lora-api.agiletelecom.com/api/messages/status/your_reference_id \
-H "X-Api-Key: your_api_key_here"

Best Practice

  1. Usa webhook in produzione — Più veloci e affidabili del polling
  2. Restituisci 200 immediatamente — Non bloccare la risposta del webhook
  3. Elabora in modo asincrono — Usa una job queue (Celery, Bull, RQ, ecc.)
  4. Gestisci i duplicati — Implementa l'elaborazione idempotente
  5. Usa HTTPS — I webhook devono essere crittografati
  6. Registra tutti gli eventi — Mantieni un audit trail dello stato di consegna
  7. Monitora la salute dei webhook — Avvisa se l'URL del webhook è irraggiungibile
  8. Valida le richieste — (Future: firme webhook in arrivo)

Risoluzione dei Problemi

Il webhook non viene chiamato?

  • Verifica che l'endpoint sia accessibile da internet
  • Controlla la validità del certificato HTTPS
  • Assicurati che il firewall consenta richieste dagli IP Qlara
  • Controlla i log dell'applicazione per errori

Ricevi eventi duplicati?

  • Implementa l'elaborazione idempotente con deduplicazione di messageId
  • Usa vincoli di unicità del database come rete di sicurezza

Il webhook restituisce errori?

  • Restituisci HTTP 200 per tutti i payload validi
  • Registra gli errori e ri-lancia all'interno di job asincroni, non nel handler del webhook
  • Verifica che l'endpoint restituisca entro 5 secondi

Hai bisogno di aiuto? Contatta support@agiletelecom.com.