Skip to content

billydev-secret/OpenMusicBot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenMusicBot

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.

Features

  • Slash commands only (discord.py 2.x app_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.be short 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 (pretty or json)
  • Retry/backoff for transient API failures and rate limits

Project Layout

  • main.py - app entrypoint
  • openmusicbot/config/settings.py - environment settings
  • openmusicbot/database.py - SQLite persistence
  • openmusicbot/discord_commands.py - slash commands + Discord event handling
  • openmusicbot/message_parsing.py - URL extraction and parsing
  • openmusicbot/spotify_client.py - Spotify API client + OAuth refresh
  • openmusicbot/youtube_resolver.py - YouTube metadata lookup
  • openmusicbot/matching.py - YouTube -> Spotify scoring logic
  • openmusicbot/message_processor.py - processing pipeline
  • openmusicbot/models.py - dataclasses and typed models
  • openmusicbot/logging_utils.py - logging setup (pretty/json)
  • sql/schema.sql - schema bootstrap
  • tests/ - unit tests for parsing and matching helpers

Requirements

  • Python 3.12+
  • Discord bot token
  • Spotify app credentials (OAuth)
  • Initial Spotify refresh token

Setup

  1. Create and activate a virtual environment.
  2. Install dependencies:
pip install -r requirements.txt
  1. Copy env template and configure:
cp .env .env
  1. Fill required variables in .env:

    • DISCORD_BOT_TOKEN
    • SPOTIFY_CLIENT_ID
    • SPOTIFY_CLIENT_SECRET
    • SPOTIFY_REDIRECT_URI
    • SPOTIFY_DEFAULT_REFRESH_TOKEN
    • Optional: LOG_FORMAT=pretty (or json)
  2. Start bot:

python main.py

Discord Configuration

Bot OAuth Invite Scopes

  • bot
  • applications.commands

Bot Permissions

  • View Channels
  • Read Message History
  • Send Messages

Manage Server (Manage Guild) is required by default for mutating admin commands.

Privileged Intent

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.

Spotify OAuth Setup

Create a Spotify app at https://developer.spotify.com/dashboard and configure redirect URI matching SPOTIFY_REDIRECT_URI.

Required scopes:

  • playlist-read-private
  • playlist-read-collaborative
  • playlist-modify-private
  • playlist-modify-public

To generate an initial refresh token:

  1. 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
  1. After approving, copy code from redirect URL.
  2. 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"
  1. Put returned refresh_token into SPOTIFY_DEFAULT_REFRESH_TOKEN.

Commands

  • /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 history processes the latest N messages per watched channel.
  • Processing only occurs in watched channels.
  • Deduplication is per guild target playlist by Spotify track ID.
  • /spotify auth_url generates a short-lived state and authorization URL.
  • /spotify auth_finish exchanges the auth code and stores the guild token.
  • If open_browser=true, the browser opens on the machine running the bot process.

Testing

Run unit tests:

pytest

Security and Privacy

  • Access tokens are persisted but never logged.
  • Use environment variables for secrets.
  • Keep .env out of source control.
  • Only configured watched channels are processed.
  • Guild/channel ownership checks are applied before config changes.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages