Hooker
Webhook relay proxy that forwards incoming webhooks from a public VPS to your local development machine. Built with Go, gRPC bidirectional streaming, and a rich terminal UI.
Architecture
Partner/Provider ──HTTP POST──▶ hooker-server (VPS, public IP)
│
gRPC bidirectional stream
│
hooker CLI (localhost)
│
──HTTP replay──▶ Local App
The CLI agent initiates an outbound gRPC connection to the server -- no inbound ports needed on your local machine. The server pushes webhooks through the persistent stream. In sync mode, the CLI relays your local app's response back to the original caller.
Quick Start
1. Deploy the server on your VPS
# Create a directory on your VPS
mkdir ~/hooker && cd ~/hooker
# Grab the deploy files
curl -sO https://raw.githubusercontent.com/1slam10/hooker/main/deploy/docker-compose.yaml
curl -sO https://raw.githubusercontent.com/1slam10/hooker/main/deploy/config.yaml
# Edit config.yaml -- set real tokens for each endpoint
# Generate tokens with: openssl rand -hex 32
nano config.yaml
# Start
docker compose up -d
2. Connect from your local machine
# Install the CLI
go install github.com/1slam10/hooker/cmd/hooker@latest
# Connect and forward webhooks to your local app
hooker connect \
--server your-vps.com:9000 \
--token <token-from-config.yaml> \
--forward http://localhost:8080
3. Give partners the webhook URL
Tell your partners to send webhooks to:
https://your-vps.com/hooks/kaspi/callback
They'll arrive in your TUI and be forwarded to http://localhost:8080/callback.
TUI
The CLI features a full terminal interface for inspecting webhooks:
- Left panel: scrollable list of received webhooks with method, path, and status
- Right panel: full request/response detail with pretty-printed JSON
- Navigation:
j/k or arrow keys, Tab to switch panels, / to filter
- Color-coded: green (2xx), yellow (4xx), red (5xx)
Configuration
Server (config.yaml)
All configuration lives in a single config.yaml. Tokens go directly in the file -- no .env needed.
server:
http:
addr: ":8080"
read_timeout: 30s
write_timeout: 60s
idle_timeout: 120s
max_body_size: "10MB"
grpc:
addr: ":9000"
keepalive_time: 30s
keepalive_timeout: 10s
tls:
enabled: false
cert_file: ""
key_file: ""
log:
level: "info" # debug | info | warn | error
format: "json" # json | text
endpoints:
- id: "kaspi"
path_prefix: "/hooks/kaspi"
token: "your-generated-secret" # openssl rand -hex 32
mode: "async"
- id: "stripe"
path_prefix: "/hooks/stripe"
token: "another-generated-secret"
mode: "sync"
sync_timeout: 30s
max_body_size: "5MB"
Every field has a sensible default. A minimal config:
endpoints:
- id: "kaspi"
path_prefix: "/hooks/kaspi"
token: "my-secret"
Client flags
hooker connect [flags]
Flags:
-s, --server string server gRPC address (env: HOOKER_SERVER) (default "localhost:9000")
-t, --token string auth token (env: HOOKER_TOKEN)
-f, --forward string local target URL (env: HOOKER_FORWARD) (default "http://localhost:8080")
--tls use TLS for gRPC
--reconnect-interval duration initial reconnect interval (default 2s)
--max-reconnect-interval duration max reconnect interval (default 1m0s)
--forward-timeout duration timeout for local forwarding (default 30s)
Endpoint Modes
Async (default)
Server returns 200 OK immediately to the partner and forwards the webhook to the CLI in the background. Suitable for most webhook integrations.
Sync
Server holds the partner's HTTP connection open, forwards the webhook to the CLI, waits for the local app's response, and relays it back. Useful for challenge/verification callbacks.
Building
make build # build both binaries to bin/
make build-server # server only
make build-cli # CLI only
make release # cross-compile CLI for all platforms to dist/
make gen # regenerate protobuf (requires buf)
make lint # run golangci-lint
Docker
The image is automatically built and pushed to ghcr.io/1slam10/hooker on every push to main.
# On your VPS -- pull latest and restart
docker compose pull && docker compose up -d
# Or build locally
make docker
make up
make down
Health Check
curl http://your-vps.com:8080/healthz
# {"status":"ok"}
Development
Prerequisites
- Go 1.23+
- buf for protobuf generation
Regenerating protobuf
make gen
This runs buf generate which produces Go code in gen/proto/.