Billy D. 1c1a9cc35f
Some checks failed
CI / Lint (push) Successful in 58s
CI / Test (push) Successful in 1m15s
CI / Release (push) Successful in 6s
CI / Docker Build & Push (push) Failing after 23s
CI / Notify (push) Successful in 1s
fix: add golangci-lint config and fix all lint errors
- Add .golangci.yml with v2 config (errcheck, govet, staticcheck, misspell, etc.)
- Fix 32 errcheck issues across config, discord, ntfy, server packages
- Fix misspelling: cancelled → canceled
- Fix staticcheck: use append(slice...) instead of loop
- Fix staticcheck: remove empty error branch
- Use t.Setenv instead of os.Setenv/Unsetenv in tests
- Update CI workflow: add lint job, release tagging, ntfy notifications
2026-02-14 09:15:01 -05:00
2026-02-02 22:46:49 +00:00

ntfy-discord

A lightweight Go bridge that forwards ntfy notifications to Discord webhooks.

Features

  • SSE Subscription: Real-time message streaming from ntfy
  • Auto-reconnection: Exponential backoff on connection failures
  • Hot Reload: Watches mounted secrets for changes (no pod restart needed)
  • Native Vault Support: Direct HashiCorp Vault integration with Kubernetes auth
  • Message Transformation: Converts ntfy format to Discord embeds
  • Priority Mapping: ntfy priorities → Discord embed colors
  • Tag → Emoji: Converts common ntfy tags to Discord-friendly emojis
  • Prometheus Metrics: /metrics endpoint for observability
  • Tiny Footprint: ~10MB image, 16-32MB memory

Configuration

Core Settings

Environment Variable Description Default
NTFY_URL ntfy server URL http://ntfy.observability.svc.cluster.local
NTFY_TOPICS Comma-separated topics to subscribe to (required)
HTTP_PORT Port for health/metrics endpoints 8080
LOG_LEVEL Log level (info or debug) info

Secret Sources (Priority Order)

The bridge loads the Discord webhook URL from the first available source:

  1. Vault (if VAULT_ENABLED=true)
  2. Mounted Secret (if SECRETS_PATH is set)
  3. Environment Variable (DISCORD_WEBHOOK_URL)

Vault Configuration

Environment Variable Description Default
VAULT_ENABLED Enable Vault integration false
VAULT_ADDR Vault server address http://vault.vault.svc.cluster.local:8200
VAULT_AUTH_METHOD Auth method: kubernetes or token kubernetes
VAULT_ROLE Vault role for Kubernetes auth ntfy-discord
VAULT_MOUNT_PATH Secrets engine mount path secret
VAULT_SECRET_PATH Path within the mount ntfy-discord
VAULT_TOKEN_PATH SA token path (for K8s auth) /var/run/secrets/kubernetes.io/serviceaccount/token

Expected Vault secret structure (KV v2):

secret/data/ntfy-discord
├── webhook-url: https://discord.com/api/webhooks/...

File-Based Secrets

Environment Variable Description Default
SECRETS_PATH Path to mounted secrets directory (optional)
DISCORD_WEBHOOK_URL Discord webhook URL (fallback) (optional)

When using SECRETS_PATH, the bridge expects:

  • webhook-url - Discord webhook URL

The bridge watches for file changes and reloads automatically.

Endpoints

Path Description
/health Health check (webhook configured?)
/ready Readiness check (connected to ntfy?)
/metrics Prometheus metrics

Priority → Color Mapping

Priority Name Color
5 Max/Urgent 🔴 Red
4 High 🟠 Orange
3 Default 🔵 Blue
2 Low Gray
1 Min Light Gray

Building

# Build binary
go build -o ntfy-discord .

# Build container
docker build -t ntfy-discord .

Kubernetes Deployment

See homelab-k8s2 for deployment manifests.

License

MIT

Description
No description provided
Readme MIT 93 KiB
Languages
Go 98.9%
Dockerfile 1.1%