Branchez les webhooks Hermes : laissez vos systèmes métier pousser des alertes vers Telegram, Discord et Slack

La plupart des systèmes métier finissent par avoir besoin de la même automatisation : lorsqu’un statut de commande change, qu’un paiement réussit, qu’un moniteur se déclenche ou qu’un pipeline CI se termine, publier un message dans un canal d’équipe. La version initiale la plus rapide est généralement un script qui fait du polling sur une base de données ou une API, puis dépose le message dans Telegram, Discord, Slack ou une autre plateforme de chat.
Le polling fonctionne, mais il a de vrais coûts à long terme :
- Latence et quota API. Scanner chaque minute signifie que la plupart des requêtes ne renvoient rien ; passer à un polling à la seconde multiplie la pression sur l’API et les coûts.
- Couplage. Le système métier finit avec des templates de message et des tokens de plateforme de chat codés en dur. Changer de canal ou de groupe impose une modification du code.
- Extensibilité. La même alerte peut devoir partir vers Telegram, Slack, ou être d’abord résumée par une IA. Les scripts de polling deviennent vite complexes.
Hermes Agent embarque une plateforme webhook — un récepteur d’événements HTTP. Votre système métier POST un événement, Hermes valide la signature, rend un template et pousse le message vers la plateforme de chat que vous avez configurée. Si l’événement est une pure notification qui n’a pas besoin de raisonnement IA, vous pouvez activer le mode Direct Delivery : aucun appel LLM, aucune boucle d’agent, une livraison en moins d’une seconde et zéro coût en tokens.
Cet article est un guide pratique pour brancher des systèmes métier sur les webhooks de Hermes : activation de la plateforme, configuration des routes, trois scénarios concrets complets et durcissement de la sécurité.
Deux modes : traitement par agent vs Direct Delivery
Les webhooks de Hermes prennent en charge deux chemins de livraison. Bien choisir est important.
| Mode | Appelle le LLM ? | Idéal pour | Latence | Coût |
|---|---|---|---|---|
| Traitement par agent | Oui | Les événements qui nécessitent compréhension, résumé ou une décision avant de répondre/transférer | Secondes | Coût en tokens |
| Direct Delivery | Non | Les pures notifications : commandes, paiements, alertes, statut CI | Moins d’une seconde | Zéro coût LLM |
Direct Delivery est au cœur de cet article. Le flux est simple :
- Le système métier signe et POST un payload JSON vers
https://your-server:8644/webhooks/<route-name>. - Hermes valide la signature HMAC pour confirmer que l’expéditeur est de confiance.
- Un template transforme les champs JSON en message lisible.
- Le message est livré directement vers Telegram, Discord, Slack, Feishu, etc., et Hermes renvoie
200 OK.
Aucun LLM n’est impliqué, si bien que la vitesse, le coût et la fiabilité se rapprochent d’une passerelle de messagerie classique — mais la configuration et l’extensibilité restent aussi flexibles que le reste de Hermes.
Étape 1 : activer la plateforme webhook
Vous pouvez activer les webhooks via des variables d’environnement pour démarrer vite, ou via config.yaml pour des déploiements durables.
Variables d’environnement (le plus rapide)
Ajoutez ces lignes à ~/.hermes/.env :
WEBHOOK_ENABLED=true
WEBHOOK_PORT=8644 # default
WEBHOOK_SECRET=your-global-secret
Redémarrez le gateway :
hermes gateway restart
Confirmez que le serveur écoute :
curl http://localhost:8644/health
Une réponse {"status": "ok", "platform": "webhook"} signifie qu’il est opérationnel.
Fichier de configuration (recommandé en production)
Déclarez le bloc platforms.webhook dans ~/.hermes/config.yaml :
platforms:
webhook:
enabled: true
extra:
port: 8644
secret: "your-global-secret"
Après le redémarrage du gateway, Hermes écoute sur le port 8644. Si le serveur est sur l’internet public, assurez-vous que le pare-feu autorise ce port. S’il est derrière un NAT ou n’a pas d’IP publique, exposez-le avec un Cloudflare Tunnel ou ngrok.
Étape 2 : configurer une route de notification métier
Les routes se déclarent sous platforms.webhook.extra.routes. Chaque route possède un nom, un filtre d’événements, un secret, un template de message et une cible de livraison. Voici un exemple complet de notification de commande e-commerce qui pousse les nouvelles commandes vers Telegram.
platforms:
webhook:
enabled: true
extra:
port: 8644
secret: "global-fallback-secret"
routes:
order-notify:
events: ["order.created"]
secret: "shopify-webhook-secret"
prompt: |
🛒 New order #{order.id}
Amount: {order.total_price} {order.currency}
Customer: {order.customer.email}
Item: {order.line_items[0].title}
deliver: "telegram"
deliver_only: true
deliver_extra:
chat_id: "-1001234567890"
Points clés :
eventsest optionnel. Si votre système métier envoie un type d’événement viaX-Webhook-Eventouevent_type, vous pouvez restreindre la route àorder.created.secretsert à la validation de la signature HMAC. Si la route n’a pas de secret, elle retombe sur lesecretglobal.deliver_only: trueactive Direct Delivery et saute l’appel au LLM.promptest un template. Utilisez la notation par points comme{order.total_price}pour accéder aux champs JSON.{__raw__}déverse tout le payload.deliver_extra.chat_idcible un groupe précis. S’il est omis, Hermes livre vers le canal d’accueil configuré de la plateforme (ce qui exige que cette plateforme soit activée et connectée).
Étape 3 : envoyer des événements depuis votre système métier
Votre système métier POST vers la bonne URL. Pour l’exemple ci-dessus :
POST https://your-server:8644/webhooks/order-notify
Utilisez la signature Generic V2 : concaténez timestamp.body, calculez le HMAC-SHA256 et envoyez-le dans l’en-tête X-Webhook-Signature-V2 accompagné de X-Webhook-Timestamp. La fenêtre de timestamp est de ±300 secondes, ce qui bloque les attaques par rejeu.
import hmac
import hashlib
import time
import json
import requests
secret = b"shopify-webhook-secret"
body = json.dumps({
"event_type": "order.created",
"order": {
"id": 10086,
"total_price": "199.00",
"currency": "USD",
"customer": {"email": "[email protected]"},
"line_items": [{"title": "Hermes sticker pack"}]
}
}).encode()
timestamp = str(int(time.time()))
signature = hmac.new(secret, f"{timestamp}.{body.decode()}".encode(), hashlib.sha256).hexdigest()
requests.post(
"https://your-server:8644/webhooks/order-notify",
data=body,
headers={
"Content-Type": "application/json",
"X-Webhook-Signature-V2": signature,
"X-Webhook-Timestamp": timestamp,
}
)
Les signatures GitHub et GitLab sont aussi détectées automatiquement. Pour les systèmes métier sur mesure, préférez Generic V2.
Étape 4 : tester la route
Pas besoin d’attendre que le système métier soit en production. Testez d’abord en local :
hermes webhook test order-notify \
--payload '{"event_type":"order.created","order":{"id":10086,"total_price":"199.00","currency":"USD","customer":{"email":"[email protected]"},"line_items":[{"title":"Hermes sticker pack"}]}}'
hermes webhook test simule un POST pour vérifier le rendu du template et la livraison. Si le message n’arrive pas, consultez gateway.log ou lancez hermes gateway run au premier plan pour voir si la signature a échoué, si l’événement a été filtré ou si la cible de livraison n’est pas connectée.
Scénario 1 : notifications de commande e-commerce → Telegram
L’exemple order-notify ci-dessus est déjà complet. Quelques détails qui valent le coup d’être soulignés :
- Les
chat_idde groupes Telegram sont généralement négatifs et commencent par-100. - Pour cibler un sujet de forum précis, ajoutez
message_thread_id: "42"dansdeliver_extra. {order.line_items[0].title}n’affiche que le premier article. Pour tout lister, pré-traitez le payload côté système métier ou utilisez le mode agent avec{__raw__}et laissez le LLM résumer.
Scénario 2 : paiement réussi → Discord
Les systèmes de paiement comme Stripe émettent déjà des webhooks. Associez l’événement de succès de Stripe à un message Discord :
routes:
payment-success:
events: ["payment_intent.succeeded"]
secret: "stripe-webhook-secret"
prompt: |
💰 Payment received: {amount} {currency}
Order: {metadata.order_id}
Customer: {receipt_email}
deliver: "discord"
deliver_only: true
deliver_extra:
chat_id: "123456789012345678"
Stripe envoie type plutôt que event_type. Si Hermes ne reconnaît pas l’en-tête d’événement, soit encapsulez le payload dans votre système métier, soit laissez events vide et utilisez filters :
routes:
payment-success:
secret: "stripe-webhook-secret"
filters:
- field: "type"
equals: "payment_intent.succeeded"
prompt: "..."
deliver: "discord"
deliver_only: true
Scénario 3 : alertes de monitoring → Slack
Grafana, Datadog ou n’importe quel moniteur sur mesure peuvent POST des alertes. Ne poussez que les alertes critiques vers Slack :
routes:
critical-alert:
events: ["alert"]
secret: "monitoring-webhook-secret"
filters:
- field: "severity"
equals: "critical"
prompt: |
🚨 Critical alert
Service: {service}
Metric: {metric}
Current value: {current_value}
Threshold: {threshold}
deliver: "slack"
deliver_only: true
deliver_extra:
chat_id: "your-slack-channel-id"
Slack doit être activé et connecté dans le gateway. Si vous n’utilisez Slack que pour les notifications webhook, vous n’en avez pas besoin comme plateforme de chat principale ; configurez simplement platforms.slack avec un canal d’accueil ou spécifiez le chat_id dans deliver_extra.
Avancé : filtrer et transformer les payloads avec des scripts
Si le JSON du système métier est brouillon ou que vous ne voulez notifier que sous certaines conditions, écrivez un script de pré-traitement. Les scripts doivent vivre sous ~/.hermes/scripts/ ; les chemins relatifs y sont résolus.
# ~/.hermes/scripts/alert-filter.py
import json
import sys
payload = json.load(sys.stdin)
if payload.get("severity") != "critical":
print("[SILENT]")
raise SystemExit(0)
payload["body"] = f"{payload['service']} critical: {payload['metric']}"
print(json.dumps(payload))
Référencez-le dans la route :
routes:
critical-alert:
events: ["alert"]
secret: "monitoring-webhook-secret"
script: "alert-filter.py"
prompt: "{body}"
deliver: "slack"
deliver_only: true
Un stdout JSON remplace le payload ; un stdout en texte brut est injecté comme script_output ; une sortie vide ou [SILENT] fait ignorer le webhook par Hermes.
Sécurité : ne comptez pas sur HMAC seul
HMAC prouve que l’expéditeur est de confiance, pas que le contenu du payload est sûr. Les titres de PR, les corps d’issues, les notes de commande et les messages d’alerte sont rédigés par des tiers et peuvent contenir des instructions injectées. Donc :
- Isolez l’environnement d’exécution. Si le webhook est exposé sur internet, lancez le gateway avec un backend terminal Docker ou SSH ; n’exposez pas directement l’hôte aux événements.
- Direct Delivery est intrinsèquement plus sûr. Comme il saute l’appel au LLM, il n’y a aucun risque d’injection de prompt susceptible de déclencher des actions d’agent.
- Limitez la portée des outils. Si une route doit passer en mode agent, désactivez les outils dangereux comme
terminaletfilepour cette route. - Laissez les approbations activées. Si l’agent déclenché par le webhook doit exécuter des commandes, laissez les approbations activées pour que des instructions injectées ne puissent pas s’exécuter sans supervision.
- Templez de façon ciblée. Évitez d’abuser de
{__raw__}; n’incluez danspromptque les champs dont vous avez besoin.
Hermes embarque aussi des garde-fous : 30 requêtes par minute par route par défaut, une limite de taille de corps de 1 Mo et un cache d’idempotence de 1 heure. Ces valeurs par défaut suffisent pour la plupart des notifications, mais vous pouvez les ajuster dans extra :
extra:
rate_limit: 60
max_body_bytes: 2097152
Checklist de dépannage
| Symptôme | Cause probable | Que vérifier |
|---|---|---|
| Le POST du système métier échoue | Port/pare-feu non ouvert | curl http://your-server:8644/health |
| 401 Unauthorized | Signature incorrecte | Vérifiez le secret et l’algorithme HMAC ; lisez les logs du gateway |
| 200 OK mais aucun message | Type d’événement incohérent | Vérifiez la liste events et le champ event_type |
| Messages en double | Nouvelles tentatives + idempotence manquée | Assurez-vous que l’expéditeur envoie X-Request-ID ou X-GitHub-Delivery |
| Variables du template non développées | Mauvais noms de champs | Itérez avec hermes webhook test |
Abonnements dynamiques vs routes du fichier de configuration
En plus des routes statiques dans config.yaml, vous pouvez créer des abonnements dynamiquement via le CLI :
hermes webhook subscribe order-notify \
--events "order.created" \
--prompt "New order #{order.id}, amount {order.total_price} {order.currency}" \
--deliver telegram \
--deliver-chat-id "-1001234567890" \
--deliver-only \
--description "E-commerce order notifications"
Les abonnements dynamiques sont stockés dans ~/.hermes/webhook_subscriptions.json et chargés à chaud par le gateway — aucun redémarrage requis. Les routes statiques portant le même nom ont la priorité. Pour la référence complète des commandes, consultez notre page de commande hermes webhook.
Résumé
La plateforme webhook de Hermes n’est pas un chatbot ; c’est un routeur de messages événementiel. Pour les systèmes métier, sa valeur principale est :
- Transformer le polling en push, économiser le quota API et réduire la latence.
- Centraliser les templates de message et les cibles de livraison dans Hermes, si bien que changer de plateforme de chat ou de groupe ne nécessite pas de déploiement du système métier.
- Le mode Direct Delivery pour des notifications en moins d’une seconde et zéro token.
Si vous faites déjà tourner Hermes pour vos tâches quotidiennes, ajouter un endpoint webhook est presque gratuit : le même gateway tourne déjà, il écoute juste un port de plus. Vos systèmes métier peuvent commencer à parler de manière proactive, et c’est vous qui décidez de ce qu’ils disent et où ils le disent.
Nouveau sur Hermes ? Commencez par le guide d’installation. Pour la référence complète des commandes webhook, consultez la page de commande hermes webhook. Si l’automatisation événementielle vous intéresse, lisez aussi notre guide cron orienté scripts et notre explication du mode yolo.