MusicBot is a clean, self-hostable Discord music bot built with JDA, LavaPlayer, Java 25, and Gradle. It focuses on fast slash-command playback, modern Discord embeds, queue controls, replay history, and lightweight JSON persistence.
Paste a YouTube link, Spotify link, or search query, and MusicBot joins your voice channel, resolves the track, and keeps the text channel updated with polished playback cards and button controls.
- Slash-command playback: Play songs with
/play <query>using YouTube URLs, Spotify track/album/playlist links, or plain search terms. - Search selection: Pick from interactive search results before queueing a track.
- Playback controls: Pause, resume, skip, stop, leave, and control playback with Discord buttons.
- Queue tools: View current playback, queue pages, volume, requested-by data, live streams, and loop status.
- Replay history: Replay one of the last 5 tracks with
/lastor instantly restart the latest track with/replaylast. - Server language: Switch each guild between Turkish and English with
/language. - Modern embeds: Uses compact, readable Discord embeds for playback notifications, command replies, search results, and queue views.
- Self-hostable storage: Stores guild language and playback history locally in
data/guild-state.json.
- Java 25
- A Discord bot token
- Spotify API credentials if you want Spotify links to be resolved
- A Discord voice channel with an appropriate bitrate for the quality you expect
git clone https://github.com/Despical/MusicBot.git
cd MusicBotCreate your local environment file for the Discord token, optional Spotify credentials, and default language.
Windows PowerShell:
Copy-Item .env.example .envLinux / macOS:
cp .env.example .envOpen .env and fill in the values:
DISCORD_TOKEN=your_discord_bot_token
SPOTIFY_CLIENT_ID=your_spotify_client_id
SPOTIFY_CLIENT_SECRET=your_spotify_client_secret
YOUTUBE_OAUTH2_ENABLED=false
YOUTUBE_OAUTH2_REFRESH_TOKEN=
YOUTUBE_CIPHER_URL=https://cipher.kikkia.dev/
DEFAULT_LANGUAGE=ENNotes:
DISCORD_TOKENis required.SPOTIFY_CLIENT_IDandSPOTIFY_CLIENT_SECRETare optional, but Spotify links will not work without them.YOUTUBE_OAUTH2_ENABLEDis optional. Set it totruewhen YouTube requires a signed-in account. A separate Google client ID or client secret is not needed becauseyoutube-sourceuses its built-in device authorization flow.- On the first OAuth2 start, leave
YOUTUBE_OAUTH2_REFRESH_TOKENempty and follow the URL and device code printed in the bot logs. Use a dedicated account instead of your primary YouTube account. - After authorization, copy the refresh token printed in the logs into
YOUTUBE_OAUTH2_REFRESH_TOKENso later starts can sign in without repeating the device flow. YOUTUBE_CIPHER_URLdefaults to the publicyt-cipherinstance. Set it to your own instance for production deployments that should not depend on the public service.DEFAULT_LANGUAGEis optional. Supported values areTRandEN.- The bot can also read these values from system environment variables instead of
.env.
Windows:
gradlew.bat buildLinux / macOS:
./gradlew buildWindows:
gradlew.bat runLinux / macOS:
./gradlew runDocker is the recommended way to keep the bot running on a server.
- Create
.envfrom.env.exampleand fill in your Discord token. - Start the container:
docker compose up -d --build- Check logs:
docker compose logs -f musicbot- Stop the bot:
docker compose downThe compose file mounts ./data into the container, so guild language settings
and playback history survive rebuilds and restarts.
- Create an application and bot in the Discord Developer Portal.
- Enable the bot token and copy it into
.envasDISCORD_TOKEN. - Invite the bot with slash command and voice permissions.
- Run the application and wait for slash commands to register.
- Join a voice channel and use
/play.
Recommended permissions:
- View Channels
- Send Messages
- Embed Links
- Use Slash Commands
- Connect
- Speak
- Use Voice Activity
MusicBot does not stream audio directly from Spotify. Spotify URLs are resolved into metadata, then matched against playable sources through LavaPlayer.
Set these variables if you want Spotify support:
SPOTIFY_CLIENT_ID=your_spotify_client_id
SPOTIFY_CLIENT_SECRET=your_spotify_client_secretEnable OAuth2 when YouTube rejects anonymous playback with a login-required error:
YOUTUBE_OAUTH2_ENABLED=true
YOUTUBE_OAUTH2_REFRESH_TOKEN=your_youtube_oauth2_refresh_tokenMusicBot sends Opus frames through JDA and LavaPlayer. If audio sounds distorted or muddy, keep the bot volume at or below 100 first:
/volume 100
Values above 100 amplify the decoded audio and can cause clipping on some tracks.
Runtime guild data is stored in:
data/guild-state.json
This file contains per-guild language settings and recent playback history. It is intentionally ignored by Git.
/play/pause/resume/skip/stop/leave/queue/nowplaying/volume/last/replaylast/language/help
Please do not open public issues for discovered vulnerabilities.
Read SECURITY.md for responsible disclosure reporting.
Pull Requests are welcome. To keep the project clean and easy to review, please follow the contribution guidelines:
- No tabs: Use spaces exclusively for indentation.
- Style consistency: Respect the established code architecture and style.
- Version control cleanliness: Do not increment project version numbers in example configurations within your PR.
- Minimal diffs: Disable automated reformat-on-save settings that affect untouched files.
Learn more via CONTRIBUTING.md.
This project is licensed under the GPL-3.0 License.
See LICENSE for the full license text.