diff --git a/README.md b/README.md index 6d902e8..75a8636 100644 --- a/README.md +++ b/README.md @@ -39,10 +39,14 @@ Full documentation: [`docs/api.md`](docs/api.md) | `/shows` | GET | -- | List all shows (paginated) | | `/shows/by-episode/{episode_number}` | GET | -- | Look up show by episode number | | `/shows/{show_id}` | GET | -- | Specific show by internal ID | +| `/login` | GET/POST | -- | Login page | +| `/logout` | GET | Session | Clear session | +| `/dashboard` | GET | Session | Live playlist dashboard | | `/admin/refresh` | POST | Bearer | Trigger immediate SoundCloud fetch | | `/admin/tracks` | POST | Bearer | Add track to current show | | `/admin/tracks/{track_id}` | DELETE | Bearer | Remove track from current show | | `/admin/tracks/{track_id}/position` | PUT | Bearer | Move track to new position | +| `/admin/announce` | POST | Bearer/Session | Announce track to IRC | ## Configuration @@ -59,6 +63,24 @@ Environment variables (prefix `NTR_`): | `NTR_SHOW_DAY` | `2` | Day of week for show (0=Mon, 2=Wed) | | `NTR_SHOW_HOUR` | `22` | Hour (Eastern Time) when the show starts | +## Dashboard + +An optional web dashboard for announcing tracks to IRC during live shows. +Nick opens the dashboard, sees the current and previous week's playlist, and +clicks "Announce" next to a track to push it to the configured IRC channel +via connected bot plugins. + +Enable by setting these environment variables: + +| Variable | Default | Description | +|----------|---------|-------------| +| `NTR_WEB_USER` | *(required)* | Dashboard login username | +| `NTR_WEB_PASSWORD` | *(required)* | Dashboard login password | +| `NTR_SECRET_KEY` | *(required)* | Secret key for cookie signing | + +Bot plugins (Sopel and Limnoria) connect to the API's WebSocket endpoint +to receive announcements. See plugin READMEs for configuration. + ## Development ```bash diff --git a/docs/api.md b/docs/api.md index 252af22..c0c8bfb 100644 --- a/docs/api.md +++ b/docs/api.md @@ -177,6 +177,35 @@ Returns a specific show by internal database ID. --- +## Dashboard Endpoints + +These routes are only available when the dashboard is enabled (all three `NTR_WEB_*` env vars set). + +### `GET /login` + +Serves the login page. + +### `POST /login` + +Authenticates with username and password. Sets a session cookie on success, redirects to `/dashboard`. + +**Form Data** + +| Field | Type | Description | +|-------|------|-------------| +| `username` | string | Dashboard username | +| `password` | string | Dashboard password | + +### `GET /logout` + +Clears the session cookie and redirects to `/login`. + +### `GET /dashboard` + +Serves the playlist dashboard page. Requires a valid session cookie (redirects to `/login` if absent). + +--- + ## Admin Endpoints All admin endpoints require a bearer token via the `Authorization` header: @@ -308,6 +337,37 @@ Move a track to a new position within the current week's show. --- +### `POST /admin/announce` + +Broadcasts a track announcement to all connected WebSocket subscribers (IRC bots). The announcement is formatted as: `Now Playing: Song #N: Title by Artist - URL`. + +Accepts either a bearer token OR a valid session cookie. + +**Request Body** + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `show_id` | integer | yes | Show database ID | +| `position` | integer | yes | Track position in the show | + +**Response** + +```json +{ + "status": "announced", + "message": "Now Playing: Song #1: Night Drive by SomeArtist - https://soundcloud.com/..." +} +``` + +**Errors** + +| Status | Detail | +|--------|--------| +| 401 | `"Unauthorized"` | +| 404 | `"No track at position {n}"` | + +--- + ## Track Object Returned inside playlist and show detail responses. @@ -338,3 +398,47 @@ All timestamps in API responses are UTC. The boundary shifts by 1 hour across DS |--------|---------|--------------| | EST (Nov -- Mar) | Wed 22:00 | Thu 03:00 | | EDT (Mar -- Nov) | Wed 22:00 | Thu 02:00 | + +--- + +## WebSocket + +### `WS /ws/announce` + +WebSocket endpoint for receiving announce broadcasts. Used by IRC bot plugins. + +**Authentication** + +After connecting, send a subscribe message: + +```json +{"type": "subscribe", "token": ""} +``` + +Invalid token closes the connection with code `4001`. + +**Messages from server** + +Announce broadcast: +```json +{"type": "announce", "message": "Now Playing: Song #1: Title by Artist - URL"} +``` + +Status update (sent on subscriber connect/disconnect): +```json +{"type": "status", "subscribers": 2} +``` + +--- + +## Dashboard Configuration + +The web dashboard is optional. Enable it by setting all three environment variables: + +| Variable | Default | Description | +|----------|---------|-------------| +| `NTR_WEB_USER` | *(required)* | Dashboard login username | +| `NTR_WEB_PASSWORD` | *(required)* | Dashboard login password | +| `NTR_SECRET_KEY` | *(required)* | Secret key for session cookie signing | + +If any of these are absent, dashboard routes are not mounted and the API works exactly as before.