Production-oriented Discord bot for Python 3.12 that watches configured channels, extracts Spotify/YouTube links, resolves to Spotify tracks, deduplicates, and adds to a target playlist per guild.
- Slash commands only (
discord.py2.xapp_commands) - Watches configured text channels via
on_message - Ignores bot and webhook messages
- Parses:
- Spotify track links
- Spotify album links
- Spotify playlist links
- YouTube video links (
youtube.com/watch) youtu.beshort links
- Spotify imports:
- Track: add directly
- Album: add all album tracks
- Playlist: import all playlist tracks
- YouTube resolution:
- Fetch metadata from YouTube oEmbed
- Clean noisy title tokens (official video, lyrics, HD, 4K, live, remaster, audio, etc.)
- Search Spotify candidates and compute confidence score
- Auto-add only above threshold
- Below threshold goes to unmatched review queue
- SQLite persistence with startup schema bootstrap
- Restart-safe dedupe:
- processed Discord message IDs
- known/added Spotify track IDs per guild playlist
- OAuth token persistence and refresh (private playlist compatible)
- Configurable logging format (
prettyorjson) - Retry/backoff for transient API failures and rate limits
main.py- app entrypointopenmusicbot/config/settings.py- environment settingsopenmusicbot/database.py- SQLite persistenceopenmusicbot/discord_commands.py- slash commands + Discord event handlingopenmusicbot/message_parsing.py- URL extraction and parsingopenmusicbot/spotify_client.py- Spotify API client + OAuth refreshopenmusicbot/youtube_resolver.py- YouTube metadata lookupopenmusicbot/matching.py- YouTube -> Spotify scoring logicopenmusicbot/message_processor.py- processing pipelineopenmusicbot/models.py- dataclasses and typed modelsopenmusicbot/logging_utils.py- logging setup (pretty/json)sql/schema.sql- schema bootstraptests/- unit tests for parsing and matching helpers
- Python 3.12+
- Discord bot token
- Spotify app credentials (OAuth)
- Initial Spotify refresh token
- Create and activate a virtual environment.
- Install dependencies:
pip install -r requirements.txt- Copy env template and configure:
cp .env .env-
Fill required variables in
.env:DISCORD_BOT_TOKENSPOTIFY_CLIENT_IDSPOTIFY_CLIENT_SECRETSPOTIFY_REDIRECT_URISPOTIFY_DEFAULT_REFRESH_TOKEN- Optional:
LOG_FORMAT=pretty(orjson)
-
Start bot:
python main.pybotapplications.commands
- View Channels
- Read Message History
- Send Messages
Manage Server (Manage Guild) is required by default for mutating admin commands.
MESSAGE CONTENT INTENT is required to read standard message content in watched channels. Enable it in:
- Discord Developer Portal -> Bot -> Privileged Gateway Intents
Without this intent, link extraction from ordinary messages will not work.
Create a Spotify app at https://developer.spotify.com/dashboard and configure redirect URI matching SPOTIFY_REDIRECT_URI.
Required scopes:
playlist-read-privateplaylist-read-collaborativeplaylist-modify-privateplaylist-modify-public
To generate an initial refresh token:
- Open authorization URL (replace values):
https://accounts.spotify.com/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2Fcallback&scope=playlist-read-private%20playlist-read-collaborative%20playlist-modify-private%20playlist-modify-public
- After approving, copy
codefrom redirect URL. - Exchange code for tokens:
curl -X POST "https://accounts.spotify.com/api/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
-d "grant_type=authorization_code&code=AUTH_CODE&redirect_uri=http://127.0.0.1:8080/callback"- Put returned
refresh_tokenintoSPOTIFY_DEFAULT_REFRESH_TOKEN.
/watch add <channel>/watch remove <channel>/watch list/playlist set <spotify_playlist_url>/playlist show/sync history <limit>/sync channel <channel> <limit>/unmatched list/unmatched approve <id>/unmatched reject <id>/pause/resume/status/spotify auth_url <open_browser>/spotify auth_finish <code_or_redirect_url> [state]/summary set <enabled>(extra helper for per-guild summary toggle)/summary show
Notes:
/sync historyprocesses the latestNmessages per watched channel.- Processing only occurs in watched channels.
- Deduplication is per guild target playlist by Spotify track ID.
/spotify auth_urlgenerates a short-lived state and authorization URL./spotify auth_finishexchanges the auth code and stores the guild token.- If
open_browser=true, the browser opens on the machine running the bot process.
Run unit tests:
pytest- Access tokens are persisted but never logged.
- Use environment variables for secrets.
- Keep
.envout of source control. - Only configured watched channels are processed.
- Guild/channel ownership checks are applied before config changes.