Webhooks
Obtenir une clé APIEnregistrer un webhook
Enregistrez une adresse https publique et les événements souhaités. Le secret de signature (whsec_…) n’est affiché que dans cette réponse. Une application peut avoir jusqu’à 10 webhooks.
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"]}'Événements
| Événement | data |
|---|---|
post.published | postId, establishmentId, platform, publishedAt, permalink |
post.failed | postId, establishmentId, platform, error |
webhook.test | webhookId |
Sofia envoie chaque événement en POST au format JSON { id, type, createdAt, data }, avec les en-têtes Sofia-Event-Id, Sofia-Event-Type et Sofia-Signature. Seules les publications créées par votre application sont annoncées.
Vérifier la signature
Sofia-Signature vaut t=<unix time>,v1=<hex>, où v1 est le HMAC-SHA256 de <t>.<raw body> avec votre secret. Vérifiez-la sur le corps brut, et refusez un horodatage ancien :
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);
};Livraison et nouvelles tentatives
- Une réponse
2xxlivre l’événement. Toute autre réponse, une redirection (jamais suivie) ou 10 secondes sans réponse déclenchent une nouvelle tentative après 1 minute, 5 minutes, 30 minutes et 2 heures, jusqu’à 5 tentatives. - Un même événement peut arriver deux fois : dédupliquez sur
Sofia-Event-Id. - Répondez vite et traitez l’événement ensuite.
POST /v1/webhooks/{id}/test envoie un événement webhook.test, signé comme les autres.