Sign inSign up

baz1536/hookrel

By baz1536

•Updated 15 days ago

Self-hosted webhook relay — receive events, match rules, and dispatch notifications.

Image
Networking
Integration & delivery
Internet of things
0

2.6K

baz1536/hookrel repository overview

⁠HookRel

Webhooks in. Notifications out.

HookRel is a self-hosted webhook relay. It receives webhook events from your applications, matches them against your rules, formats them using templates, and dispatches notifications to your chosen providers — all without writing a single line of code.

Your App  →  HookRel  →  Rules  →  Message Template  →  Provider

⁠Features

  • Multiple providers — SMTP, Microsoft 365, Teams, Telegram, Pushover, Slack, Discord, Gotify, ntfy
  • Rich message templates — HTML editor with formatting, tables, and colour for email; plain text for Telegram and Pushover
  • Pre-built source catalogue — Sonarr, Radarr, Prowlarr, Seerr, Tautulli, Plex, Jellyfin, Uptime Kuma, and more
  • Live token learning — Custom sources automatically discover available tokens from real payloads
  • Flexible rules — Match by source, event type, or payload conditions; fire all matching rules or just the first
  • Dual database — SQLite (zero setup, default) or MongoDB
  • Credential encryption — Provider secrets encrypted at rest using AES-256-GCM
  • Multi-user — Admin and read-only roles with session authentication

⁠Quick Start

services:
  hookrel:
    image: baz1536/hookrel:latest
    container_name: hookrel
    restart: unless-stopped
    ports:
      - "3551:3551"
    environment:
      PORT: 3551
      NODE_ENV: production
      PUBLIC_URL: http://your-server-ip:3551
      DB_TYPE: sqlite
      DB_PATH: /app/data/hookrel.db
      AUTH_ENABLED: "true"
      ENCRYPTION_KEY: "replace_with_64_hex_chars"
      SESSION_SECRET: "replace_with_64_hex_chars"
    volumes:
      - hookrel_data:/app/data
      - hookrel_logs:/app/logs

volumes:
  hookrel_data:
  hookrel_logs:

Then open http://your-server-ip:3551 — you'll be prompted to create an admin account on first launch.

⁠Generate secrets
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Run twice — once for ENCRYPTION_KEY, once for SESSION_SECRET.


⁠Environment Variables

VariableDefaultDescription
PORT3551Port the server listens on
NODE_ENVproductionNode environment
PUBLIC_URL(none)Public-facing base URL — used to build webhook URLs shown in the UI
DB_TYPEsqliteDatabase backend — sqlite or mongodb
DB_PATH./data/hookrel.dbSQLite file path, or full MongoDB connection URI
AUTH_ENABLEDtrueSet to false to bypass login (trusted network only)
ENCRYPTION_KEY(required)64-char hex string — encrypts provider credentials at rest
SESSION_SECRET(required)64-char hex string — signs session cookies
LOG_LEVELinfoLog verbosity — error, warn, info, debug
LOG_DIR./logsDirectory for daily rotating log files
TZ(system)Timezone (e.g. Europe/London)
HTTPS_PROXY(none)Proxy for outbound HTTPS (Telegram, Pushover, MS Graph, email)
HTTP_PROXY(none)Proxy for outbound HTTP
NO_PROXY(none)Comma-separated hosts/CIDRs to bypass the proxy

Important: ENCRYPTION_KEY and SESSION_SECRET should be long, random strings. Generate with:

openssl rand -hex 32

If ENCRYPTION_KEY changes, existing provider credentials will no longer decrypt and must be re-entered.


⁠Volumes

PathDescription
/app/dataDatabase and configuration — mount this to persist your data
/app/logsDaily rotating log files

⁠Supported Providers

ProviderFormat
SMTPHTML or plain text
Microsoft 365HTML or plain text (via Microsoft Graph API)
Microsoft TeamsPlain text
TelegramPlain text
PushoverPlain text
SlackPlain text
DiscordPlain text
GotifyPlain text
ntfyPlain text

⁠Supported Webhook Sources

SourceKnown events
SonarrGrab, Download, Rename, SeriesAdd, Health, and more
RadarrGrab, Download, Rename, MovieAdded, Health, and more
Plexmedia.play, media.pause, media.stop, library.new, and more
JellyfinItemAdded, PlaybackStart, PlaybackStop, UserCreated, and more
ProwlarrHealth, ApplicationUpdate
Seerr / OverseerrMedia pending/approved/available, issue events
Tautulliplay, stop, pause, resume, watched, recently_added
Uptime KumaMonitor down / up
CustomAny app — tokens learned automatically from live payloads

⁠Docker Compose with MongoDB

services:
  hookrel:
    image: baz1536/hookrel:latest
    container_name: hookrel
    restart: unless-stopped
    ports:
      - "3551:3551"
    environment:
      PORT: 3551
      NODE_ENV: production
      PUBLIC_URL: http://your-server-ip:3551
      DB_TYPE: mongodb
      DB_PATH: mongodb://hookrel:yourpassword@mongodb:27017/hookrel?authSource=admin
      AUTH_ENABLED: "true"
      ENCRYPTION_KEY: "replace_with_64_hex_chars"
      SESSION_SECRET: "replace_with_64_hex_chars"
    volumes:
      - hookrel_logs:/app/logs

  mongodb:
    image: mongo:8.2.7
    container_name: mongodb
    restart: unless-stopped
    environment:
      MONGO_INITDB_ROOT_USERNAME: hookrel
      MONGO_INITDB_ROOT_PASSWORD: yourpassword
    volumes:
      - mongodb_data:/data/db

volumes:
  hookrel_logs:
  mongodb_data:

⁠Webhook Authentication

Each source gets a unique URL and bearer token. Configure your application to POST to:

POST https://your-hookrel-url/webhook/<slug>

With either:

Authorization: Bearer <token>

or:

X-API-Key: <token>

Note: Plex webhooks are sent as multipart/form-data (Plex Pass required). HookRel handles this automatically.


⁠Behind a Reverse Proxy

Set PUBLIC_URL to your external domain so webhook URLs in the UI are correct:

PUBLIC_URL=https://hookrel.example.com

⁠Source

https://github.com/baz1536/hookrel⁠


⁠License

MIT — Copyright © 2026 dBR Promotions

Tag summary

Content type

Image

Digest

sha256:6b89df5b6…

Size

93.2 MB

Last updated

15 days ago

docker pull baz1536/hookrel