Files
webhooker/README.md
clawbot 18cfedb81c
All checks were successful
check / check (push) Successful in 2m19s
feat: bring repo up to REPO_POLICIES standards
- 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
2026-03-01 08:20:51 -08:00

157 lines
5.4 KiB
Markdown

# webhooker
webhooker is a Go web application by [@sneak](https://sneak.berlin) that
receives, stores, and proxies webhooks to configured targets with retry
support, observability, and a management web UI. License: pending.
## Getting Started
```bash
# 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``dev` or `prod` (default: `dev`)
- `DEBUG` — Enable debug logging
- `PORT` — Server port (default: `8080`)
- `DBURL` — Database connection string
- `SESSION_KEY` — Base64-encoded 32-byte session key (required in prod)
- `METRICS_USERNAME` — Username for metrics endpoint
- `METRICS_PASSWORD` — Password for metrics endpoint
- `SENTRY_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 via `pkg/config` (Viper-based)
- `internal/database` — GORM database connection, migrations, and models
- `internal/globals` — Global application metadata (version, build info)
- `internal/handlers` — HTTP handlers using the closure pattern
- `internal/healthcheck` — Health check endpoint logic
- `internal/logger` — Structured logging setup (`log/slog`)
- `internal/middleware` — HTTP middleware (auth, CORS, logging, metrics)
- `internal/server` — HTTP server setup and routing
- `internal/session` — Session management (gorilla/sessions)
- `pkg/config` — Reusable multi-environment configuration library
- `static/` — 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 page
- `GET /.well-known/healthcheck.json` — Health check with uptime, version
- `GET /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).
## Author
[@sneak](https://sneak.berlin)