haiven-notification-hub

Unified notification dispatcher for Haiven agent services. Accepts a structured notification payload and routes it to one or more delivery channels (email, ntfy push, Home Assistant TTS) based on a YAML routing table keyed by source agent.

API Endpoints

POST /notify

Accept a notification and dispatch it to resolved channels.

Request

{
  "source_agent": "haiven-agent-briefing",
  "priority": "normal",
  "title": "Daily Briefing",
  "body": "Markdown body text...",
  "channels": [],
  "metadata": {}
}
Field Type Default Description
source_agent string required Agent identifier used to look up routes (e.g. briefing, research)
title string required Notification title
body string required Notification body (markdown)
priority string "normal" low | normal | high | urgent
channels list[string] [] Explicit channel override — bypasses route table when non-empty
metadata dict {} Arbitrary key/value pairs forwarded to channels

Response

{
  "notification_id": "550e8400-e29b-41d4-a716-446655440000",
  "channels_dispatched": ["email", "ntfy"],
  "status": "ok"
}
Status Meaning
ok All resolved channels succeeded
partial At least one channel succeeded, at least one failed
failed No channels succeeded

Channel resolution order

  1. channels field (explicit override) if non-empty
  2. Routes table entry for source_agent
  3. default route entry
  4. Hard fallback: ["email"]

GET /health

Liveness probe. Returns 200 when the process is running.

{"status": "ok"}

Supported Channels

Channel Description Required Config
email SMTP delivery via smtp-relay HUB_SMTP_HOST, HUB_SMTP_TO
ntfy Push notification via ntfy.sh HUB_NTFY_URL
ha_tts Home Assistant TTS announcement via webhook HUB_HA_WEBHOOK_URL

Routing Configuration

Routes are defined in a YAML file mounted at /etc/haiven/notification-routes.yaml (host path: /mnt/storage/notification-hub/routes/).

routes:
  briefing: ["email", "ntfy"]
  research: ["email"]
  eod: ["email", "ntfy"]
  default: ["email"]

The file is loaded once at startup. If missing or malformed, the service falls back to default: ["email"] and continues — it does not fail to start.

Configuration

Variable Default Description
HUB_SMTP_HOST smtp-relay SMTP relay hostname
HUB_SMTP_PORT 25 SMTP port
HUB_SMTP_FROM haiven@haiven.site From address
HUB_SMTP_TO "" Recipient address (required for email delivery)
HUB_NTFY_URL "" ntfy.sh endpoint URL
HUB_NTFY_TOPIC haiven ntfy topic name
HUB_HA_WEBHOOK_URL "" Home Assistant webhook URL for TTS
HUB_ROUTES_FILE /etc/haiven/notification-routes.yaml Path to routes config

Deployment

cd /mnt/apps/docker/ai/notification-hub
docker compose up -d

Manual test:

curl -sf -X POST http://localhost:8040/notify \
  -H "Content-Type: application/json" \
  -d '{"source_agent": "test", "title": "Test", "body": "Hello from hub", "priority": "normal"}'