API WhatsApp avec Python : un webhook FastAPI qui répond
Pour utiliser l'API WhatsApp depuis Python, exposez une route HTTP pour le webhook et appelez une API REST pour répondre. Aucun SDK n'est nécessaire : la signature est un HMAC-SHA256 que l'on vérifie en quelques lignes, et chaque appel est du JSON sur HTTPS.
L'application
# main.py — pip install fastapi uvicorn httpximport hashlib, hmac, json, os, timeimport httpxfrom fastapi import FastAPI, Request, Responseapp = FastAPI()API = "https://nodium.io/api/v1"def verify_nodium(raw_body: bytes, header: str, secret: str) -> bool: parts = header.split(",") t = next((p[2:] for p in parts if p.startswith("t=")), None) signatures = [p[3:] for p in parts if p.startswith("v1=")] if not t or abs(time.time() - int(t)) > 300: return False expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest() return any(hmac.compare_digest(sig, expected) for sig in signatures)@app.post("/webhooks/nodium")async def nodium_webhook(request: Request): raw_body = await request.body() # the raw bytes, before any JSON parsing header = request.headers.get("x-nodium-signature", "") if not verify_nodium(raw_body, header, os.environ["NODIUM_WEBHOOK_SECRET"]): return Response(status_code=400) event = json.loads(raw_body) if event["event"] == "message.received" and event["data"]["type"] == "text": async with httpx.AsyncClient() as client: await client.post( f"{API}/messages", headers={"Authorization": f"Bearer {os.environ['NODIUM_KEY']}"}, json={ "channelId": event["data"]["channel_id"], "to": event["data"]["from"], "type": "text", "text": f"You wrote: {event['data']['text']}", "idempotencyKey": f"reply-{event['id']}", }, ) return Response(status_code=200)Lancez-la avec uvicorn main:app, avec NODIUM_KEY et NODIUM_WEBHOOK_SECRET dans l'environnement.
Dire à Nodium où vous appeler
curl https://nodium.io/api/v1/webhooks \ -H "Authorization: Bearer $NODIUM_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.example.com/webhooks/nodium", "events": ["message.received"] }'# → data.secret (whsec_…): shown onceEnsuite
- Écrivez en premier à un client avec un modèle approuvé : le texte libre ne part que dans la fenêtre de 24 heures.
- Répondez
200vite et faites le travail lent ensuite : un événement non acquitté est livré de nouveau, avec le mêmeid. - Branchez les numéros de vos clients avec une clé pour tous.
Questions fréquentes
Existe-t-il un SDK Python ?
Pas encore. L'API est du REST simple, décrite en OpenAPI 3.1, et la référence porte un exemple Python pour chaque route.
Cela marche-t-il avec Django ou Flask ?
Oui. Deux choses seulement comptent : vérifier la signature sur le corps brut de la requête, avant toute lecture du JSON, et répondre 200 vite.