Skip to content

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Webhook Delivery Platform

A minimal webhook delivery platform built with Go and PostgreSQL.

It accepts events, finds subscribed webhooks, queues deliveries, and delivers them asynchronously with retries, HMAC signatures, SSRF protection, and basic observability.

Features

  • Webhook registration
  • Event subscriptions
  • Asynchronous delivery using Go workers
  • In-memory job queue
  • Retry with exponential backoff and jitter
  • Durable delivery state in PostgreSQL
  • Delivery lease and stuck-delivery recovery
  • HMAC-SHA256 webhook signatures
  • SSRF protection for webhook URLs
  • API key authentication
  • Structured delivery logs
  • Prometheus metrics
  • Minimal web UI
  • Demo subscriber for testing failures and retries

Architecture

                    ┌─────────────────┐
                    │    Web UI       │
                    └────────┬────────┘
                             │
                             ▼
                    ┌─────────────────┐
                    │    Go API       │
                    └────────┬────────┘
                             │
              ┌──────────────┴──────────────┐
              ▼                             ▼
       ┌─────────────┐               ┌─────────────┐
       │ PostgreSQL  │               │ In-Memory   │
       │             │               │ Queue       │
       └─────────────┘               └──────┬──────┘
                                            │
                                            ▼
                                     ┌─────────────┐
                                     │   Workers   │
                                     └──────┬──────┘
                                            │
                                            │ HTTP POST
                                            ▼
                                     ┌─────────────┐
                                     │  Subscriber │
                                     └─────────────┘

Delivery Flow

Create Webhook
      ↓
Create Event
      ↓
Find Subscribers
      ↓
Create Deliveries in PostgreSQL
      ↓
Queue
      ↓
Worker
      ↓
HTTP POST + HMAC Signature
      ↓
Subscriber
      ↓
Success / Retry / Failure

Requirements

  • Go 1.22+
  • PostgreSQL

Setup

Clone the repository:

git clone <repository-url>
cd webhook-platform

Create a PostgreSQL database:

CREATE DATABASE webhooks;

Create .env:

WEBHOOK_API_KEY=my-demo-key

Update the database connection if required.

Run the migrations:

psql postgres://postgres:postgres@localhost:5432/webhooks \
  -f migrations/001_init.sql

Run

Start the webhook platform:

go run .

The platform runs on:

http://localhost:8080

Open the UI:

http://localhost:8080

Start the demo subscriber in another terminal:

go run ./subscriber

The subscriber runs on:

http://localhost:9000

Demo Subscriber

The subscriber verifies the X-Webhook-Signature header and randomly returns:

200 → successful delivery
500 → retry
400 → permanent failure
timeout → retry

This makes it easy to demonstrate the delivery and retry behavior.

API

Create Webhook

POST /webhooks
X-API-Key: my-demo-key
Content-Type: application/json

Example:

{
  "url": "http://localhost:9000/webhook",
  "events": ["order.created", "order.updated"]
}

The response contains the generated webhook secret.

Create Event

POST /events
X-API-Key: my-demo-key
Content-Type: application/json

Example:

{
  "event_type": "order.created",
  "payload": {
    "order_id": "123"
  }
}

List Webhooks

GET /webhooks
X-API-Key: my-demo-key

Get Webhook

GET /webhooks/{id}
X-API-Key: my-demo-key

List Deliveries

GET /deliveries
X-API-Key: my-demo-key

Get Delivery

GET /deliveries/{id}
X-API-Key: my-demo-key

Health

GET /health

Metrics

GET /metrics

Webhook Signature

Every delivery contains:

X-Webhook-Signature: sha256=<signature>

The signature is generated using HMAC-SHA256:

HMAC-SHA256(webhook_secret, request_body)

The subscriber verifies the signature before processing the event.

Retry Behavior

Temporary failures such as:

  • HTTP 5xx
  • network errors
  • timeouts

are retried with exponential backoff and jitter.

Permanent failures such as HTTP 4xx are not retried.

A delivery can make up to 4 attempts.

Tests

Run all tests:

go test ./...

Run with the race detector:

go test -race ./...

Local Demo

The demo subscriber runs on localhost:9000.

For local development, enable:

ALLOW_LOCAL_WEBHOOKS=true

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages