Back to devops
devops v1.0.0 3.4 min read 180 lines

webhook-subscriptions

이벤트 기반 에이전트 활성화를 위한 웹훅 구독 생성 및 관리

Webhook Subscriptions

Create dynamic webhook subscriptions so external services (GitHub, GitLab, Stripe, CI/CD, IoT sensors, monitoring tools) can trigger Hermes agent runs by POSTing events to a URL.

Setup (Required First)

The webhook platform must be enabled before subscriptions can be created. Check with:

hermes webhook list

If it says "Webhook platform is not enabled", set it up:

Option 1: Setup wizard


hermes gateway setup

Follow the prompts to enable webhooks, set the port, and set a global HMAC secret.

Option 2: Manual config


Add to $CONFIG_FILE:
platforms:
webhook:
enabled: true
extra:
host: "0.0.0.0"
port: 8644
secret: "generate-a-strong-secret-here"

Option 3: Environment variables


Add to $ENV_FILE:
WEBHOOK_ENABLED=true
WEBHOOK_PORT=8644
WEBHOOK_SECRET=generate-a-strong-secret-here

After configuration, start (or restart) the gateway:

hermes gateway run

Or if using systemd:


systemctl --user restart hermes-gateway

Verify it's running:

curl http://localhost:8644/health

Commands

All management is via the hermes webhook CLI command:

Create a subscription


hermes webhook subscribe  \
--prompt "Prompt template with {payload.fields}" \
--events "event1,event2" \
--description "What this does" \
--skills "skill1,skill2" \
--deliver telegram \
--deliver-chat-id "12345" \
--secret "optional-custom-secret"

Returns the webhook URL and HMAC secret. The user configures their service to POST to that URL.

List subscriptions


hermes webhook list

Remove a subscription


hermes webhook remove 

Test a subscription


hermes webhook test 
hermes webhook test --payload '{"key": "value"}'

Prompt Templates

Prompts support {dot.notation} for accessing nested payload fields:

  • {issue.title} — GitHub issue title
  • {pull_request.user.login} — PR author
  • {data.object.amount} — Stripe payment amount
  • {sensor.temperature} — IoT sensor reading

If no prompt is specified, the full JSON payload is dumped into the agent prompt.

Common Patterns

GitHub: new issues


hermes webhook subscribe github-issues \
--events "issues" \
--prompt "New GitHub issue #{issue.number}: {issue.title}\n\nAction: {action}\nAuthor: {issue.user.login}\nBody:\n{issue.body}\n\nPlease triage this issue." \
--deliver telegram \
--deliver-chat-id "-100123456789"

Then in GitHub repo Settings → Webhooks → Add webhook:

  • Payload URL: the returned webhook_url
  • Content type: application/json
  • Secret: the returned secret
  • Events: "Issues"

GitHub: PR reviews


hermes webhook subscribe github-prs \
--events "pull_request" \
--prompt "PR #{pull_request.number} {action}: {pull_request.title}\nBy: {pull_request.user.login}\nBranch: {pull_request.head.ref}\n\n{pull_request.body}" \
--skills "github-code-review" \
--deliver github_comment

Stripe: payment events


hermes webhook subscribe stripe-payments \
--events "payment_intent.succeeded,payment_intent.payment_failed" \
--prompt "Payment {data.object.status}: {data.object.amount} cents from {data.object.receipt_email}" \
--deliver telegram \
--deliver-chat-id "-100123456789"

CI/CD: build notifications


hermes webhook subscribe ci-builds \
--events "pipeline" \
--prompt "Build {object_attributes.status} on {project.name} branch {object_attributes.ref}\nCommit: {commit.message}" \
--deliver discord \
--deliver-chat-id "1234567890"

Generic monitoring alert


hermes webhook subscribe alerts \
--prompt "Alert: {alert.name}\nSeverity: {alert.severity}\nMessage: {alert.message}\n\nPlease investigate and suggest remediation." \
--deliver origin

Security

  • Each subscription gets an auto-generated HMAC-SHA256 secret (or provide your own with --secret)
  • The webhook adapter validates signatures on every incoming POST
  • Static routes from config.yaml cannot be overwritten by dynamic subscriptions
  • Subscriptions persist to webhook_subscriptions.json

How It Works

  • hermes webhook subscribe writes to webhook_subscriptions.json
  • The webhook adapter hot-reloads this file on each incoming request (mtime-gated, negligible overhead)
  • When a POST arrives matching a route, the adapter formats the prompt and triggers an agent run
  • The agent's response is delivered to the configured target (Telegram, Discord, GitHub comment, etc.)

Troubleshooting

If webhooks aren't working:

  • Is the gateway running? Check with systemctl --user status hermes-gateway or ps aux | grep gateway
  • Is the webhook server listening? curl http://localhost:8644/health should return {"status": "ok"}
  • Check gateway logs: grep webhook logs/gateway.log | tail -20
  • Signature mismatch? Verify the secret in your service matches the one from hermes webhook list. GitHub sends X-Hub-Signature-256, GitLab sends X-Gitlab-Token.
  • Firewall/NAT? The webhook URL must be reachable from the service. For local development, use a tunnel (ngrok, cloudflared).
  • Wrong event type? Check --events filter matches what the service sends. Use hermes webhook test to verify the route works.

Related Skills / 관련 스킬

local-dashboard

Hermes Agent 로컬 웹 대시보드 실행 — FastAPI 서버를 띄워 브라우저로 관리 UI 제공

neon-drizzle

Creates a fully functional Drizzle ORM setup with a provisioned Neon database. Installs dependencies, provisions database credentials, configures connections, generates schemas, and runs migrations. Use when creating new projects with Drizzle, adding ORM to existing applications, or modifying database schemas.

neon-serverless

Configures Neon Serverless Driver for Next.js, Vercel Edge Functions, AWS Lambda, and other serverless environments. Use when connecting applications to Neon, querying data, or setting up database access in edge/serverless environments.

skill-security-audit

스킬 파일 보안 감사 — 공개 전 민감 정보(DB ID, 절대경로, 시크릿 경로, 계정명 등) 검출 및 환경변수 대체