Branch v1 was renamed to v0.
Rust LavaLink Discord Music Bot Prototype
A prototype Discord music bot built with Rust, using the Serenity library for Discord interactions and the lavalink-rs crate to interface with a LavaLink audio server. This bot utilizes slash commands for user interaction and features a modular command structure using the inventory crate. It can be run natively or using Docker Compose for easier setup and deployment.
Features
- Connects to Discord via the Gateway.
- Connects to a LavaLink node for audio processing.
- Slash command support for core music functions:
/join: Connect the bot to your voice channel./play: Play audio from a URL or search query (YouTube default). Handles single tracks and playlists./skip: Skip the currently playing track./leave: Disconnect the bot from the voice channel.
- Basic queueing (handled internally by LavaLink).
- Modular command system using
inventoryfor easy addition of new commands. - Basic auto-leaving functionality when the bot is alone in a voice channel (with a short delay).
- Asynchronous architecture using Tokio.
- Logging using
tracing. - Containerized setup using Docker and Docker Compose.
Prerequisites
For Native Execution
- Rust Toolchain: Install Rust using rustup. (
rustup updaterecommended). - LavaLink Server:
- Download the latest
Lavalink.jarfrom the LavaLink Releases. - A Java Runtime Environment (JRE) (Version 11 or higher, 17 recommended) to run the
.jarfile. - Configure the
application.ymlfile for LavaLink.
- Download the latest
- Discord Bot Application: (See details below)
For Docker Execution
- Docker & Docker Compose: Install Docker Desktop (which includes Compose) or Docker Engine and the Docker Compose plugin. See the official Docker installation guide.
- LavaLink Server Files: You still need to download
Lavalink.jarand create/configureapplication.ymllocally, as these will be mounted into the LavaLink container. - Discord Bot Application: (See details below)
Discord Bot Application Details (Common)
- Create a bot application on the Discord Developer Portal.
- Retrieve the Bot Token.
- Enable the Privileged Gateway Intents:
PRESENCE INTENT(Optional)SERVER MEMBERS INTENT(Optional, not strictly required for prototype)MESSAGE CONTENT INTENT(Optional, not strictly required for prototype)GUILD_VOICE_STATES(Required for voice functionality)
- Invite the bot to your Discord server with necessary permissions:
Connect,Speak,Send Messages/Send Messages in Threads,Use Application Commands.
Setup
-
Clone the Repository:
git clone <repository-url> cd discord-music-bot-lavalink-rs -
Prepare LavaLink Files:
-
Download the latest
Lavalink.jarfrom LavaLink Releases and place it in the project root directory. -
Create or copy an
application.ymlfile into the project root directory. Configure at least thelavalink.server.password. Example:# application.yml server: port: 2333 address: 0.0.0.0 lavalink: server: password: "youshallnotpass" # CHANGE THIS sources: # Enable desired sources youtube: true soundcloud: true # Add other configurations as needed
-
-
Configure Environment Variables: Create a
.envfile in the project root:cp .env.example .envEdit
.envwith your credentials:# .env DISCORD_TOKEN=YOUR_BOT_TOKEN_HERE # --- IMPORTANT: Choose ONE Lavalink Host setting --- # == For Docker Compose Execution == # Use the service name defined in docker-compose.yml LAVALINK_HOST=lavalink # == For Native Execution == # Use the actual IP or hostname of your LavaLink server # LAVALINK_HOST=127.0.0.1 # Or e.g., other-machine-ip # --- Common Settings --- LAVALINK_PORT=2333 LAVALINK_PASSWORD=youshallnotpass # Must match password in application.ymlNote: Ensure the
LAVALINK_PASSWORDhere matches the one inapplication.yml.
Running the Bot
You can run the bot natively or using Docker Compose.
Option 1: Running with Docker Compose (Recommended)
This method runs both the bot and the LavaLink server in isolated containers.
-
Ensure Prerequisites: Docker, Docker Compose,
Lavalink.jar,application.yml, configured.env(withLAVALINK_HOST=lavalink). -
Build and Start: In the project root, run:
docker compose up --build -d--build: Builds the bot image. Needed the first time or after code changes.-d: Runs containers in the background.
-
Check Logs (Optional):
docker compose logs -f app # View bot logs docker compose logs -f lavalink # View LavaLink logsPress
Ctrl+Cto stop following. -
Stopping:
docker compose down
Option 2: Running Natively
This method requires you to run LavaLink separately.
-
Start LavaLink: Navigate to the directory containing
Lavalink.jarandapplication.yml. Run:java -jar Lavalink.jarKeep this terminal open.
-
Build the Bot (if needed):
cargo build --release -
Configure
.env: EnsureLAVALINK_HOSTin your.envfile points to the correct IP/hostname where LavaLink is running (e.g.,127.0.0.1if running on the same machine). -
Run the Bot: In a new terminal, navigate to the project root and run:
# Using cargo cargo run # Or using the compiled release binary # target/release/discord-music-bot-lavalink-rs
Available Commands
Use these commands in your Discord server where the bot is present:
/join: Makes the bot join the voice channel you are currently in./play query:<url or search term>: Plays a song from a URL (direct link or playlist) or searches YouTube for the term and plays the first result. Queues subsequent tracks/playlists./skip: Skips the song currently playing./leave: Disconnects the bot from the voice channel.
Project Structure
discord-music-bot-lavalink-rs/
├── .env # Local environment variables (ignored by git)
├── .env.example # Example environment file
├── .dockerignore # Files ignored by Docker context
├── Dockerfile # Instructions to build the bot's Docker image
├── docker-compose.yml # Defines bot and LavaLink services for Docker Compose
├── Lavalink.jar # LavaLink server executable (add locally)
├── application.yml # LavaLink configuration (add locally)
├── Cargo.toml # Rust project manifest, dependencies
└── src/
├── main.rs # Entry point, client setup, task spawning
├── state.rs # Definition of the shared BotState struct
├── handler.rs # Serenity event handler (ready, interaction_create, voice_state_update)
├── lavalink_handler.rs # lavalink-rs event handler (track start/end, etc.)
├── utils.rs # Utility functions (e.g., get_voice_state)
└── commands/ # Directory for slash command implementations
├── mod.rs # Command registration setup (inventory, traits)
├── join.rs # /join command implementation & registration
├── leave.rs # /leave command implementation & registration
├── play.rs # /play command implementation & registration
└── skip.rs # /skip command implementation & registration
Key Dependencies
- Serenity: Discord API library for Rust.
- lavalink-rs: Client implementation for the LavaLink protocol.
- Tokio: Asynchronous runtime.
- Inventory: Type-driven dependency injection / global struct collection (used for command registration).
- Anyhow: Flexible error handling.
- Tracing: Application-level tracing and logging framework.
- Url: URL parsing.
- Dotenv: Loading environment variables from
.envfiles. - Docker: Containerization platform.
Future Improvements
This is a prototype, and many features could be added or improved:
- [] More Commands:
/queue,/pause,/resume,/nowplaying,/volume,/remove,/loop,/shuffle, etc. - [] Robust Error Handling: More specific error types and user-friendly feedback.
- [] Queue Management: Displaying the queue, allowing users to remove specific tracks.
- [] Permissions: Restricting commands based on user roles or voice channel status.
- [] Configuration: Per-guild settings (e.g., announcement channels, DJ roles).
- [] Player Persistence: Saving/loading player state across bot restarts (more complex).
- [] Multi-Node Support: Utilizing multiple LavaLink nodes for scalability.
- [] Tests: Adding unit and integration tests.