- Create cmd/webhooker/main.go with fx dependency injection wiring - Add REPO_POLICIES.md, .editorconfig, .dockerignore - Add .gitea/workflows/check.yml for CI (docker build on push) - Rewrite Makefile with all required targets (test, lint, fmt, fmt-check, check, build, hooks, docker, clean, dev, run, deps) - Rewrite Dockerfile with sha256-pinned base images, golangci-lint installed from verified release archive, make check as build step - Fix README.md: add required sections (description, getting started, rationale, design, TODO, license, author) - Integrate TODO.md content into README.md and remove TODO.md - Move config.yaml to configs/config.yaml.example - Fix .gitignore pattern for webhooker binary - Fix static/static.go embed directive (remove empty vendor dir) - Fix database test to use in-memory config (no filesystem dependency) closes #1 closes #2
5.4 KiB
webhooker
webhooker is a Go web application by @sneak that receives, stores, and proxies webhooks to configured targets with retry support, observability, and a management web UI. License: pending.
Getting Started
# Clone the repo
git clone https://git.eeqj.de/sneak/webhooker.git
cd webhooker
# Install dependencies
make deps
# Copy example config
cp configs/config.yaml.example config.yaml
# Run in development mode
make dev
# Run all checks (format, lint, test, build)
make check
# Build Docker image
make docker
Environment Variables
WEBHOOKER_ENVIRONMENT—devorprod(default:dev)DEBUG— Enable debug loggingPORT— Server port (default:8080)DBURL— Database connection stringSESSION_KEY— Base64-encoded 32-byte session key (required in prod)METRICS_USERNAME— Username for metrics endpointMETRICS_PASSWORD— Password for metrics endpointSENTRY_DSN— Sentry error reporting (optional)
Rationale
Webhook integrations between services are fragile: the receiving service must be up when the webhook fires, there is no built-in retry for most webhook senders, and there is no visibility into what was sent or when. webhooker solves this by acting as a reliable intermediary that receives webhooks, stores them, and delivers them to configured targets — with optional retries, logging, and Prometheus metrics for observability.
Use cases include:
- Store-and-forward with unlimited retries for unreliable receivers
- Prometheus/Grafana metric analysis of webhook frequency, size, and handler performance
- Introspection and debugging of webhook payloads
- Redelivery of webhook events for application testing
- Fan-out delivery of webhooks to multiple targets
- HA ingestion endpoint for delivery to less reliable systems
Design
Architecture
webhooker uses Uber's fx dependency injection library for managing
application lifecycle. It uses log/slog for structured logging, GORM
for database access, and SQLite (via modernc.org/sqlite, pure Go, no
CGO) for storage. HTTP routing uses chi.
Package Layout
All application code lives under internal/ to prevent external imports.
The main entry point is cmd/webhooker/main.go.
internal/config— Configuration management viapkg/config(Viper-based)internal/database— GORM database connection, migrations, and modelsinternal/globals— Global application metadata (version, build info)internal/handlers— HTTP handlers using the closure patterninternal/healthcheck— Health check endpoint logicinternal/logger— Structured logging setup (log/slog)internal/middleware— HTTP middleware (auth, CORS, logging, metrics)internal/server— HTTP server setup and routinginternal/session— Session management (gorilla/sessions)pkg/config— Reusable multi-environment configuration librarystatic/— Embedded static assets (CSS, JS)templates/— Go HTML templates
Data Model
- Users — Service users with username/password (Argon2id hashing)
- Processors — Webhook processing units, many-to-one with users
- Webhooks — Inbound URL endpoints feeding into processors
- Targets — Delivery destinations per processor (HTTP, retry, database, log)
- Events — Captured webhook payloads
- Deliveries — Pairing of events with targets
- Delivery Results — Outcome of each delivery attempt
- API Keys — Programmatic access credentials per user
API Endpoints
GET /— Web UI index pageGET /.well-known/healthcheck.json— Health check with uptime, versionGET /s/*— Static file serving (CSS, JS)GET /metrics— Prometheus metrics (requires basic auth)POST /webhook/{uuid}— Webhook receiver endpoint/pages/login,/pages/logout— Authentication/user/{username}— User profile/sources/*— Webhook source management
TODO
Phase 1: Security & Infrastructure
- Security headers (HSTS, CSP, X-Frame-Options)
- Rate limiting middleware
- CSRF protection for forms
- Request ID tracking through entire lifecycle
Phase 2: Authentication & Authorization
- Authentication middleware for protected routes
- Session expiration and "remember me"
- Password reset flow
- API key authentication for programmatic access
Phase 3: Core Webhook Features
- Webhook reception and event storage at
/webhook/{uuid} - Event processing and target delivery engine
- HTTP target type (fire-and-forget POST)
- Retry target type (exponential backoff)
- Database target type (store only)
- Log target type (console output)
- Webhook signature verification (GitHub, Stripe formats)
Phase 4: Web UI
- Webhook source management pages (list, create, edit, delete)
- Webhook request log viewer with filtering
- Delivery status and retry management UI
- Manual event redelivery
- Analytics dashboard (success rates, response times)
Phase 5: API
- RESTful CRUD for processors, webhooks, targets
- Event viewing and filtering endpoints
- API documentation (OpenAPI)
Future
- Email source and delivery target types
- SNS, S3, Slack delivery targets
- Data transformations (e.g. webhook-to-Slack message)
- JSONL file delivery with periodic S3 upload
License
Pending — to be determined by the author (MIT, GPL, or WTFPL).