Section 11.3.5 : Webhooks — Événements en temps réel
🎯 Objectif pédagogique
Comprendre le modèle de communication par webhooks (push vs pull) et savoir les recevoir en Python. Vous serez capable de réagir automatiquement à des événements externes — la brique fondamentale de l'automatisation en temps réel.
Pull vs Push — Deux façons de récupérer des données
Jusqu'ici, Marc faisait du polling (pull) : son script appelait l'API toutes les 5 minutes pour vérifier s'il y a du nouveau. C'est comme vérifier sa boîte aux lettres toutes les heures. Un webhook est l'inverse : l'API VOUS notifie quand il y a du nouveau. C'est le facteur qui sonne à la porte.
Comment fonctionnent les webhooks
- →Vous donnez une URL au service (votre endpoint webhook)
- →Quand un événement se produit, le service envoie un POST à votre URL
- →Vous traitez la notification et répondez 200 OK
Créer un endpoint webhook avec Flask
pip install flask
from flask import Flask, request, jsonify
import json
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def handle_webhook():
"""Réceptionne les notifications webhook."""
# Récupérer les données envoyées
data = request.json
event_type = request.headers.get('X-Event-Type', 'unknown')
print(f"\n🔔 Webhook reçu : \{event_type\}")
print(json.dumps(data, indent=2, ensure_ascii=False))
# Traiter selon le type d'événement
if event_type == 'application.status_changed':
company = data.get('company', 'N/A')
new_status = data.get('status', 'N/A')
print(f"📋 \{company\} → statut changé en : \{new_status\}")
if new_status == 'interview':
# Déclencher une action (notification, agenda, etc.)
print("🎉 Entretien détecté ! Envoi notification...")
# Répondre 200 rapidement (le service attend)
return jsonify(\{"status": "received"\}), 200
@app.route('/health', methods=['GET'])
def health():
return jsonify(\{"status": "ok"\}), 200
if __name__ == '__main__':
app.run(port=5000, debug=True)
Sécuriser les webhooks
import hmac
import hashlib
def verify_webhook_signature(payload, signature, secret):
"""Vérifie que le webhook vient bien du service attendu."""
expected = hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256=\{expected\}", signature)
@app.route('/webhook', methods=['POST'])
def secure_webhook():
# Vérifier la signature
signature = request.headers.get('X-Signature-256', '')
if not verify_webhook_signature(request.data, signature, os.getenv('WEBHOOK_SECRET')):
return jsonify(\{"error": "Invalid signature"\}), 401
# Traiter si valide
data = request.json
# ...
return jsonify(\{"status": "ok"\}), 200
Exposer un webhook local avec ngrok
Pour tester en local, les services externes ne peuvent pas atteindre localhost:5000. ngrok crée un tunnel public temporaire :
# Installer ngrok (https://ngrok.com)
# Lancer votre serveur Flask puis :
ngrok http 5000
# Résultat :
# https://abc123.ngrok-free.app → localhost:5000
# Utilisez cette URL comme webhook dans le service externe
Webhooks courants
| Service | Événements | Usage Marc |
|---|---|---|
| GitHub | Push, PR, Issue | Notification quand un repo intéressant est mis à jour |
| Stripe | Paiement, remboursement | (Futur projet e-commerce) |
| Slack | Message, réaction | Centraliser les notifications |
| Calendly | Rendez-vous créé/annulé | Quand un entretien est planifié |
| Gmail | Push notification (via Pub/Sub) | Email reçu d'un recruteur |
Webhook vs WebSocket vs SSE
- →Webhook : événement ponctuel, serveur → serveur (POST HTTP)
- →WebSocket : connexion bidirectionnelle persistante (chat, jeux)
- →SSE : flux unidirectionnel serveur → client (notifications temps réel) Pour l'automatisation, les webhooks suffisent dans 90% des cas.
🏋️ Exercice pratique (20 minutes)
- →Créez un serveur Flask avec un endpoint
/webhook - →Envoyez un webhook de test avec curl ou Python :
curl -X POST http://localhost:5000/webhook \
-H "Content-Type: application/json" \
-H "X-Event-Type: application.status_changed" \
-d '\{"company": "Google", "status": "interview", "date": "2026-03-20"\}'
- →Traitez l'événement : affichez un message personnalisé
- →Ajoutez la vérification de signature
Quelle est la principale différence entre le polling et les webhooks ?
Pourquoi faut-il vérifier la signature d'un webhook ?