Channels
/jabali-admin/notifications/channels. Configure the delivery endpoints that notification events fan out to (M14).
Available channels
| Channel | Configuration |
|---|---|
| In-app | Always on. Renders as a bell-dropdown indicator in the panel header. |
SMTP submission via the panel’s own Stalwart instance; uses mail-recovery-sender@<panel-hostname> as From by default. |
|
| Slack | Incoming-webhook URL. |
| Telegram | Bot token plus chat ID. |
| ntfy.sh | Topic URL (works against the public ntfy.sh or a self-hosted ntfy server). |
| Web Push | VAPID public/private keys; users subscribe per browser via the bell dropdown. |
Per-channel test
Each row has a Send test button that emits a synthetic event through the channel. Receiving a test confirms the credentials and connectivity end-to-end.
Enabling and disabling
A channel may be globally enabled or disabled. A disabled channel skips dispatch even if a routing rule targets it; the queue depth does not grow because skipped channels are dropped at producer time.
Per-user opt-in
Tenants opt-in to receive certain notifications about their own account (cron failures, backup results, mail quarantine) via Profile → Notifications. The channel must be enabled here at the server level before any tenant may opt-in to it.
Web Push keys
VAPID keys are auto-generated by the installer. Rotating the keys (button on the Web Push row) invalidates every active subscription; users must re-subscribe from the bell dropdown.
Architecture
Producers emit a row into Redis Streams jabali:notifications. The in-process dispatcher (single consumer per panel instance) reads the stream, consults Routing, and calls each enabled sender. Each sender is a Go file under panel-api/internal/notifications/senders/.
ADR-0056 covers the data model; ADRs 0057–0059 cover the sender interface, Web Push, and the bell dropdown.