discord-music-bot/README.md
2025-04-20 00:47:27 +08:00

224 lines
9.5 KiB
Markdown

# Rust LavaLink Discord Music Bot Prototype
A prototype Discord music bot built with Rust, using the [Serenity](https://github.com/serenity-rs/serenity) library for Discord interactions and the [lavalink-rs](https://github.com/adamsoutar/lavalink-rs) crate to interface with a [LavaLink](https://github.com/lavalink-devs/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 `inventory` for 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
1. **Rust Toolchain:** Install Rust using [rustup](https://rustup.rs/). (`rustup update` recommended).
2. **LavaLink Server:**
* Download the latest `Lavalink.jar` from the [LavaLink Releases](https://github.com/lavalink-devs/Lavalink/releases).
* A **Java Runtime Environment (JRE)** (Version 11 or higher, 17 recommended) to run the `.jar` file.
* Configure the `application.yml` file for LavaLink.
3. **Discord Bot Application:** (See details below)
### For Docker Execution
1. **Docker & Docker Compose:** Install Docker Desktop (which includes Compose) or Docker Engine and the Docker Compose plugin. See the [official Docker installation guide](https://docs.docker.com/engine/install/).
2. **LavaLink Server Files:** You still need to download `Lavalink.jar` and create/configure `application.yml` locally, as these will be mounted into the LavaLink container.
3. **Discord Bot Application:** (See details below)
### Discord Bot Application Details (Common)
* Create a bot application on the [Discord Developer Portal](https://discord.com/developers/applications).
* 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
1. **Clone the Repository:**
```bash
git clone <repository-url>
cd discord-music-bot-lavalink-rs
```
2. **Prepare LavaLink Files:**
* Download the latest `Lavalink.jar` from [LavaLink Releases](https://github.com/lavalink-devs/Lavalink/releases) and place it in the project root directory.
* Create or copy an `application.yml` file into the project root directory. Configure at least the `lavalink.server.password`. Example:
```yaml
# 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
```
3. **Configure Environment Variables:**
Create a `.env` file in the project root:
```bash
cp .env.example .env
```
Edit `.env` with your credentials:
```env
# .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.yml
```
**Note:** Ensure the `LAVALINK_PASSWORD` here matches the one in `application.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.
1. **Ensure Prerequisites:** Docker, Docker Compose, `Lavalink.jar`, `application.yml`, configured `.env` (with `LAVALINK_HOST=lavalink`).
2. **Build and Start:** In the project root, run:
```bash
docker compose up --build -d
```
* `--build`: Builds the bot image. Needed the first time or after code changes.
* `-d`: Runs containers in the background.
3. **Check Logs (Optional):**
```bash
docker compose logs -f app # View bot logs
docker compose logs -f lavalink # View LavaLink logs
```
Press `Ctrl+C` to stop following.
4. **Stopping:**
```bash
docker compose down
```
### Option 2: Running Natively
This method requires you to run LavaLink separately.
1. **Start LavaLink:**
Navigate to the directory containing `Lavalink.jar` and `application.yml`. Run:
```bash
java -jar Lavalink.jar
```
Keep this terminal open.
2. **Build the Bot (if needed):**
```bash
cargo build --release
```
3. **Configure `.env`:** Ensure `LAVALINK_HOST` in your `.env` file points to the correct IP/hostname where LavaLink is running (e.g., `127.0.0.1` if running on the same machine).
4. **Run the Bot:**
In a **new terminal**, navigate to the project root and run:
```bash
# 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](https://github.com/serenity-rs/serenity): Discord API library for Rust.
* [lavalink-rs](https://github.com/adamsoutar/lavalink-rs): Client implementation for the LavaLink protocol.
* [Tokio](https://tokio.rs/): Asynchronous runtime.
* [Inventory](https://github.com/dtolnay/inventory): Type-driven dependency injection / global struct collection (used for command registration).
* [Anyhow](https://github.com/dtolnay/anyhow): Flexible error handling.
* [Tracing](https://github.com/tokio-rs/tracing): Application-level tracing and logging framework.
* [Url](https://crates.io/crates/url): URL parsing.
* [Dotenv](https://crates.io/crates/dotenv): Loading environment variables from `.env` files.
* [Docker](https://www.docker.com/): 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.