Self-hosted web application for collaborative Spotify queue management at live events. Guests can search the Spotify catalog, preview tracks, and submit requests. The organizer can monitor playback and control the active Spotify device from a protected administration panel.
The project is designed for Cloudflare Pages and Cloudflare Pages Functions. Spotify credentials remain server-side; the public client never receives a Spotify access token.
- Spotify track search with album artwork and preview support when available.
- Public, mobile-first request interface with duplicate prevention.
- Live “now playing” and queue views with periodic updates.
- Server-side request throttling and URI validation.
- Organizer dashboard at
/admin.html. - Admin controls for play, pause, and skip to next track.
- Maintenance mode through an environment variable.
- Optional, consent-based Google Analytics integration.
- Security headers and server-side Spotify token caching.
The application has no client-side build step. Static assets are served by Cloudflare Pages; the functions/ directory contains the API layer.
index.html Public event interface
admin.html Organizer dashboard
script.js Public client logic
functions/api/search.js Spotify catalog search
functions/api/add.js Validated queue insertion
functions/api/player.js
functions/api/queue.js Playback and queue state
functions/api/admin/* Authenticated organizer endpoints
functions/_spotify.js Spotify authentication and API helpers
functions/_middleware.js Security headers and maintenance mode
The Spotify refresh token is used only by the Functions runtime. The deprecated /api/token endpoint is intentionally unavailable.
- A Spotify Premium account with an active playback device.
- A Spotify Developer application.
- A Cloudflare account with Pages enabled.
- Python 3.x for the one-time refresh-token setup.
The Spotify application must use this redirect URI:
http://localhost:8888/callback
The authorization scopes required by the application are:
user-modify-playback-state user-read-playback-state
Configure the following variables in Cloudflare Pages for the required deployment environments.
| Variable | Required | Description |
|---|---|---|
SPOTIFY_CLIENT_ID |
Yes | Spotify application client ID. |
SPOTIFY_CLIENT_SECRET |
Yes | Spotify application client secret. |
SPOTIFY_REFRESH_TOKEN |
Yes | Refresh token generated by get_token.py. |
ADMIN_PASSWORD |
Recommended | Password for /admin.html. Use a long, unique value. |
SPOTIFY_MARKET |
No | ISO 3166-1 alpha-2 market code, for example IT. Defaults to IT. |
EVENT_NAME |
No | Event name displayed in the welcome flow. |
GOOGLE_ANALYTICS_ID |
No | Google Analytics measurement ID. Loaded only after consent. |
MAINTENANCE |
No | Set to TRUE to serve the maintenance page with HTTP 503. |
Insert the Spotify client ID and secret in get_token.py, then run:
python -m pip install spotipy
python get_token.pyThe script writes spotify_refresh_token.txt. This file is ignored by Git and must never be committed. If the application scopes change, revoke the previous Spotify authorization and generate a new refresh token.
Connect the repository to Cloudflare Pages with the following settings:
- Framework preset: none
- Build command: leave empty
- Build output directory:
/
Add the environment variables listed above, then deploy. Cloudflare detects the functions/ directory automatically.
Set ADMIN_PASSWORD and open:
/admin.html
Guests do not need a PIN or account. The administrator session uses a signed, HttpOnly, Secure, SameSite=Strict cookie and expires after eight hours.
Install Wrangler if it is not already available, then build the Pages Functions bundle:
npx wrangler@3.114.17 pages functions buildFor a full local Pages runtime, use Wrangler Pages development mode with the required environment variables configured locally. Do not place production secrets in tracked files.
Before submitting changes, run:
node --check script.js
node --check functions/api/search.js
npx wrangler@3.114.17 pages functions build
git diff --checkSpotify exposes endpoints to read the queue and add tracks, but not to remove an arbitrary item already queued. The admin panel therefore supports playback controls and queue inspection; it cannot provide a genuine per-track removal operation through the official API.
The in-memory request limiter is effective per runtime instance. Production deployments with high traffic should also configure Cloudflare Rate Limiting or a shared Durable Object/KV-backed counter.
Generate a new refresh token with both required scopes and update SPOTIFY_REFRESH_TOKEN in Cloudflare Pages. Also verify that the Spotify account is authorized for the Developer application and that SPOTIFY_MARKET is a valid two-letter country code.
Start playback in the Spotify client and ensure the account is Premium. Spotify playback endpoints require an active, controllable device.
Verify ADMIN_PASSWORD is configured in the same Cloudflare environment as the deployed site. Use a fresh browser session after changing it.
MAINTENANCE is case-sensitive. Set it to anything other than TRUE and redeploy, or wait for the new deployment to become active.
See SECURITY.md for the vulnerability-reporting policy and responsible-disclosure process.
This project is licensed under the GNU General Public License v3.0. See LICENSE.