Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Webhooks

DatanoiseTV edited this page Jun 18, 2026 · 1 revision

Webhooks

Outbound HTTP notifications for stream and AutoDJ events, with templated bodies so you can match whatever shape the receiver wants. Manage from Admin → Webhooks or the JSON API at /api/webhooks (super-admin only).

SSRF guard: webhook URLs are validated against the same rules as relays — loopback, private (RFC 1918), and link-local addresses are rejected. See Security.

Events

Event Fires when Payload includes
now_playing A new track starts on an AutoDJ mount mount, name, artist, title, album, file, format, bitrate, duration_seconds
source_connect An external source connects mount
source_disconnect An external source disconnects mount
metadata_update Mount metadata (title/artist/song) changes mount, song fields
security_lockout An IP is locked out for repeated auth failures IP, reason

A webhook subscribes to one or more events via its events list.

Configuration

"webhooks": [
 {
 "name": "Discord — #now-playing",
 "url": "https://discord.com/api/webhooks/<id>/<token>",
 "method": "POST",
 "content_type": "application/json",
 "headers": { "X-Source": "tinyice" },
 "events": ["now_playing"],
 "body_template": "{\"content\": \"Now playing: {{.Artist}} - {{.Title}}\"}",
 "enabled": true
 }
]
Field Default Notes
id auto Stable handle (assigned on load if missing).
name Label in the UI.
url Target. SSRF-validated.
method POST Any HTTP method.
content_type application/json Request Content-Type.
headers Extra request headers (auth tokens, routing keys).
events Which events trigger this webhook.
body_template Go text/template. Empty = legacy JSON envelope.
enabled Per-webhook toggle.

Body templates

Leave body_template empty to send the legacy JSON envelope ({event, timestamp, hostname, data}) — existing receivers keep working unchanged. Fill it in to render any shape with Go's text/template.

For GET / HEAD webhooks the rendered body is appended to the URL as a query string instead of sent as a request body — that's how the TuneIn AIR Playing.ashx preset works from a single template.

Always-available variables

Variable Example
{{.Event}} now_playing
{{.Timestamp}} 2026年05月04日T19:30:00Z
{{.UnixTimestamp}} 1809974400
{{.Date}} · {{.Time}} 2026年05月04日 · 19:30:00
{{.Hostname}} · {{.BaseURL}} · {{.Version}} from config

When the payload carries a mount, the dispatcher derives {{.MountURL}} (public listen URL) and {{.PlayerURL}} (embedded player) from base_url. Use {{if .MountURL}}...{{end}} to no-op gracefully when base_url isn't set.

Payload variables and helpers

Every key from the event payload is promoted to the top level, in both snake_case and a CamelCase alias — {{.duration_seconds}} and {{.DurationSeconds}} both work; likewise {{.Artist}}, {{.Title}}, {{.Mount}}.

Helper functions: urlencode, json, lower, upper. Example: {{.Artist | urlencode}}.

Presets

The editor's Load preset dropdown fills method, headers, and body for: Discord, Slack, Mattermost, Microsoft Teams (MessageCard), Telegram bot sendMessage, ntfy.sh, Pushover, TuneIn AIR Playing.ashx, a generic JSON envelope, and webhook.site (echo, for debugging templates). Loading a preset leaves your URL field alone if you've already typed one.

Each row has a Test button that fires a sample payload so you can validate the template before going live.

Example: Discord "now playing"

{
 "name": "Discord — #now-playing",
 "url": "https://discord.com/api/webhooks/<channel-id>/<token>",
 "method": "POST",
 "events": ["now_playing"],
 "body_template": "{\"username\":\"TinyIce\",\"content\":\":musical_note: **{{.Mount}}** — {{.Artist}} – {{.Title}}{{if .MountURL}} — [Listen]({{.MountURL}}){{end}}\"}",
 "enabled": true
}

Prefer a local script?

For track-start specifically, the AutoDJ on_play_command hook runs a shell command with the track metadata in environment variables — no HTTP endpoint required. Webhook panics in user-supplied subscribers are contained by recover() so a bad receiver can't crash the server.


Next: HTTP API · Observability · Authentication and Users

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /