Webhook
I webhook permettono di ricevere notifiche in tempo reale sugli eventi dei tuoi messaggi. UniMsg invierà una richiesta HTTP POST al tuo endpoint ogni volta che si verifica un evento.
Configurazione
Dalla Dashboard
- Accedi alla Dashboard
- Vai su Impostazioni → Webhook
- Inserisci l'URL del tuo endpoint
- Seleziona gli eventi da ricevere
- Copia il Webhook Secret per la verifica
- Clicca su "Salva"
Requisiti Endpoint
- Deve essere raggiungibile pubblicamente (HTTPS consigliato)
- Deve rispondere con status 2xx entro 30 secondi
- Deve accettare richieste POST con Content-Type: application/json
Eventi Disponibili
| Evento | Descrizione |
|---|---|
message.sent |
Messaggio inviato al gateway |
message.delivered |
Messaggio consegnato al destinatario |
message.read |
Messaggio letto (WhatsApp/Telegram) |
message.failed |
Invio fallito |
email.opened |
Email aperta |
email.clicked |
Link email cliccato |
email.bounced |
Email rimbalzata |
email.complained |
Email segnalata come spam |
credits.low |
Saldo crediti basso |
Formato Payload
Ogni webhook contiene:
{
"id": "evt_xxxxxxxxxxxx",
"event": "message.delivered",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"message_id": "msg_xxxxxxxxxxxx",
"channel": "sms",
"to": "+39123456789",
"status": "delivered",
"delivered_at": "2024-01-15T10:30:03Z"
}
}
Esempi per Evento
message.sent
{
"id": "evt_xxxxxxxxxxxx",
"event": "message.sent",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"message_id": "msg_xxxxxxxxxxxx",
"channel": "sms",
"to": "+39123456789",
"status": "sent"
}
}
message.failed
{
"id": "evt_xxxxxxxxxxxx",
"event": "message.failed",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"message_id": "msg_xxxxxxxxxxxx",
"channel": "sms",
"to": "+39123456789",
"status": "failed",
"error_code": "INVALID_PHONE",
"error_message": "Il numero non è valido"
}
}
email.clicked
{
"id": "evt_xxxxxxxxxxxx",
"event": "email.clicked",
"created_at": "2024-01-15T10:35:00Z",
"data": {
"message_id": "msg_email_xxxxxxxxxxxx",
"to": "test@example.com",
"url": "https://mysite.com/promo",
"ip": "93.xxx.xxx.xxx",
"user_agent": "Mozilla/5.0..."
}
}
Verifica Signature
Ogni webhook include una firma HMAC-SHA256 nell'header X-UniMsg-Signature per verificare l'autenticità della richiesta.
Come Verificare
- Estrai l'header
X-UniMsg-Signature - Calcola l'HMAC-SHA256 del body usando il tuo Webhook Secret
- Confronta le due firme
Esempio PHP
<?php
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_UNIMSG_SIGNATURE'];
$secret = 'your_webhook_secret';
$expectedSignature = hash_hmac('sha256', $payload, $secret);
if (hash_equals($expectedSignature, $signature)) {
// Webhook valido
$event = json_decode($payload, true);
switch ($event['event']) {
case 'message.delivered':
// Gestisci consegna
break;
case 'message.failed':
// Gestisci errore
break;
}
http_response_code(200);
} else {
// Firma non valida
http_response_code(401);
}
Esempio Node.js
const crypto = require('crypto');
const express = require('express');
const app = express();
app.use(express.json({
verify: (req, res, buf) => {
req.rawBody = buf.toString();
}
}));
app.post('/webhook', (req, res) => {
const signature = req.headers['x-unimsg-signature'];
const secret = 'your_webhook_secret';
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(req.rawBody)
.digest('hex');
if (crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
)) {
const event = req.body;
console.log('Evento:', event.event);
res.status(200).send('OK');
} else {
res.status(401).send('Invalid signature');
}
});
Esempio Python
import hmac
import hashlib
from flask import Flask, request
app = Flask(__name__)
WEBHOOK_SECRET = 'your_webhook_secret'
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-UniMsg-Signature')
payload = request.get_data()
expected = hmac.new(
WEBHOOK_SECRET.encode(),
payload,
hashlib.sha256
).hexdigest()
if hmac.compare_digest(signature, expected):
event = request.json
print(f"Evento: {event['event']}")
return 'OK', 200
else:
return 'Invalid signature', 401
Retry e Gestione Errori
Se il tuo endpoint non risponde con 2xx, UniMsg ritenterà l'invio:
| Tentativo | Ritardo |
|---|---|
| 1 | Immediato |
| 2 | 1 minuto |
| 3 | 5 minuti |
| 4 | 30 minuti |
| 5 | 2 ore |
Dopo 5 tentativi falliti, il webhook viene segnato come fallito e visibile in dashboard.
Debug Webhook
Dalla dashboard puoi:
- Vedere lo storico degli webhook inviati
- Verificare payload e risposta
- Ritentare manualmente un webhook fallito
- Inviare un webhook di test
Suggerimento: Per testare in locale, puoi usare servizi come ngrok o webhook.site.
Best Practices
- Rispondi velocemente - Rispondi con 200 OK subito, elabora in background
- Gestisci i duplicati - Usa l'ID evento per deduplicazione
- Verifica sempre la firma - Non processare webhook non verificati
- Logga tutto - Tieni traccia dei webhook per debug
- Usa HTTPS - Proteggi i dati in transito