Webhook
Ottieni una chiave APIRegistrare un webhook
Registra un indirizzo https pubblico e gli eventi che vuoi. Il signing secret (whsec_…) viene mostrato solo in questa risposta. Un'applicazione può avere fino a 10 webhook.
curl -X POST https://api.sofia-post.com/api/v1/webhooks \
-H "Authorization: Bearer $SOFIA_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"url":"https://app.example.com/hooks/sofia","events":["post.published","post.failed"]}'Eventi
| Evento | data |
|---|---|
post.published | postId, establishmentId, platform, publishedAt, permalink |
post.failed | postId, establishmentId, platform, error |
webhook.test | webhookId |
Sofia invia ogni evento con una POST come JSON { id, type, createdAt, data }, con gli header Sofia-Event-Id, Sofia-Event-Type e Sofia-Signature. Vengono notificate solo le pubblicazioni create dalla tua applicazione.
Verificare la firma
Sofia-Signature è t=<unix time>,v1=<hex>, dove v1 è l'HMAC-SHA256 di <t>.<raw body> con il tuo secret. Verificala sul body grezzo e rifiuta un timestamp vecchio:
import { createHmac, timingSafeEqual } from 'node:crypto';
const isSignedBySofia = (header, rawBody, secret) => {
const parts = Object.fromEntries(
(header ?? '').split(',').map((part) => part.trim().split('=', 2)),
);
const timestamp = Number(parts.t);
if (!Number.isInteger(timestamp) || typeof parts.v1 !== 'string') return false;
if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest();
const received = Buffer.from(parts.v1, 'hex');
return received.length === expected.length && timingSafeEqual(received, expected);
};Consegna e nuovi tentativi
- Una risposta
2xxconsegna l'evento. Qualsiasi altra risposta, un reindirizzamento (mai seguito) o 10 secondi senza risposta lo riprovano dopo 1 minuto, 5 minuti, 30 minuti e 2 ore, fino a 5 tentativi. - Lo stesso evento può arrivare due volte: deduplica su
Sofia-Event-Id. - Rispondi in fretta ed elabora l'evento dopo.
POST /v1/webhooks/{id}/test invia un evento webhook.test, firmato come gli altri.