📑 Table des matières

16 - Hermes Agent : Webhooks — déclencher Hermes depuis l'extérieur

Hermes Agent 🔴 Avancé ⏱️ 11 min de lecture 📅 2026-05-05

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éfaut 0.0.0.0)
  • port : port HTTP (défaut 8644)
  • secret : secret HMAC global, utilisé si aucune route ne définit son propre secret
  • rate_limit : nombre max de requêtes par minute par route (défaut 30)
  • max_body_bytes : taille max du payload en octets (défaut 1 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 header X-GitHub-Event, X-GitLab-Event ou champ event_type)
  • prompt : template de prompt avec interpolation du payload
  • skills : liste des skills à injecter dans le contexte de l''agent
  • deliver : cible de livraison (log, github_comment, telegram, discord, slack, etc.)
  • deliver_extra : paramètres de livraison (templates interpolés depuis le payload)
  • deliver_only : si true, 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ée
  • pull_request_review : un review est soumis
  • issues : un ticket est créé ou modifié
  • release : une nouvelle version est publiée
  • workflow_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

  1. Allez dans Settings → Webhooks → Add webhook
  2. Payload URL : http://votre-serveur:8644/webhooks/github_pr_review
  3. Content type : application/json
  4. Secret : le même secret que dans votre config.yaml
  5. 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émarrage
  • session:start / session:end — lifecycle sessions
  • agent:start / agent:step / agent:end — boucle de l''agent
  • command:* — 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.yaml correspond exactement à celui configuré côté provider
  • Pour GitHub, vérifiez le header X-Hub-Signature-256 (nécessite secret encodé en UTF-8)
  • Pour GitLab, vérifiez le header X-Gitlab-Token
  • Pour un webhook générique, utilisez le header X-Webhook-Signature avec 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 CLI gh et authentifiez-vous (gh auth login)
  • Cross-platform : vérifiez que la plateforme cible est activée dans config.yaml et connectée
  • chat_id manquant : fournissez un chat_id dans deliver_extra ou configurez un home_channel pour 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 :

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.