> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bodyguard.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Démarrage rapide des webhooks

> Créez un endpoint webhook et vérifiez chaque requête Bodyguard avec une bibliothèque Standard Webhooks.

Bodyguard signe chaque requête webhook, afin que vous puissiez vérifier qu'elle provient de Bodyguard et que personne ne l'a altérée. Les signatures suivent la spécification [Standard Webhooks](https://www.standardwebhooks.com) : vous les vérifiez avec les bibliothèques open source officielles, sans écrire vous-même la cryptographie.

## Prérequis

* Le secret de signature de votre webhook. Il commence par `whsec_`. Voir [Configuration](https://docs.bodyguard.ai/fr/api-reference/webhooks/configuration.md#secret-de-signature).
* Un serveur capable d'exposer un endpoint HTTPS public.
  * L'endpoint doit établir une négociation TLS valide, avec un certificat émis par une autorité de certification reconnue. Les certificats auto-signés ne sont pas acceptés.
  * L'endpoint doit répondre sous 10 secondes. Sinon, la livraison est considérée comme un échec.

## Fonctionnement de la signature

Bodyguard signe chaque requête comme décrit dans la section [Verifying webhook authenticity](https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md#verifying-webhook-authenticity) de la spécification Standard Webhooks. Bodyguard utilise le schéma de signature symétrique : `HMAC-SHA256` avec votre secret de signature `whsec_`, et l'identifiant de signature `v1`.

## Créer votre endpoint

Installez la bibliothèque correspondant à votre langage :

```bash JavaScript theme={null}
npm install standardwebhooks express
```

```bash Python theme={null}
pip install standardwebhooks flask
```

```bash Go theme={null}
go get github.com/standard-webhooks/standard-webhooks/libraries/go
```

Créez ensuite un endpoint qui accepte les requêtes `POST` et vérifie chacune d'elles. Transmettez le secret de signature dans la variable d'environnement `BODYGUARD_WEBHOOK_SECRET`. Pour le contenu de `event.data`, consultez [Payloads › Types d'événements](https://docs.bodyguard.ai/fr/api-reference/reference/webhooks/payloads.md#types-d’événements).

```javascript JavaScript theme={null}
const express = require("express");
const { Webhook } = require("standardwebhooks");

const wh = new Webhook(process.env.BODYGUARD_WEBHOOK_SECRET); // "whsec_..."
const app = express();

// Conservez le corps brut : la signature couvre les octets exacts envoyés par Bodyguard.
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
  let event;
  try {
    event = wh.verify(req.body, req.headers);
  } catch (err) {
    return res.status(400).send("Invalid signature");
  }

  switch (event.type) {
    case "message.updated":
      console.log("Message updated:", event.data.id, event.data);
      break;
    case "author.updated":
      console.log("Author updated:", event.data.id, event.data);
      break;
  }

  // Toute réponse 2xx acquitte la livraison.
  res.sendStatus(200);
});

app.listen(8080, () => console.log("Listening on port 8080"));
```

```python Python theme={null}
import os

from flask import Flask, request
from standardwebhooks import Webhook, WebhookVerificationError

wh = Webhook(os.environ["BODYGUARD_WEBHOOK_SECRET"])  # "whsec_..."
app = Flask(__name__)


@app.post("/webhook")
def webhook():
    # Utilisez le corps brut : la signature couvre les octets exacts envoyés par Bodyguard.
    try:
        event = wh.verify(request.get_data(), request.headers)
    except WebhookVerificationError:
        return "Invalid signature", 400

    if event["type"] == "message.updated":
        print("Message updated:", event["data"])
    elif event["type"] == "author.updated":
        print("Author updated:", event["data"])

    # Toute réponse 2xx acquitte la livraison.
    return "", 200


if __name__ == "__main__":
    app.run(port=8080)
```

```go Go theme={null}
package main

import (
	"encoding/json"
	"io"
	"log"
	"net/http"
	"os"

	standardwebhooks "github.com/standard-webhooks/standard-webhooks/libraries/go"
)

func main() {
	wh, err := standardwebhooks.NewWebhook(os.Getenv("BODYGUARD_WEBHOOK_SECRET")) // "whsec_..."
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) {
		// Utilisez le corps brut : la signature couvre les octets exacts envoyés par Bodyguard.
		body, err := io.ReadAll(r.Body)
		if err != nil {
			http.Error(w, "Cannot read body", http.StatusBadRequest)
			return
		}

		if err := wh.Verify(body, r.Header); err != nil {
			http.Error(w, "Invalid signature", http.StatusBadRequest)
			return
		}

		var event struct {
			Type string          `json:"type"`
			Data json.RawMessage `json:"data"`
		}
		if err := json.Unmarshal(body, &event); err != nil {
			http.Error(w, "Invalid payload", http.StatusBadRequest)
			return
		}

		switch event.Type {
		case "message.updated":
			log.Printf("Message updated: %s", event.Data)
		case "author.updated":
			log.Printf("Author updated: %s", event.Data)
		}

		// Toute réponse 2xx acquitte la livraison.
		w.WriteHeader(http.StatusOK)
	})

	log.Println("Listening on port 8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}
```

> [!WARNING]
>
> Vérifiez le corps brut de la requête, exactement tel que reçu. Si un framework analyse le JSON et que vous le sérialisez à nouveau, les espaces et l'ordre des clés peuvent changer et la vérification de la signature échoue.

L'événement [`webhook.validate`](https://docs.bodyguard.ai/fr/api-reference/reference/webhooks/payloads#webhook-validate) ne nécessite aucun traitement particulier : il est signé comme n'importe quel autre événement, votre endpoint le vérifie donc et répond avec un code de statut `2xx`.

Lancez votre endpoint :

```bash JavaScript theme={null}
BODYGUARD_WEBHOOK_SECRET="whsec_..." node index.js
```

```bash Python theme={null}
BODYGUARD_WEBHOOK_SECRET="whsec_..." python app.py
```

```bash Go theme={null}
BODYGUARD_WEBHOOK_SECRET="whsec_..." go run .
```

### Autres langages

Standard Webhooks fournit aussi des bibliothèques pour Java et Kotlin, Rust, Ruby, PHP, C# et Elixir. Consultez la [liste des bibliothèques](https://github.com/standard-webhooks/standard-webhooks#libraries).

> [accordion] Vérifier une signature sans bibliothèque
>
> Si aucune bibliothèque ne convient à votre stack, implémentez la vérification décrite dans la [spécification Standard Webhooks](https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md) :
>
> 1. Lisez les [en-têtes](https://docs.bodyguard.ai/fr/api-reference/reference/webhooks/payloads.md#en-têtes) `webhook-id`, `webhook-timestamp` et `webhook-signature`.
> 2. Rejetez la requête si `webhook-timestamp` est trop éloigné de l'heure actuelle (les bibliothèques officielles utilisent cinq minutes).
> 3. Construisez le contenu signé : `{webhook-id}.{webhook-timestamp}.{corps brut}`.
> 4. Retirez le préfixe `whsec_` de votre secret de signature et décodez le reste en base64. Calculez le HMAC SHA256 du contenu signé avec cette clé, puis encodez le résultat en base64.
> 5. Comparez-le, en temps constant, à chaque signature `v1,` de l'en-tête `webhook-signature`. La requête est valide si l'une d'elles correspond.

## Tester votre endpoint

Lorsque vous enregistrez le webhook ou modifiez son URL, Bodyguard envoie un événement [`webhook.validate`](https://docs.bodyguard.ai/fr/api-reference/reference/webhooks/payloads#webhook-validate) : si votre endpoint ne répond pas avec un code de statut `2xx`, l'enregistrement échoue. Pour vérifier votre endpoint à tout moment, cliquez sur **Send test event** dans le dashboard.

## Traiter les événements en toute sécurité

* **Répondez rapidement.** Renvoyez un code de statut `2xx` sous 10 secondes, dès que vous avez vérifié et stocké l'événement, et effectuez le traitement lourd ensuite. Toute autre réponse, ou l'absence de réponse, est un [échec](https://docs.bodyguard.ai/fr/api-reference/webhooks/handling-errors.md#traitement-des-réponses) et déclenche une nouvelle tentative.
* **Dédoublonnez avec `webhook-id`.** Bodyguard retente les livraisons échouées avec le même en-tête [`webhook-id`](https://docs.bodyguard.ai/fr/api-reference/reference/webhooks/payloads#en-têtes). Stockez les identifiants que vous avez déjà traités, et ignorez ceux que vous avez déjà vus.
* **Gardez le secret privé.** Chargez-le depuis l'environnement et ne l'écrivez jamais dans les logs.

## Étapes suivantes

> [card] [Configuration](https://docs.bodyguard.ai/fr/api-reference/webhooks/configuration.md)
>
> Événements, secret de signature, contacts et statuts du webhook.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.