Webhooks d'événements

Recevez message.status et message.inbound en temps réel, signés HMAC-SHA256. Vérifiez toujours la signature.

Webhooks

Plutôt que de sonder GET /v1/messages/{id}, enregistrez UN endpoint HTTPS et nous y postons les événements en temps réel : mises à jour de statut de vos envois, et messages entrants de vos clients. Nous ne faisons tourner aucun bot sur votre numéro — nous vous relayons l'entrant.

Enregistrer le webhook

POST /v1/console/webhook

Attention — Le secret n'est affiché qu'une fois
À l'enregistrement, le secret de signature est renvoyé une seule fois — stockez-le. Un GET ultérieur renvoie { url, configured } sans jamais le secret ; DELETE désactive le webhook.

Format de livraison

Chaque événement est un POST vers votre URL. La livraison est best-effort (~8 s de timeout, pas de retries automatiques pour l'instant) : répondez 2xx rapidement et faites le gros du travail de façon asynchrone.

En-tête de signature

X-Camairetech-Signature: sha256=<hex hmac-sha256 du corps brut>

Types d'événements

message.status

{
  "event": "message.status",
  "data": {
    "id": "6f1c…",
    "wa_message_id": "wamid…",
    "status": "delivered",
    "recipient_masked": "2376****3456",
    "error": null
  },
  "timestamp": "2026-08-04T09:14:07.123456+00:00"
}

message.inbound

{
  "event": "message.inbound",
  "data": {
    "from": "+237699123456",
    "wa_message_id": "wamid…",
    "type": "text",
    "text": "Bonjour",
    "media_url": null
  },
  "timestamp": "…"
}

type vaut text ou un type média (image, audio, video, document, sticker). media_url est null : nous n'hébergeons pas les médias des numéros API — récupérez-les auprès de Meta avec votre propre jeton si besoin.

Vérifier la signature (toujours)

Recalculez le HMAC sur les octets bruts du corps (avant tout parsing JSON) et comparez à l'en-tête ; rejetez en cas d'écart. Re-sérialiser le corps changerait la signature.

Vérification (Python)

import hmac, hashlib

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header or "")

Vérification (Node.js)

const crypto = require("crypto");
function verify(rawBody, header, secret) {
  const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header || ""));
}