Invite the public MusicMaker bot β’ Support Server β’ MusicMaker Web Dashboard β’ CodeShare
Capability | Details |
---|---|
ποΈ Dynamic Embeds | Auto-refreshing "Now Playing" cards with cover art, platform badges, queue countdowns, and localized metadata. |
πͺ Smart Queue | Instant mix-ins, sequential preloading, shuffle with DJ-only guardrails, and playlist collapsing to keep channels tidy. |
π Loop Modes | Three-way loop toggle: Off, Track Repeat (endless current song), or Queue Repeat (restart queue when finished). |
π² Autoplay Engine | Genre-aware autoplay with intelligent filteringβselect from 20 genres (Pop, Rock, Hip-Hop, Anime, Lo-Fi, etc.) and the bot automatically queues matching music when your queue ends, filtering out tutorials, podcasts, and non-music content with smart duration and keyword detection. |
πΎ Local Audio Cache | All tracks are pre-downloaded and cached locally to eliminate stream interruptions, network lag, and voice cracklingβdelivering buffer-free playback even during peak Discord load or ISP throttling. |
π‘οΈ Resilient Playback | Voice connection watchdog, stream retry logic, idle auto-disconnect, and graceful SIGINT shutdown. |
π§ Localization | Cached translations via node-json-db with runtime language switching and fallback logic. |
π Static Lyrics | Fetches lyrics from Genius (web scraping) with LRCLIB fallbackβbutton-only display with pagination support. |
βοΈ Extensible Core | Modular providers (src/YouTube.js , src/Spotify.js , src/SoundCloud.js , src/DirectLink.js ) let you add more sources quickly. |
- Slash-first UX β
/play
,/search
,/language
,/nowplaying
, and/help
respond instantly with localized embeds and live-updating buttons. - Platform polyglot β Streams from YouTube, Spotify, SoundCloud, or a direct MP3/WAV/OGG link. Spotify albums, playlists, and artist radios turn into fully hydrated queues.
- Adaptive UI β A two-row control deck (Pause, Skip, Stop, Queue, Shuffle, Volume) stays in sync with the audio engine and locks down expired sessions automatically.
- Edge-ready audio core β Preloads entire queues, heals voice reconnections, and falls back gracefully when Discord or upstream services hiccup.
- Global voice β 21 fully translated language packs shipped out-of-the-box with instant server switching.
- Privacy-first β Stores only the language preference per guild in a local JSON database. No chat logs, no audio recordings.
- Project Highlights
- Folder Anatomy
- Prerequisites
- Quick Start
- Configuration
- Spotify API Setup
- Genius API Setup (Optional)
- YT-DLP Cookie Add
- Sharding for Large Bots (1000+ Servers)
- Slash Commands & Controls
- Language Support
- Deployment Tips
- Troubleshooting
- Privacy & Legal
- Contributing
discord-musicbot/
βββ commands/ # Slash command handlers (play, help, search, language, ...)
βββ events/ # Button & modal controllers for playback UI
βββ src/ # Core services: MusicPlayer, MusicEmbedManager, providers
βββ languages/ # 21 JSON language packs
βββ database/ # node-json-db store for guild language preferences
βββ config.js # Central configuration + env fallbacks
βββ index.js # Bot bootstrap, client wiring, voice auto-cleanup
βββ LICENSE # MIT License
βββ PRIVACY_POLICY.md # Data handling details
βββ TERMS_OF_SERVICE.md # Acceptable use guidelines
- Node.js β₯ 18 (LTS recommended) and npm.
- Git for cloning the repository.
- Discord application with a bot user created in the Discord Developer Portal.
- (Optional but recommended) A VPS or host with stable bandwidth and low latency to Discord voice regions.
βΉοΈ
ffmpeg-static
ships with the project. You do not need a system-wide FFmpeg unless you prefer using a custom build.
# Run from the repo root
.\setup.bat
# Edit the generated .env with your credentials
.\start.bat
setup.bat
verifies Node.js/npm, installs dependencies, and scaffolds a .env
template if you donβt have one yet. start.bat
makes sure your environment is ready and launches the bot via npm run start
.
# 1. Clone & enter
git clone https://github.com/umutxyp/musicbot.git discord-musicbot
cd discord-musicbot
# 2. Install dependencies
npm install
# 3.
EF2F
Configure secrets (see below)
Copy-Item .env .env.backup -ErrorAction SilentlyContinue
# Edit .env with your token, client ID, Spotify credentials, etc.
# 4. Boot the bot
npm run start
# or
node index.js
Slash commands register automatically when the bot starts. Guild-scoped deployment executes within seconds if GUILD_ID
is provided; global rollout can take up to an hour per Discord caching rules.
MusicMaker reads from both config.js
defaults and environment variables via .env
. Update whichever approach fits your hosting workflow.
DISCORD_TOKEN=your_bot_token
CLIENT_ID=your_application_id
GUILD_ID=optional_guild_for_fast_testing
SPOTIFY_CLIENT_ID=spotify_client_id
SPOTIFY_CLIENT_SECRET=spotify_client_secret
GENIUS_CLIENT_ID=optional_genius_client_id
GENIUS_CLIENT_SECRET=optional_genius_client_secret
STATUS=π΅ MusicMaker | /play
EMBED_COLOR=#FF6B6B
SUPPORT_SERVER=https://discord.gg/ACJQzJuckW
WEBSITE=https://musicmaker.vercel.app
COOKIES_FROM_BROWSER=chrome
COOKIES_FILE=./cookies.txt
Setting | Location | Purpose |
---|---|---|
discord.token |
.env β config.discord.token |
Discord bot token used for login and REST registration. |
discord.clientId |
.env β config.discord.clientId |
Application ID required to register slash commands. |
discord.guildId |
.env β config.discord.guildId |
Optional testing guild ID for <1 minute command deployment. Leave blank for global registration. |
bot.status |
.env /config.js |
Activity text shown as "Listening to ...". |
bot.embedColor |
.env /config.js |
Hex color for all embeds. |
bot.supportServer & bot.website |
.env /config.js |
Populates help links and README badges. |
spotify.clientId & spotify.clientSecret |
.env /config.js |
Enables Spotify search, playlist and album expansion. |
genius.clientId & genius.clientSecret |
.env /config.js |
Optional Genius API credentials for higher rate limits (works without via web scraping). |
ytdl.cookiesFromBrowser & ytdl.cookiesFile |
.env /config.js |
It is an optional feature to add cookies against YouTube cookie errors. |
π Never commit
.env
to source control. Use deployment secrets in your hosting provider or create environment variables at runtime.
- Visit the Spotify Developer Dashboard, sign in, and click Create an App.
- Name your integration (e.g.,
MusicMaker Bot
) and enable Web API. - Reveal and copy the Client ID and Client Secret.
- Add a redirect URI (any valid URL, e.g.,
https://localhost/callback
) β although client credentials flow is used, Spotify requires at least one placeholder. - Paste both values into your
.env
(SPOTIFY_CLIENT_ID
,SPOTIFY_CLIENT_SECRET
). - Restart the bot. The credentials are cached and refreshed automatically with the client credentials grant.
Without these credentials Spotify requests fall back to zero results.
MusicMaker uses web scraping by default to fetch lyrics from Geniusβno API key required! However, if you want higher rate limits and faster responses, you can optionally add Genius API credentials.
Without API Key | With API Key |
---|---|
β Works perfectly via web scraping | β Higher rate limits |
β No registration needed | β Faster response times |
β Official API support |
- Visit the Genius API Clients Page, sign in with your Genius account (or create one).
- Click New API Client and fill in:
- App Name:
MusicMaker Bot
(or any name) - App Website URL:
https://localhost
(placeholder is fine) - Redirect URI:
https://localhost/callback
(not used, but required)
- App Name:
- Click Save and reveal your Client ID and Client Secret.
- Copy both values and add them to your
.env
:GENIUS_CLIENT_ID=your_genius_client_id GENIUS_CLIENT_SECRET=your_genius_client_secret
- Restart the bot. The Genius client will now use API authentication.
π‘ Note: Even without credentials, lyrics work perfectly! The bot automatically scrapes Genius.com and falls back to LRCLIB if needed.
The bot fetches lyrics in this order:
- Genius (with API key if provided, otherwise web scraping)
- LRCLIB (free lyrics database)
- If both fail, no lyrics button appears
YouTube may occasionally block yt-dlp with a "Sign in to confirm you're not a bot" error. To fix this, you need to provide browser cookies to yt-dlp.
-
Open your
.env
file or set environment variables -
Add one of the following based on your browser:
# For Chrome users COOKIES_FROM_BROWSER=chrome # For Firefox users COOKIES_FROM_BROWSER=firefox # For Edge users COOKIES_FROM_BROWSER=edge # For Safari users COOKIES_FROM_BROWSER=safari
-
Make sure you're logged into YouTube in that browser
-
Restart your bot
Note: This method automatically extracts cookies from your browser, so you need to be logged into YouTube in the specified browser.
-
Install a browser extension to export cookies:
- Chrome/Edge: Get cookies.txt LOCALLY
- Firefox: cookies.txt
-
Go to YouTube while logged in and export cookies to a file named
cookies.txt
-
Place
cookies.txt
in your bot's root directory (same folder asindex.js
) -
Add to your
.env
file:COOKIES_FILE=./cookies.txt
-
Restart your bot
After setting up cookies, test with:
npm start
If you still see bot detection errors:
- Make sure you're logged into YouTube in your browser
- Try clearing your browser cookies and logging in again
- Regenerate the cookies.txt file
- Try a different browser
Security Note: Keep your cookies.txt
file private and never share it, as it contains your YouTube session data.
When your bot reaches 1,000+ servers, Discord requires you to use sharding to distribute the load across multiple processes. MusicMaker includes a fully automated sharding system powered by Discord.js's ShardingManager
.
π Read the complete Sharding Guide for detailed documentation, troubleshooting, and best practices.
Sharding splits your bot into multiple instances (shards), each handling a subset of servers:
- Shard 0 might handle servers 1-1000
- Shard 1 might handle servers 1001-2000
- And so on...
Discord automatically routes events to the correct shard based on server ID.
.\start.bat
Choose option [2] Sharding Mode when prompted.
.\start-shard.bat
# or
node shard.js
node index.js
Configure sharding in .env
or config.js
:
# Sharding Settings
TOTAL_SHARDS=auto # 'auto' = Discord calculates optimal count
SHARD_LIST=auto # 'auto' = spawn all shards, or [0,1,2] for specific
SHARD_MODE=process # 'process' (recommended) or 'worker'
SHARD_RESPAWN=true # Auto-restart crashed shards
SHARD_SPAWN_DELAY=5500 # Delay between spawning shards (ms)
SHARD_SPAWN_TIMEOUT=30000 # Timeout for shard ready event (ms)
Mode | Description | Best For |
---|---|---|
process | Each shard runs in a separate Node.js process | Production (more stable, isolated memory) |
worker | Each shard runs in a worker thread | Development (less memory, experimental) |
Discord recommends: 1 shard per 1,000 servers
Servers | Recommended Shards |
---|---|
< 1,000 | No sharding needed (use node index.js ) |
1,000 - 2,000 | 2 shards |
2,000 - 3,000 | 3 shards |
5,000+ | 5+ shards |
The bot automatically calculates the optimal count when TOTAL_SHARDS=auto
.
- Use
auto
for production β Let Discord.js calculate the optimal shard count - Respect spawn delays β Discord rate-limits shard connections (5-5.5 seconds recommended)
- Monitor shard health β The shard manager logs each shard's status in real-time
- Enable auto-respawn β Crashed shards restart automatically
- Use process mode β More stable than worker threads for production
The bot displays detailed shard information:
[SHARD MANAGER] Launching shard 0...
[SHARD 0] β
Shard 0 is ready!
[SHARD 0] π΅ Music bot serving 847 servers on this shard!
[SHARD 0] π Total servers across all shards: 1523
[SHARD MANAGER] Launching shard 1...
[SHARD 1] β
Shard 1 is ready!
[SHARD 1] π΅ Music bot serving 676 servers on this shard!
SHARD_LIST=[0,1,2] # Only spawn shards 0, 1, and 2
TOTAL_SHARDS=4 # Force 4 shards regardless of server count
SHARD_RESPAWN=false
- Sharding is mandatory at 1,000+ servers β Discord will reject connections without it
- Commands work identically β Users see no difference between sharded and non-sharded bots
- Database remains local β Each shard shares the same
database/languages.json
file - Voice connections are isolated β Each shard manages its own voice connections
Issue | Solution |
---|---|
"Cannot spawn more than X shards" | Discord limits shards based on server count. Use auto or contact Discord for limit increase. |
Shards keep crashing | Check memory usage and increase spawn timeout (SHARD_SPAWN_TIMEOUT ). |
Commands not appearing | Wait for all shards to be ready. Global commands can take up to 1 hour to propagate. |
Bot shows as offline | Ensure all shards are running. Check the shard manager logs. |
Command | What it does |
---|---|
/play <query> |
Smart-detects platform links or search keywords, queues playlists/albums, and spins up the control panel. |
/search <keywords> |
Presents a paginated selection menu of YouTube matches β choose with buttons. |
/nowplaying |
Drops the live embed again, including queue status, repeat/shuffle flags, and volume. |
/language |
Opens a flag button wall for instant localization (cached per guild). |
/help |
Gorgeous, localized feature tour + live stats and support links. |
- βΈοΈ /
βΆοΈ Pause & Resume β Auth-limited to DJs, admins, or the original requester. - βοΈ Skip β Jumps to the next queued item (requires at least 1 upcoming track).
- βΉοΈ Stop β Clears queue, tears down voice, and locks the panel.
- π Queue β Renders the next 10 tracks with real-time progress bar.
- π Shuffle β Randomizes the queue with guard rails (min. 2 tracks).
- π Volume β Opens a modal allowing 0β100 input.
- π Loop β Cycles through loop modes: Off β Track Repeat β Queue Repeat. Track mode replays the current song endlessly; Queue mode restarts the entire queue when finished.
- π² Autoplay β Toggles genre-based autoplay (Off β On with genre selection). When enabled, the bot automatically adds matching music from your selected genre when the queue ends, keeping the music flowing seamlessly.
All button sessions carry a short-lived signature, preventing stale interactions from previous queues.
MusicMaker features an intelligent autoplay engine that keeps the music flowing when your queue runs out.
- Enable Autoplay β Click the π² Autoplay button on the now-playing embed
- Choose Your Genre β Select from 20 carefully curated genres:
- π΅ Pop, Rock, Hip-Hop, Electronic, Jazz, Classical, Metal, Country
- πΈ R&B, Indie, Latin, K-Pop, Anime, Lo-Fi, Blues, Reggae
- πΉ Disco, Punk, Ambient, or Random (all genres)
- Sit Back & Enjoy β When your queue ends, the bot automatically searches and queues relevant tracks
The autoplay system includes sophisticated filters to ensure you only get actual music:
Duration Limits:
- β Minimum: 30 seconds
- β Maximum: 10 minutes (600 seconds)
- β Filters out: Full movies, podcasts, long tutorials, DJ sets
Keyword Blocking: Automatically skips content containing:
- Tutorial, lesson, course, how-to, guide
- Podcast, interview, talk, speech, lecture
- Review, unboxing, reaction, gameplay
- Full movie, full album, documentary
- ASMR, audiobook, story, meditation
- Mix, compilation (long-form content)
Quality Checks:
- Filters excessive emojis (spam/clickbait indicators)
- Blocks playlist-style titles with many brackets
- Prioritizes official music videos and verified uploads
Each genre uses optimized search terms to find the best content:
Genre | Search Strategy |
---|---|
Anime | "anime opening official", "anime songs official", "best anime op" |
K-Pop | "kpop official mv", "kpop songs 2024", "korean music official" |
Lo-Fi | "lofi hip hop music", "lofi beats official", "chill lofi music" |
Electronic | "edm music", "electronic dance music", "house music official" |
Others | Similarly optimized with "official", year markers, and quality indicators |
If the first search yields no suitable tracks after filtering:
- Automatically retries with a different keyword from the genre pool
- Ensures you always get music, never silence
- Logs the entire process for transparency
All autoplay tracks leverage the same local cache system as manual plays:
- Pre-downloaded before playback starts
- Zero buffering during playback
- Instant playback from local storage
- Automatic cleanup when tracks finish
Watch the autoplay engine work in real-time:
π² Autoplay: Finding anime music...
β
Autoplay: Added "YOASOBI - γ’γ€γγ« (Idol) [Official Music Video]" (244s)
β¬οΈ Pre-downloading: YOASOBI - γ’γ€γγ« (Idol) [Official Music Video]
π₯ Downloading: YOASOBI - γ’γ€γγ« (Idol) [Official Music Video]
β
Downloaded: YOASOBI - γ’γ€γγ« (Idol) [Official Music Video]
π File size: 3.87 MB
π² Autoplay: Now playing "YOASOBI - γ’γ€γγ« (Idol) [Official Music Video]"
- Random Mode β Can't decide? Select "Random" to get music from all genres
- Queue Priority β Manually added tracks always play before autoplay suggestions
- Toggle Anytime β Turn autoplay on/off at any point during playback
- No Spam β Only adds one track at a time as each song finishes
MusicMaker eliminates playback interruptions by pre-downloading and caching all audio locally before streaming to Discord.
Traditional Discord bots stream directly from YouTube/Spotify/SoundCloud URLs, which causes:
- β Random buffering and stuttering during playback
- β Voice crackling when your ISP throttles streaming sites
- β Stream failures during Discord voice server load spikes
- β Quality drops when network conditions fluctuate
MusicMaker's solution:
- β
Downloads entire tracks to
audio_cache/
before playback - β Streams from local disk at consistent quality
- β Zero dependency on external stream stability during playback
- β Instant resume after voice reconnections
- Queue Detection β When you add a track with
/play
or autoplay triggers - Background Download β Track downloads silently while previous song plays
- Smart Preloading β Entire queue preloads in parallel for instant transitions
- Local Streaming β FFmpeg streams the cached file to Discord voice
- Automatic Cleanup β Files delete after playback to save disk space
β¬οΈ Pre-downloading: Song Title
π₯ Downloading: Song Title
β
Downloaded: Song Title
π File size: 4.23 MB
β
Background download completed: Song Title
π΅ Streaming: Song Title
β»οΈ Reusing cached file: Song Title
βΆοΈ Playing from cache: Song Title
ποΈ Deleted: track_abc123.opus
Cache Directory:
- Location:
audio_cache/
(auto-created on first run) - Format: Opus audio (
.opus
extension) for optimal Discord voice quality - Naming:
track_[MD5 hash].opus
to prevent conflicts
Download Process:
- Uses
youtube-dl-exec
with best audio format selection - FFmpeg transcodes to Opus for Discord's native codec
- Parallel downloads for multiple queued tracks
- Retry logic for failed downloads with fallback streaming
Memory Management:
- Files persist only during active playback
- Automatic deletion after track finishes
- Graceful cleanup on bot shutdown or errors
- Prevents disk bloat with aggressive pruning
Performance Benefits:
- Zero mid-song buffering β entire file ready before playback
- Fast skip/seek β local I/O is instant vs. network round-trip
- Reliable autoplay β pre-cached tracks guarantee smooth transitions
- Network resilience β download failures don't affect current playback
Average track sizes:
- 3-5 minutes: ~3-8 MB
- Queue of 10 tracks: ~30-80 MB peak usage
- Auto-cleanup: Disk usage drops to ~5-15 MB during playback
The cache system requires minimal disk space and automatically manages itself. For VPS deployments, ensure at least 500 MB free space for comfortable operation with large queues.
Out-of-the-box translations (and matching flag buttons):
Arabic, German, English, Spanish, French, Indonesian, Italian, Japanese, Dutch, Portuguese, Russian, Turkish, Traditional Chinese, Simplified Chinese, Hindi, Finnish, Danish, Norwegian, Polish, Korean, Swedish
Add your own by copying languages/en.json
, translating strings, and restarting the bot. The LanguageManager
hot-loads every JSON file in languages/
.
- Testing Guild β Set
GUILD_ID
during development to avoid the global propagation delay. Remove it before production to reach every server automatically. - Process Manager β Use
pm2
,systemd
, or Docker to keep the bot alive and restart on crashes. Remember to persist thedatabase/languages.json
file if you containerize. - Logging β Leverage the built-in Chalk-colored console output. Redirect stdout/stderr to log files for long-term monitoring.
- Scaling β The bot maintains one voice connection per guild. Horizontal scaling requires a shared state & queue (Redis, REST API, etc.) β future roadmap material.
Symptom | Fix |
---|---|
Slash commands do not appear | Ensure CLIENT_ID is correct and the bot logged in successfully. For new deployments, invite the bot with applications.commands scope. |
Spotify tracks return nothing | Verify SPOTIFY_CLIENT_ID /SECRET and that the app is approved for Spotify Web API. |
Bot joins but plays silence | Confirm the host has outbound UDP open, and the voice channel permissions allow Connect and Speak. |
Buttons stop working mid-song | Interactions expire after Discord's cache TTL or when a new session is generated. Use /play again to refresh the deck. |
Lyrics button disabled or missing | The bot fetches from Genius first (web scraping or API), then LRCLIB. If both fail, no lyrics button appears. Check console for fetch errors. |
Command language incorrect | Run /language , select your flag, and ensure database/languages.json is writable. |
YouTube bot detection error | YouTube requires bot verification via cookies. See YouTube Cookie Setup below for detailed instructions. |
- Privacy Policy β Exactly what data we store (guild ID + language preference) and how to request deletion.
- Terms of Service β Acceptable use, liability limits, and contact info.
- License β MIT. Use it privately or commercially β just keep the notice.
- Fork the repository and create a feature branch.
- Run
npm install
to load dependencies. - Add or refine features (translation packs, UI tweaks, new providers).
- Open a pull request with a clear description and screenshots/console logs where relevant.
Bug reports, feature ideas, and localization pull requests are all welcome. Swing by the Support Server to chat with the community.
Happy streaming, and keep the servers grooving! π§