Introduction
Hermes Agent n''est pas qu''un assistant conversationnel : c''est aussi un moteur d''automatisation capable de réagir à des événements externes. Les webhooks constituent le pont entre le monde extérieur et votre instance Hermes. Que ce soit une Pull Request sur GitHub, une alerte de monitoring, un formulaire soumis ou un pipeline CI/CD qui termine, les webhooks permettent à Hermes de recevoir ces signaux et d''y répondre de manière intelligente.
Cet article explore en profondeur le système de webhooks intégré à Hermes — de la configuration dans config.yaml jusqu''aux mécanismes de sécurité, en passant par les cas d''usage concrets et les meilleures pratiques de dépannage. C''est un guide de niveau avancé qui suppose que vous maîtrisez déjà les fondamentaux d''Hermes Agent, décrits dans l''article de présentation et la configuration avancée.
Qu''est-ce que les webhooks dans Hermes ?
Un webhook est un mécanisme par lequel un service externe envoie une requête HTTP POST vers une URL que vous exposez, contenant un payload JSON décrivant un événement. Dans le contexte d''Hermes, l''adaptateur Webhook (gateway/platforms/webhook.py) est un adaptateur de plateforme au même titre que Telegram ou Discord : il tourne dans le gateway multi-plateforme et bénéficie du même cycle de vie, de la même gestion de sessions et des mêmes mécanismes de livraison de réponses.
Concrètement, Hermes lance un serveur HTTP (aiohttp) sur un port configurable (par défaut 8644) et écoute les requêtes POST sur /webhooks/{route_name}. Chaque route est déclarée dans config.yaml et définit quels événements accepter, comment transformer le payload en prompt pour l''agent, quels skills charger, et où livrer la réponse.
Architecture d''un webhook dans Hermes
Service externe (GitHub, GitLab, Sentry…)
│
▼ HTTP POST
┌─────────────────────────────┐
│ WebhookAdapter (aiohttp) │
│ ┌─ Validation HMAC │
│ ├─ Rate limiting │
│ ├─ Idempotency cache │
│ ├─ Filtre événements │
│ ├─ Render prompt template │
│ ├─ Injection skills │
│ └─ Agent run (202 Accepted) │
└─────────────────────────────┘
│
▼
Réponse livrée vers :
• Telegram / Discord / Slack (cross-platform)
• Commentaire GitHub PR
• Log interne
Le point clé : la réponse HTTP est immédiate (202 Accepted), l''agent traite la requête de manière asynchrone, et la réponse est routée vers la plateforme de votre choix.
Configuration dans config.yaml
La configuration des webhooks se place sous la clé platforms.webhook dans votre fichier ~/.hermes/config.yaml. Voici la structure complète :
platforms:
webhook:
enabled: true
extra:
host: "0.0.0.0"
port: 8644
secret: "votre-secret-hmac-global"
rate_limit: 30
max_body_bytes: 1048576
routes:
github_pr_review:
secret: "${WEBHOOK_GITHUB_SECRET}"
events:
- pull_request
- pull_request_review
prompt: >
Review this pull request and provide detailed feedback:
PR #{pull_request.number} — {pull_request.title}
Author: {pull_request.user.login}
Body: {pull_request.body}
Diff: {__raw__}
skills:
- code-review
deliver: github_comment
deliver_extra:
repo: "{repository.full_name}"
pr_number: "{pull_request.number}"
monitoring_alert:
secret: "${WEBHOOK_GRAFANA_SECRET}"
events:
- alerting
prompt: >
Analyse cette alerte de monitoring et propose des actions :
{__raw__}
deliver: telegram
deliver_extra:
chat_id: "-1001234567890"
deploy_notification:
secret: "${WEBHOOK_DEPLOY_SECRET}"
events:
- deploy.success
- deploy.failure
prompt: >
Déploiement {event_type} sur {environment} :
{__raw__}
deliver_only: true
deliver: discord
deliver_extra:
chat_id: "123456789"
Paramètres globaux
host: adresse d''écoute (défaut0.0.0.0)port: port HTTP (défaut8644)secret: secret HMAC global, utilisé si aucune route ne définit son propre secretrate_limit: nombre max de requêtes par minute par route (défaut30)max_body_bytes: taille max du payload en octets (défaut1 048 576= 1 Mo)
Paramètres par route
Chaque clé sous routes définit un endpoint /webhooks/{nom_de_la_route} :
secret: secret HMAC pour cette route (requis — voir section sécurité)events: liste des événements acceptés (filtrage par headerX-GitHub-Event,X-GitLab-Eventou champevent_type)prompt: template de prompt avec interpolation du payloadskills: liste des skills à injecter dans le contexte de l''agentdeliver: cible de livraison (log,github_comment,telegram,discord,slack, etc.)deliver_extra: paramètres de livraison (templates interpolés depuis le payload)deliver_only: sitrue, skip l''agent — la template rendue est livrée directement (notification push, zéro coût LLM)
Événements déclencheurs
GitHub Events
Les webhooks GitHub utilisent le header X-GitHub-Event pour identifier le type d''événement. Hermes lit automatiquement ce header et le compare à la liste events de la route. Événements courants :
push: un commit est poussépull_request: une PR est ouverte, mise à jour ou ferméepull_request_review: un review est soumisissues: un ticket est créé ou modifiérelease: une nouvelle version est publiéeworkflow_run: un GitHub Action se termine
GitLab Events
Le header équivalent est X-GitLab-Event. Les événements incluent Push Hook, Merge Request Hook, Note Hook, etc.
Custom Events
Pour tout service qui n''utilise pas les headers GitHub/GitLab, Hermes vérifie le champ event_type dans le payload JSON. Cela couvre Sentry, Grafana, Supabase, Stripe, ou tout webhook personnalisé.
Exemple de webhook CI/CD
platforms:
webhook:
extra:
routes:
ci_pipeline:
secret: "${WEBHOOK_CI_SECRET}"
events:
- pipeline.success
- pipeline.failure
prompt: >
Pipeline CI/CD terminée pour le projet {project_name} :
Statut: {event_type}
Commit: {commit_sha} par {author}
Branche: {branch}
Détails: {__raw__}
deliver: telegram
deliver_extra:
chat_id: "-1001234567890"
Handlers : prompt template, skills et contexte
Templates de prompt
Les templates de prompt supportent l''interpolation par notation pointée pour naviguer dans le payload JSON imbriqué :
{pull_request.title} → payload["pull_request"]["title"]
{pull_request.user.login} → payload["pull_request"]["user"]["login"]
{repository.full_name} → payload["repository"]["full_name"]
Le token spécial {__raw__} dump le payload entier en JSON (tronqué à 4000 caractères), idéal quand l''agent a besoin de voir toutes les données.
Si aucun template n''est fourni, Hermes génère un prompt par défaut avec le payload JSON brut.
Injection de skills
Le paramètre skills charge le contenu d''un skill directement dans le prompt envoyé à l''agent, sans passer par les commandes slash. Cela permet de donner à l''agent un contexte spécifique pour traiter le webhook :
routes:
github_pr_review:
skills:
- code-review
prompt: "Review this PR: {pull_request.title}
{pull_request.body}"
Le skill code-review sera injecté avec ses instructions et son prompt template, guidant l''agent dans son analyse.
Mode deliver_only (push direct)
Le mode deliver_only: true contourne totalement l''agent. La template rendue devient le message envoyé directement à la plateforme cible. Cas d''usage :
- Alertes de monitoring vers Telegram/Discord (latence < 1 seconde)
- Notifications de déploiement vers un canal
- Pings inter-agents (zéro coût LLM)
Sécurité
HMAC Signature Verification
Chaque route doit avoir un secret configuré. Hermes valide la signature HMAC avant de lire le payload (auth-before-body) :
- GitHub : vérifie
X-Hub-Signature-256(HMAC-SHA256) - GitLab : vérifie
X-Gitlab-Token(comparaison directe) - Générique : vérifie
X-Webhook-Signature(HMAC-SHA256)
Si un secret est configuré mais qu''aucun header de signature n''est trouvé, la requête est rejetée (401 Unauthorized).
Mode test (INSECURE_NO_AUTH)
Pour le développement local, vous pouvez temporairement désactiver l''authentification :
routes:
test_route:
secret: "INSECURE_NO_AUTH"
⚠️ Ne jamais utiliser en production. Ce mode skip toute validation de signature.
Rate Limiting
Hermes impose un rate limit par route (fenêtre fixe de 60 secondes). Au-delà, les requêtes reçoivent un 429 Too Many Requests. Le défaut est de 30 requêtes/minute par route.
Idempotency Cache
Pour éviter les doublons lors des retries des providers, Hermes maintient un cache des IDs de livraison (X-GitHub-Delivery ou X-Request-ID) avec un TTL de 1 heure. Une requête dupliquée reçoit un 200 avec status: "duplicate" au lieu de déclencher un second run de l''agent.
Limites de taille du payload
Le paramètre max_body_bytes (défaut 1 Mo) est vérifié avant la lecture du corps via Content-Length. Un payload trop gros reçoit un 413 Payload Too Large.
Cas d''usage concrets
1. Review automatique de Pull Requests
Configurez Hermes pour recevoir les événements pull_request de GitHub et poster un commentaire de review directement sur la PR :
routes:
pr_review:
secret: "${GITHUB_WEBHOOK_SECRET}"
events: ["pull_request"]
prompt: >
Analyse cette pull request avec attention.
Vérifie la qualité du code, les risques potentiels
et suggère des améliorations.
Repo: {repository.full_name}
PR #{pull_request.number}: {pull_request.title}
Par: {pull_request.user.login}
Description: {pull_request.body}
skills: ["code-review"]
deliver: github_comment
deliver_extra:
repo: "{repository.full_name}"
pr_number: "{pull_request.number}"
2. Alertes de monitoring vers Telegram
Recevez les alertes Grafana ou Sentry et faites analyser les incidents par l''IA :
routes:
grafana_alert:
secret: "${GRAFANA_WEBHOOK_SECRET}"
events: ["alerting"]
prompt: >
Alerte de monitoring reçue.
Analyser la cause probable et proposer un plan d''action.
{__raw__}
deliver: telegram
deliver_extra:
chat_id: "${ALERTS_CHAT_ID}"
3. Soumission de formulaires
Un site web envoie les soumissions de formulaire vers Hermes, qui les traite et les redirige :
routes:
contact_form:
secret: "${FORM_WEBHOOK_SECRET}"
prompt: >
Nouvelle soumission de formulaire de contact :
Nom: {name}
Email: {email}
Sujet: {subject}
Message: {message}
Catégorise cette demande et propose une réponse adaptée.
deliver: slack
deliver_extra:
chat_id: "C12345SUPPORT"
4. Notifications de déploiement (push direct)
Pour les déploiements, pas besoin d''IA — une notification brute suffit :
routes:
deploy:
secret: "${DEPLOY_WEBHOOK_SECRET}"
events: ["deploy.success", "deploy.failure"]
prompt: "🚀 Déploiement {event_type} sur {environment} (v{version})"
deliver_only: true
deliver: discord
deliver_extra:
chat_id: "${DEPLOYS_CHANNEL}"
Intégration avec GitHub Webhooks
Configuration côté GitHub
- Allez dans Settings → Webhooks → Add webhook
- Payload URL :
http://votre-serveur:8644/webhooks/github_pr_review - Content type :
application/json - Secret : le même secret que dans votre
config.yaml - Events : sélectionnez
Pull requests,Push events, etc.
Sécurité du secret
Stockez le secret dans ~/.hermes/.env et référencez-le avec ${VAR} dans le config :
# ~/.hermes/.env
GITHUB_WEBHOOK_SECRET=whsec_abc123def456...
# config.yaml
routes:
github_pr_review:
secret: "${GITHUB_WEBHOOK_SECRET}"
Hermes résout automatiquement les variables d''environnement dans la configuration au démarrage.
Publication via ngrok (développement)
Pour tester en local derrière un NAT :
ngrok http 8644
# → https://abc123.ngrok.io/webhooks/votre_route
Mettez l''URL ngrok comme Payload URL dans les paramètres GitHub.
Logs et monitoring des webhooks
Logs de l''adaptateur
Chaque requête webhook est loggée par l''adaptateur :
[webhook] POST event=pull_request route=github_pr_review prompt_len=847 delivery=12345-abcde
[webhook] Posted comment on owner/repo#42
[webhook] Skipping duplicate delivery 12345-abcde
[webhook] Invalid signature for route grafana_alert
Health check
Le endpoint GET /health retourne {"status": "ok", "platform": "webhook"}. Utilisez-le pour votre monitoring :
curl http://localhost:8644/health
Routes dynamiques
Hermes supporte les routes créées dynamiquement par l''agent lui-même. Ces routes sont stockées dans ~/.hermes/webhook_subscriptions.json et sont rechargées automatiquement à chaque requête (vérification mtime). Les routes statiques (config.yaml) ont toujours la priorité sur les routes dynamiques.
Hooks lifecycle
Le système de hooks d''Hermes (gateway/hooks.py) permet de réagir aux événements internes du gateway, indépendamment des webhooks externes :
gateway:startup— au démarragesession:start/session:end— lifecycle sessionsagent:start/agent:step/agent:end— boucle de l''agentcommand:*— wildcard pour toute commande slash
Vous pouvez combiner hooks et webhooks : un hook agent:end pourrait logger les statistiques de chaque réponse webhook.
Dépannage
Port déjà utilisé
[webhook] Port 8644 already in use.
Changez le port dans config.yaml :
platforms:
webhook:
extra:
port: 8645
Signature invalide
[webhook] Invalid signature for route ma_route
- Vérifiez que le secret dans
config.yamlcorrespond exactement à celui configuré côté provider - Pour GitHub, vérifiez le header
X-Hub-Signature-256(nécessitesecretencodé en UTF-8) - Pour GitLab, vérifiez le header
X-Gitlab-Token - Pour un webhook générique, utilisez le header
X-Webhook-Signatureavec le HMAC-SHA256 du body
Route non trouvée (404)
Vérifiez que le nom de la route dans l''URL correspond exactement à la clé dans config.yaml. L''URL est sensible à la casse : /webhooks/GitHub_PR ≠ /webhooks/github_pr.
deliver échoue
github_comment: installez le CLIghet authentifiez-vous (gh auth login)- Cross-platform : vérifiez que la plateforme cible est activée dans
config.yamlet connectée chat_idmanquant : fournissez unchat_iddansdeliver_extraou configurez unhome_channelpour la plateforme cible
Payload trop gros (413)
Augmentez max_body_bytes si vos webhooks envoient de gros payloads (par ex. des diffs de PR très volumineux) :
platforms:
webhook:
extra:
max_body_bytes: 5242880 # 5 Mo
Rate limit (429)
Si un service envoie trop d''événements, ajustez rate_limit par route :
routes:
busy_service:
rate_limit: 100
Dépendance aiohttp manquante
L''adaptateur webhook nécessite aiohttp. Si vous obtenez une erreur d''import :
pip install aiohttp
✅ Conclusion
Les webhooks transforment Hermes Agent en un véritable nœud d''automatisation capable de réagir à des événements provenant de dizaines de services externes. L''architecture d''adaptateur de plateforme garantit que les webhooks bénéficient du même cycle de vie robuste que Telegram, Discord ou Slack — avec en plus des mécanismes de sécurité avancés (HMAC, rate limiting, idempotency) et la flexibilité du routage cross-platform.
Pour aller plus loin dans la maîtrise d''Hermes :
- Cron Jobs et automatisation — pour les tâches récurrentes programmées
- Gateway multi-plateforme — pour comprendre l''architecture complète
- Profils et configurations — pour gérer plusieurs instances d''Hermes
- Délegation et sous-agents — pour paralléliser les tâches complexes
- Serveurs MCP — pour étendre les capacités d''Hermes via des outils externes
Conclusion
Les webhooks d'Hermes Agent offrent une passerelle bidirectionnelle entre votre agent IA et l'écosystème externe. Là où les cron jobs permettent à Hermes de prendre l'initiative à intervalles réguliers, les webhooks permettent aux services tiers de déclencher des actions en temps réel. Combinés ensemble, cron jobs et webhooks couvrent l'intégralité du spectre d'automatisation : tâches planifiées d'un côté, événements réactifs de l'autre. La flexibilité de routage cross-platform, les mécanismes de sécurité (HMAC, rate limiting) et le support de la livraison asynchrone font des webhooks un outil essentiel pour intégrer Hermes dans n'importe quel flux de travail.