NitroHook
NitroHook is a self-hosted webhook gateway that receives, transforms, and fans out webhook deliveries to multiple destinations — HTTP endpoints, Slack, email (SMTP), Twilio SMS, and sandboxed JavaScript handlers. Built with Go, PostgreSQL, and Redis Streams.

Features
- Multi-destination fan-out — route one incoming webhook to any combination of HTTP, Slack, SMTP, Twilio, and JavaScript actions.
- Sandboxed JS transforms — attach per-source or per-action scripts (Goja runtime, ES5+) to mutate payloads, drop events, or filter which actions fire. 500ms timeout, 64KB limit.
- Retry with exponential backoff + jitter — failed deliveries retry automatically with per-attempt tracking.
- HMAC-SHA256 signing — outbound deliveries are signed so downstream consumers can verify authenticity.
- Record mode — capture incoming webhooks without dispatching, then replay on demand.
- Prometheus metrics — ingest latency, dispatch duration, pending queue depth, and retry backlog exposed on
/metrics.
Monaco-powered script editor with inline testing against recorded payloads.
Architecture
Two cooperating processes backed by PostgreSQL and Redis:
- API server — receives incoming webhooks at
POST /webhooks/:sourceSlug, persists the payload + headers, and publishes a delivery ID to a Redis Stream. Also serves the web UI, REST API, and Prometheus metrics. - Fan-out worker — pool of consumers reads from the Redis Stream consumer group, resolves the source’s active actions, runs transform scripts, and dispatches through a pluggable dispatcher registry. Failed attempts schedule retries; a background poller sweeps retryable attempts and pending deliveries as a catch-up mechanism.
A delivery is marked completed only when every action succeeds or exhausts its retries.
Per-source action list — toggle active/inactive inline, add webhooks/Slack/SMTP/Twilio/JS handlers.
Event log — every incoming webhook with its status, idempotency key, and receive time.
Drill into an event to see headers, payload, and per-attempt HTTP status for every fan-out action.
Tech Stack
- Language: Go 1.24
- HTTP framework: Gin
- Database: PostgreSQL 18 (pgx driver, golang-migrate for schema management)
- Queue: Redis 8 Streams (consumer groups for competing workers)
- JS engine: Goja (ES5+ sandbox)
- Metrics: Prometheus client
- Packaging: Docker, Docker Compose, Helm chart for Kubernetes
- CI/CD: GitHub Actions → GHCR