Passer au contenu principal

Webhooks

Les webhooks vous permettent de recevoir des callbacks HTTP en temps reel lorsque des evenements se produisent sur vos instances WhatsApp. Au lieu d’interroger l’API, Wappfy pousse les evenements vers votre serveur au fur et a mesure qu’ils surviennent.

Evenements pris en charge

Wappfy prend en charge 12 types d’evenements webhook :
EvenementDescription
message.receivedUn nouveau message entrant a ete recu.
message.sentUn message sortant a ete envoye avec succes.
message.deliveredUn message envoye a ete livre sur l’appareil du destinataire (double coche).
message.readUn message envoye a ete lu par le destinataire (coches bleues).
message.failedL’envoi d’un message sortant a echoue.
message.reactionQuelqu’un a reagi a un message avec un emoji.
EvenementDescription
instance.connectedUne instance s’est connectee a WhatsApp avec succes.
instance.disconnectedUne instance a perdu sa connexion WhatsApp.
instance.qrUn nouveau QR code est disponible pour le scan.
EvenementDescription
group.joinedUn participant a rejoint un groupe (y compris le bot lui-meme).
group.leftUn participant a quitte un groupe.
contact.createdUn nouveau contact a ete enregistre ou detecte.

Creer un webhook

Enregistrez un endpoint webhook pour commencer a recevoir des evenements.
curl -X POST https://api.wappfy.io/api/webhooks \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhooks/wappfy",
    "events": ["message.received", "message.sent", "message.delivered"],
    "instance_id": "inst_abc123",
    "secret": "whsec_my_signing_secret",
    "retry_count": 3,
    "timeout_ms": 10000
  }'
Reponse :
{
  "data": {
    "id": "wh_xyz789",
    "url": "https://your-server.com/webhooks/wappfy",
    "events": ["message.received", "message.sent", "message.delivered"],
    "instance_id": "inst_abc123",
    "is_active": true,
    "retry_count": 3,
    "timeout_ms": 10000,
    "created_at": "2026-02-10T12:00:00Z"
  }
}

Options de configuration

ChampTypeDefautDescription
urlstringobligatoireL’URL HTTPS qui recevra les requetes POST du webhook.
eventsstring[]obligatoireTableau des types d’evenements auxquels s’abonner.
instance_idstringnullLimiter le webhook a une instance specifique. Si null, recoit les evenements de toutes les instances.
secretstringnullSecret utilise pour generer des signatures HMAC pour la verification du contenu.
retry_countnumber3Nombre de tentatives de reessai en cas d’echec de livraison (0-5).
timeout_msnumber10000Delai d’expiration de la requete en millisecondes (1000-30000).
Le champ instance_id est optionnel. S’il est omis, le webhook recevra les evenements de toutes les instances de votre compte.

Lister les webhooks

curl https://api.wappfy.io/api/webhooks \
  -H "X-Api-Key: YOUR_API_KEY"
Reponse :
{
  "data": [
    {
      "id": "wh_xyz789",
      "url": "https://your-server.com/webhooks/wappfy",
      "events": ["message.received", "message.sent", "message.delivered"],
      "instance_id": "inst_abc123",
      "is_active": true,
      "retry_count": 3,
      "timeout_ms": 10000
    }
  ]
}

Mettre a jour un webhook

Mettez a jour l’URL, les evenements ou la configuration d’un webhook existant.
curl -X PATCH https://api.wappfy.io/api/webhooks/wh_xyz789 \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["message.received", "message.sent", "message.delivered", "message.read"],
    "is_active": true
  }'

Supprimer un webhook

curl -X DELETE https://api.wappfy.io/api/webhooks/wh_xyz789 \
  -H "X-Api-Key: YOUR_API_KEY"

Format du contenu de livraison

Lorsqu’un evenement se produit, Wappfy envoie une requete POST a votre URL webhook avec la structure suivante :
{
  "id": "dlv_abc123def456",
  "event": "message.received",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T14:30:00Z",
  "data": {
    "message_id": "BAE5F2C4D3B2A1",
    "chat_id": "[email protected]",
    "from": "[email protected]",
    "type": "text",
    "text": "Hello!",
    "timestamp": "2026-02-10T14:30:00Z"
  }
}

Champs du contenu

ChampDescription
idIdentifiant unique de la livraison. Utilisez-le pour la deduplication.
eventLe type d’evenement qui a declenche cette livraison.
instance_idL’instance qui a genere l’evenement.
timestampHorodatage ISO 8601 du moment ou l’evenement s’est produit.
dataContenu specifique a l’evenement. Le contenu varie selon le type d’evenement.

Verification de la signature HMAC

Si vous fournissez un secret lors de la creation d’un webhook, chaque livraison inclura un en-tete X-Wappfy-Signature contenant une signature HMAC-SHA256 du corps de la requete. Verifiez toujours cette signature pour vous assurer que la requete provient de Wappfy et n’a pas ete alteree.

Exemples de verification

const crypto = require("crypto");

function verifyWebhookSignature(req, secret) {
  const signature = req.headers["x-wappfy-signature"];
  if (!signature) return false;

  const expectedSignature = crypto
    .createHmac("sha256", secret)
    .update(JSON.stringify(req.body))
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Express middleware
app.post("/webhooks/wappfy", (req, res) => {
  const isValid = verifyWebhookSignature(req, "whsec_my_signing_secret");

  if (!isValid) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  const { event, data } = req.body;
  console.log(`Received event: ${event}`, data);

  // Always respond with 200 quickly to prevent retries
  res.status(200).json({ received: true });
});
Utilisez toujours une comparaison a temps constant (comme timingSafeEqual ou hmac.compare_digest) lors de la verification des signatures pour prevenir les attaques par timing.

Comportement de reessai

Si votre serveur ne repond pas avec un code de statut 2xx dans le delai configure timeout_ms, Wappfy reessaiera la livraison.
TentativeDelai
1er reessai10 secondes
2e reessai60 secondes
3e reessai5 minutes
4e reessai30 minutes
5e reessai2 heures
Les reessais s’arretent lorsqu’une reponse 2xx est recue ou que le retry_count est epuise. Le nombre de reessais par defaut est de 3.

Consulter l’historique de livraison

Consultez le journal de livraison d’un webhook pour voir les tentatives de livraison passees et leurs resultats.
curl https://api.wappfy.io/api/webhooks/wh_xyz789/deliveries \
  -H "X-Api-Key: YOUR_API_KEY"
Reponse :
{
  "data": [
    {
      "id": "dlv_abc123def456",
      "event": "message.received",
      "status": "delivered",
      "http_status": 200,
      "attempts": 1,
      "created_at": "2026-02-10T14:30:00Z",
      "delivered_at": "2026-02-10T14:30:01Z"
    },
    {
      "id": "dlv_ghi789jkl012",
      "event": "message.sent",
      "status": "failed",
      "http_status": 500,
      "attempts": 3,
      "created_at": "2026-02-10T14:31:00Z",
      "last_error": "Server returned 500 Internal Server Error"
    }
  ]
}

Exemples de contenu par evenement

{
  "id": "dlv_abc123",
  "event": "message.received",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T14:30:00Z",
  "data": {
    "message_id": "BAE5F2C4D3B2A1",
    "chat_id": "[email protected]",
    "from": "[email protected]",
    "type": "text",
    "text": "Hello, I need help with my order",
    "timestamp": "2026-02-10T14:30:00Z"
  }
}
{
  "id": "dlv_def456",
  "event": "message.delivered",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T14:30:05Z",
  "data": {
    "message_id": "BAE5A1B2C3D4E5",
    "chat_id": "[email protected]",
    "status": "delivered"
  }
}
{
  "id": "dlv_ghi789",
  "event": "message.read",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T14:31:00Z",
  "data": {
    "message_id": "BAE5A1B2C3D4E5",
    "chat_id": "[email protected]",
    "status": "read"
  }
}
{
  "id": "dlv_jkl012",
  "event": "message.reaction",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T14:32:00Z",
  "data": {
    "message_id": "BAE5F2C4D3B2A1",
    "chat_id": "[email protected]",
    "from": "[email protected]",
    "reaction": "\u2764\ufe0f"
  }
}
{
  "id": "dlv_mno345",
  "event": "instance.connected",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T12:00:00Z",
  "data": {
    "instance_id": "inst_abc123",
    "status": "connected",
    "phone_number": "5511999998888"
  }
}
{
  "id": "dlv_pqr678",
  "event": "instance.qr",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T11:59:00Z",
  "data": {
    "instance_id": "inst_abc123",
    "qr": "data:image/png;base64,iVBORw0KGgo..."
  }
}
{
  "id": "dlv_stu901",
  "event": "group.joined",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T15:00:00Z",
  "data": {
    "group_id": "[email protected]",
    "participant": "[email protected]"
  }
}

Bonnes pratiques

Repondez rapidement

Retournez un statut 200 dans les 5 secondes. Traitez l’evenement de maniere asynchrone pour eviter les depassements de delai.

Dedupliquez

Utilisez l’id de livraison pour detecter et ignorer les livraisons en double causees par les reessais.

Verifiez les signatures

Validez toujours l’en-tete X-Wappfy-Signature si vous avez configure un secret.

Utilisez HTTPS

Les URL de webhook doivent utiliser HTTPS. Les endpoints HTTP seront rejetes.