You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(readme): document webhooks v2, on_play_command and now_playing event
Adds a dedicated Webhooks section between HTTP API and Admin UI with
the event list, always-available template variables, helper funcs,
preset roster, and a Discord example. Also bumps the AutoDJ admin-UI
bullet to mention on_play_command and the Admin UI list to mention
the new Webhooks page. A new collapsible block at the top of "What's
new" summarises the changes (clearly marked as on-main / post-beta.9).
- New **`now_playing`** event fires once per track on every AutoDJ mount, alongside the existing `source_connect` / `source_disconnect` / `metadata_update` / `security_lockout` events.
80
+
-**Templated webhook bodies** with Go `text/template` syntax. Empty template falls back to the legacy JSON envelope so existing receivers keep working unchanged.
81
+
-**Per-webhook HTTP method, Content-Type, custom headers**, and a free-form body template. For `GET` / `HEAD` the rendered body is appended as a query string — that's how the TuneIn AIR `Playing.ashx` preset works from a single template.
82
+
-**Always-available variables**: `{{.Event}}`, `{{.Timestamp}}`, `{{.UnixTimestamp}}`, `{{.Date}}`, `{{.Time}}`, `{{.Hostname}}`, `{{.BaseURL}}`, `{{.Version}}`. When the event payload carries a mount, `{{.MountURL}}` and `{{.PlayerURL}}` are derived from `base_url`. Helper funcs: `urlencode`, `json`, `lower`, `upper`.
83
+
-**Presets** for Discord, Slack, Mattermost, Microsoft Teams, Telegram, ntfy.sh, Pushover, TuneIn AIR `Playing.ashx`, generic JSON envelope, and webhook.site (for debugging templates).
84
+
-**Admin UI**: dedicated `/admin/webhooks` page with add / edit / delete, per-row Test button (fires a sample payload), preset dropdown, click-to-insert placeholder helper.
85
+
-**AutoDJ `on_play_command`**: shell hook executed at track-start with `TINYICE_ARTIST` / `TINYICE_TITLE` / `TINYICE_ALBUM` / `TINYICE_FILE` / `TINYICE_MOUNT` env vars, for integrations that prefer a script over an HTTP endpoint.
@@ -371,16 +386,100 @@ equivalent. See `/api/docs` for the full list.
371
386
372
387
---
373
388
389
+
## Webhooks
390
+
391
+
Outbound HTTP notifications for stream and AutoDJ events. Manage from
392
+
**Admin → Webhooks** or via the JSON API at `/api/webhooks` (super-admin
393
+
only). URLs are validated against the same SSRF guard as relays —
394
+
loopback, private and link-local addresses are rejected.
395
+
396
+
### Events
397
+
398
+
| Event | Fired when |
399
+
|---|---|
400
+
|`now_playing`| A new track starts on an AutoDJ mount. Carries `mount`, `name`, `artist`, `title`, `album`, `file`, `format`, `bitrate`, `duration_seconds`. |
401
+
|`source_connect`| An external source (broadcaster) connects to a mount. |
402
+
|`source_disconnect`| An external source disconnects from a mount. |
403
+
|`metadata_update`| Mount metadata (title / artist / song) changes. |
404
+
|`security_lockout`| An IP is locked out for repeated auth failures. |
405
+
406
+
### Body templates
407
+
408
+
Webhooks have an optional `body_template` rendered with Go's
409
+
`text/template` syntax. Leaving it empty sends the legacy JSON envelope
410
+
(`{event, timestamp, hostname, data}`). Filling it in lets you match
411
+
whatever shape the receiver wants.
412
+
413
+
**Always-available variables** (every event, every template):
0 commit comments