A self-hosted Discord music bot powered by yt-dlp with slash commands and Docker support.
- Multi-Platform โ YouTube, SoundCloud, Bandcamp, Twitch, Vimeo and all yt-dlp sites
- Search & Select โ
/play <query>shows 10 results,/select <nr>picks one - Playlist Support โ YouTube playlists with background downloading and progress display
- Now Playing UI โ Interactive embed with โฎ๏ธโฏ๏ธโญ๏ธ๐๐ buttons
- Audio Cache โ LRU file cache with configurable size, persisted to disk
- Local Mapping Playback โ
/playchristqueues local audio files from/mapping/christ - Repeat & Shuffle โ Song loop, queue loop, shuffle mode
- Rate Limiting โ 10 downloads/user/minute
- Graceful Shutdown โ Clean voice disconnects on container stop
- Go to Discord Developer Portal โ New Application
- Create a Bot โ copy the token
- OAuth2 โ URL Generator: Scopes
bot+applications.commands, Permissions:Connect,Speak,Send Messages - Invite the bot to your server
cp .env.example .envEdit .env โ at minimum set TOKEN:
TOKEN=your_bot_token
MAX_CACHE=200
DOWNLOAD_TIMEOUT_SEC=120
LOG_LEVEL=info
DOWNLOAD_HOST_PATH=./downloads
MAPPING_HOST_PATH=./mapping/christdocker compose up -d --buildView logs:
docker compose logs -f musicbotyt-dlp is automatically updated on every container start and checked every 6 hours.
| Command | Description |
|---|---|
/play <query/url> |
Play a song, playlist or start a search |
/select <1-10> |
Pick a search result |
/pause |
Pause playback |
/resume |
Resume playback |
/skip |
Skip current song |
/stop |
Stop playback and clear queue |
/queue |
Show current queue |
/volume <0-100> |
Set volume |
/shuffle |
Toggle shuffle mode |
/repeatsingle |
Repeat current song |
/repeat |
Repeat entire queue |
/playcache |
Play all cached songs |
/playchrist |
Play all audio files from /mapping/christ |
/leave |
Disconnect bot from voice |
/debug |
Show debug info |
/clearcache |
Clear audio cache (Admin) |
/refresh |
Re-register slash commands (Admin) |
src/
โโโ index.js # Entry point, slash commands, events
โโโ commands/
โ โโโ commandHandlers.js # All command handlers
โโโ queue/
โ โโโ QueueManager.js # Queue & playback (ffmpeg PCM buffering)
โโโ download/
โ โโโ ytdlp.js # yt-dlp wrapper
โ โโโ BackgroundDownloader.js
โ โโโ ProgressManager.js
โ โโโ RateLimiter.js
โโโ cache/
โ โโโ AudioCache.js # LRU file cache
โ โโโ SearchCache.js
โโโ voice/
โ โโโ VoiceManager.js # Voice join with retry
โโโ utils/
โ โโโ validation.js # URL/input security
โ โโโ urlCleaner.js # YouTube URL parsing
โ โโโ formatting.js
โ โโโ logger.js # Winston logger
โโโ config/
โโโ constants.js # All configuration values
- URL validation against SSRF (localhost, private IPs,
file://) - Shell injection prevented (
shell: falseon all spawns) - Input sanitization for all user inputs
- Per-user rate limiting
- yt-dlp runs with
nice -n 19(low CPU priority)
| Variable | Default | Description |
|---|---|---|
TOKEN |
โ | Discord bot token (required) |
MAX_CACHE |
200 |
Max number of cached audio files |
DOWNLOAD_TIMEOUT_SEC |
120 |
Download timeout in seconds |
SEARCH_TIMEOUT_SEC |
30 |
Search timeout in seconds |
LOG_LEVEL |
info |
Log level (debug, info, warn, error) |
DOWNLOAD_HOST_PATH |
./downloads |
Host path for audio cache |
MAPPING_HOST_PATH |
./mapping/christ |
Host path for local audio files mounted for /playchrist |
MAPPING_DIR |
/mapping/christ |
Container/local path read by /playchrist |
LOGS_HOST_PATH |
./logs |
Host path for log files |
MIT