Conecte Webhooks do Hermes: Deixe Seus Sistemas de Negócio Enviarem Alertas para Telegram, Discord e Slack

A maioria dos sistemas de negócio acaba precisando da mesma automação: quando o status de um pedido muda, um pagamento é aprovado, um monitor dispara ou um pipeline de CI termina, publicar uma mensagem no canal da equipe. A primeira versão mais rápida costuma ser um script que faz polling em um banco de dados ou API e depois envia a mensagem para o Telegram, Discord, Slack ou outra plataforma de chat.
Polling funciona, mas tem custos reais de longo prazo:
- Latência e cota de API. Escanear a cada minuto significa que a maioria das requisições não retorna nada; passar para polling em nível de segundos multiplica a pressão sobre a API e os custos.
- Acoplamento. O sistema de negócio acaba com templates de mensagem e tokens de plataformas de chat hard-coded. Trocar de canal ou grupo exige mudança de código.
- Extensibilidade. O mesmo alerta pode precisar ir para o Telegram, o Slack, ou ser resumido por uma IA primeiro. Scripts de polling crescem em complexidade rapidamente.
O Hermes Agent vem com uma plataforma de webhooks — um receptor de eventos HTTP. Seu sistema de negócio faz um POST de um evento, o Hermes valida a assinatura, renderiza um template e envia a mensagem para a plataforma de chat que você configurou. Se o evento for uma notificação pura que não precisa de raciocínio de IA, você pode ativar o modo Direct Delivery: sem chamada de LLM, sem loop de agente, entrega em menos de um segundo e custo zero de tokens.
Este post é um guia prático para conectar sistemas de negócio aos webhooks do Hermes: habilitar a plataforma, configurar rotas, três cenários reais completos e endurecimento de segurança.
Dois modos: processamento por agente vs. Direct Delivery
Os webhooks do Hermes suportam dois caminhos de entrega. Escolher o certo importa.
| Modo | Chama LLM? | Melhor para | Latência | Custo |
|---|---|---|---|---|
| Processamento por agente | Sim | Eventos que precisam de compreensão, resumo ou uma decisão antes de responder/encaminhar | Segundos | Custo de tokens |
| Direct Delivery | Não | Notificações puras: pedidos, pagamentos, alertas, status de CI | Menos de um segundo | Custo zero de LLM |
O Direct Delivery é o foco aqui. O fluxo é simples:
- O sistema de negócio assina e faz um POST de um payload JSON para
https://your-server:8644/webhooks/<route-name>. - O Hermes valida a assinatura HMAC para confirmar que o remetente é confiável.
- Um template renderiza os campos do JSON em uma mensagem legível.
- A mensagem é entregue diretamente ao Telegram, Discord, Slack, Feishu, etc., e o Hermes retorna
200 OK.
Nenhum LLM está envolvido, então velocidade, custo e confiabilidade ficam mais próximos de um gateway de mensagens tradicional — mas a configuração e a extensibilidade continuam tão flexíveis quanto o resto do Hermes.
Passo 1: Habilite a plataforma de webhooks
Você pode habilitar webhooks via variáveis de ambiente para um início rápido ou via config.yaml para implantações de longo prazo.
Variáveis de ambiente (mais rápido)
Adicione estas linhas ao ~/.hermes/.env:
WEBHOOK_ENABLED=true
WEBHOOK_PORT=8644 # default
WEBHOOK_SECRET=your-global-secret
Reinicie o gateway:
hermes gateway restart
Confirme que o servidor está escutando:
curl http://localhost:8644/health
Uma resposta {"status": "ok", "platform": "webhook"} significa que está no ar.
Arquivo de configuração (recomendado para produção)
Declare o bloco platforms.webhook no ~/.hermes/config.yaml:
platforms:
webhook:
enabled: true
extra:
port: 8644
secret: "your-global-secret"
Após reiniciar o gateway, o Hermes escuta na porta 8644. Se o servidor estiver na internet pública, certifique-se de que o firewall permite essa porta. Se estiver atrás de NAT ou sem IP público, exponha-o com um Cloudflare Tunnel ou ngrok.
Passo 2: Configure uma rota de notificação de negócio
As rotas ficam em platforms.webhook.extra.routes. Cada rota tem um nome, filtro de eventos, secret, template de mensagem e destino de entrega. Abaixo está um exemplo completo de notificação de pedidos de e-commerce que envia novos pedidos para o 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"
Pontos-chave:
eventsé opcional. Se o seu sistema de negócio envia um tipo de evento viaX-Webhook-Eventouevent_type, você pode restringir a rota aorder.created.secreté usado para validação da assinatura HMAC. Se a rota não tiver secret, ela recai nosecretglobal.deliver_only: trueativa o Direct Delivery e pula o LLM.prompté um template. Use notação de ponto como{order.total_price}para acessar campos do JSON.{__raw__}despeja o payload inteiro.deliver_extra.chat_idaponta para um grupo específico. Se omitido, o Hermes entrega para o canal doméstico configurado da plataforma (o que exige que essa plataforma esteja habilitada e conectada).
Passo 3: Envie eventos do seu sistema de negócio
Seu sistema de negócio faz um POST para a URL correta. Para o exemplo acima:
POST https://your-server:8644/webhooks/order-notify
Use a assinatura Generic V2: concatene timestamp.body, calcule o HMAC-SHA256 e envie-o no header X-Webhook-Signature-V2 junto com X-Webhook-Timestamp. A janela de timestamp é de ±300 segundos, o que bloqueia ataques de replay.
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,
}
)
As assinaturas do GitHub e do GitLab também são detectadas automaticamente. Para sistemas de negócio customizados, prefira a Generic V2.
Passo 4: Teste a rota
Você não precisa esperar o sistema de negócio entrar em produção. Teste localmente primeiro:
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 simula um POST para que você possa verificar a renderização do template e a entrega. Se a mensagem não chegar, verifique o gateway.log ou execute hermes gateway run em primeiro plano para ver se a assinatura falhou, o evento foi filtrado ou o destino de entrega não está conectado.
Cenário 1: Notificações de pedidos de e-commerce → Telegram
O exemplo order-notify acima já está completo. Alguns detalhes que valem destaque:
- Os valores de
chat_idde grupos do Telegram costumam ser negativos e começam com-100. - Para apontar para um tópico específico do fórum, adicione
message_thread_id: "42"emdeliver_extra. {order.line_items[0].title}mostra apenas o primeiro item. Para listar tudo, pré-processe o payload no sistema de negócio ou use o modo agente com{__raw__}e deixe o LLM resumir.
Cenário 2: Pagamento aprovado → Discord
Sistemas de pagamento como o Stripe já emitem webhooks. Mapeie o evento de sucesso do Stripe para uma mensagem no 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"
O Stripe envia type em vez de event_type. Se o Hermes não reconhecer o header de evento, envolva o payload no seu sistema de negócio ou deixe events vazio e use filters:
routes:
payment-success:
secret: "stripe-webhook-secret"
filters:
- field: "type"
equals: "payment_intent.succeeded"
prompt: "..."
deliver: "discord"
deliver_only: true
Cenário 3: Alertas de monitoramento → Slack
O Grafana, o Datadog ou qualquer monitor customizado podem fazer um POST de alertas. Envie apenas alertas críticos para o 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"
O Slack deve estar habilitado e conectado no gateway. Se você usa o Slack apenas para notificações de webhook, não precisa dele como sua plataforma de chat principal; basta configurar platforms.slack com um canal doméstico ou especificar o chat_id em deliver_extra.
Avançado: filtre e transforme payloads com scripts
Se o JSON do sistema de negócio for bagunçado ou você quiser notificar apenas sob condições específicas, escreva um script de pré-processamento. Os scripts devem ficar em ~/.hermes/scripts/; caminhos relativos são resolvidos ali.
# ~/.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))
Referencie-o na rota:
routes:
critical-alert:
events: ["alert"]
secret: "monitoring-webhook-secret"
script: "alert-filter.py"
prompt: "{body}"
deliver: "slack"
deliver_only: true
O stdout em JSON substitui o payload; o stdout em texto puro é injetado como script_output; saída vazia ou [SILENT] faz o Hermes ignorar o webhook.
Segurança: não confie apenas no HMAC
O HMAC prova que o remetente é confiável, não que o conteúdo do payload é seguro. Títulos de PRs, corpos de issues, notas de pedidos e mensagens de alerta são escritos por terceiros e podem conter instruções injetadas. Então:
- Isole o runtime. Se o webhook estiver exposto à internet, execute o gateway com um backend de terminal Docker ou SSH; não exponha o host diretamente a eventos.
- Direct Delivery é inerentemente mais seguro. Como ele pula o LLM, não há risco de prompt injection que possa disparar ações do agente.
- Escopelize o conjunto de ferramentas. Se uma rota precisar entrar em modo agente, desabilite ferramentas perigosas como
terminalefilepara essa rota. - Mantenha as aprovações ativas. Se o agente acionado por webhook precisar executar comandos, deixe as aprovações habilitadas para que instruções injetadas não possam ser executadas sem supervisão.
- Faça templates estreitos. Evite abusar de
{__raw__}; inclua apenas os campos de que você precisa noprompt.
O Hermes também vem com salvaguardas: 30 requisições por minuto por rota por padrão, um limite de tamanho de corpo de 1 MB e um cache de idempotência de 1 hora. Esses padrões são suficientes para a maioria das notificações, mas você pode ajustá-los em extra:
extra:
rate_limit: 60
max_body_bytes: 2097152
Checklist de solução de problemas
| Sintoma | Causa provável | O que verificar |
|---|---|---|
| O POST do sistema de negócio falha | Porta/firewall não abertos | curl http://your-server:8644/health |
| 401 Unauthorized | Assinatura incompatível | Verifique o secret e o algoritmo HMAC; leia os logs do gateway |
| 200 OK mas sem mensagem | Tipo de evento incompatível | Verifique a lista de events e o campo event_type |
| Mensagens duplicadas | Retries + falha de idempotência | Garanta que o remetente envie X-Request-ID ou X-GitHub-Delivery |
| Variáveis do template não expandidas | Nomes de campo errados | Itere com hermes webhook test |
Assinaturas dinâmicas vs. rotas no arquivo de configuração
Além das rotas estáticas no config.yaml, você pode criar assinaturas dinamicamente via 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"
As assinaturas dinâmicas são armazenadas em ~/.hermes/webhook_subscriptions.json e recarregadas a quente pelo gateway — sem necessidade de reinício. Rotas estáticas com o mesmo nome têm precedência. Para a referência completa de comandos, veja nossa página de comando hermes webhook.
Resumo
A plataforma de webhooks do Hermes não é um chatbot; é um roteador de mensagens orientado a eventos. Para sistemas de negócio, seu principal valor é:
- Transformar polling em push, economizando cota de API e cortando latência.
- Centralizar templates de mensagem e destinos de entrega no Hermes, de modo que mudar de plataforma de chat ou grupo não exija um deploy do sistema de negócio.
- O modo Direct Delivery para notificações com custo zero de tokens e entrega em menos de um segundo.
Se você já roda o Hermes para tarefas diárias, adicionar um endpoint de webhook é quase de graça: o mesmo gateway já está em execução, ele só passa a escutar mais uma porta. Seus sistemas de negócio podem começar a falar proativamente, e você decide o que eles dizem e onde dizem.
Novo no Hermes? Comece com o guia de instalação. Para a referência completa de comandos de webhook, veja a página de comando hermes webhook. Se você se interessa por automação orientada a eventos, leia também nosso guia de cron apenas com scripts e o explicador do modo yolo.