Added new `MusicEvent` types, including `TRACK_ERROR`, `TRACK_STUCK`, and `PLAYER_POSITION`, providing enhanced diagnostics and feedback. Improved queue mutation notifications by introducing granular events like `added`, `removed`, `moved`, `cleared`, and `shuffled`. Updated tests and documentation to reflect the changes, ensuring consistency and clarity across the event system.
101 lines
4.4 KiB
Markdown
101 lines
4.4 KiB
Markdown
# Net Neutrality Discord Bot
|
|
|
|
A custom Discord bot written in Java. It uses [JDA](https://github.com/discord-jda/JDA) for Discord, a [Lavalink](https://github.com/lavalink-devs/Lavalink) node for music playback, MariaDB/MySQL for persistence, and exposes an HTTP API built with Javalin.
|
|
|
|
This is a personal project. No support is offered for building or running it.
|
|
|
|
## Table of Contents
|
|
|
|
- [Requirements](#requirements)
|
|
- [Configuration](#configuration)
|
|
- [Running with Docker Compose](#running-with-docker-compose)
|
|
- [Running Locally](#running-locally)
|
|
- [Testing](#testing)
|
|
- [License](#license)
|
|
|
|
## Requirements
|
|
|
|
- Docker and Docker Compose (recommended), or
|
|
- JDK 25 and Maven (the included `mvnw` wrapper works) for local runs
|
|
- A MariaDB/MySQL database
|
|
- A Lavalink node, version 4.2.0 or newer
|
|
- A Discord bot token
|
|
|
|
## Configuration
|
|
|
|
All settings are provided as environment variables. A template with every supported variable is available in [`bot.properties.example`](bot.properties.example).
|
|
|
|
Key variables:
|
|
|
|
| Variable | Description |
|
|
| --- | --- |
|
|
| `NETNEUTRALITY_BOT_TOKEN` | Discord bot token |
|
|
| `NETNEUTRALITY_BOT_PREFIX` | Command prefix |
|
|
| `NETNEUTRALITY_BOT_OWNER` | Discord user ID of the bot owner |
|
|
| `NETNEUTRALITY_API_PORT` | Port for the HTTP API (default `9000`) |
|
|
| `MYSQL_HOST`, `MYSQL_PORT`, `MYSQL_USER`, `MYSQL_PASSWORD`, `MYSQL_DATABASE` | Database connection settings |
|
|
| `NETNEUTRALITY_LAVALINK_URI`, `NETNEUTRALITY_LAVALINK_PASSWORD` | Lavalink connection settings |
|
|
| `NETNEUTRALITY_SENTRY_DSN` | Optional Sentry DSN for error reporting |
|
|
| `GITEA_HOST`, `GITEA_TOKEN`, `GITEA_OWNER`, `GITEA_REPO` | Optional Gitea settings for issue reporting |
|
|
| `NETNEUTRALITY_WEBHOOK_URL`, `NETNEUTRALITY_WEBHOOK_SECRET` | Optional frontend webhook URL and HMAC secret (see below) |
|
|
|
|
### Webhook events
|
|
|
|
When `NETNEUTRALITY_WEBHOOK_URL` is set, the bot POSTs JSON music-state events (`TRACK_START`, `TRACK_END`, `QUEUE_UPDATED`, `PLAYER_PAUSED`, `PLAYER_RESUMED`, `VOLUME_CHANGED`, `VOICE_CONNECTED`, `VOICE_DISCONNECTED`) to it asynchronously. Each event has `type`, `guildId`, `timestamp`, a per-guild `seq` and a `payload`. Requests carry an `X-Signature: sha256=<hex HMAC-SHA256 of the body>` header computed with `NETNEUTRALITY_WEBHOOK_SECRET`. Failed deliveries are retried 3 times with exponential backoff and then dropped, so the frontend should still do a full resync on load and periodically. The polling endpoints remain available.
|
|
|
|
`PLAYER_SEEKED` is sent after a seek with payload `{ position }` (milliseconds). `VOTE_SKIP_UPDATED` is sent after a vote that doesn't skip the track yet, with payload `{ userId, votes, threshold }` (`threshold` is the percentage of listeners needed). A vote that does skip produces the usual `TRACK_END` / `TRACK_START` / `QUEUE_UPDATED` events instead.
|
|
|
|
`TRACK_START` / `TRACK_END` payloads are `{ identifier, title, author, length, uri, artworkUrl }` (plus `reason` on `TRACK_END`). `uri` and `artworkUrl` may be `null` when the source doesn't provide them.
|
|
|
|
`VOICE_CONNECTED` / `VOICE_DISCONNECTED` are sent for the bot itself and for any member joining or leaving the voice channel the bot is currently in. Their payload is `{ channelId, userId, username, nickname, bot, self }`, where `nickname` is the member's effective display name in the guild, `bot` marks bot accounts and `self` marks this bot's own voice changes.
|
|
|
|
## Running with Docker Compose
|
|
|
|
Docker Compose is the preferred way to run the bot. It starts the bot, the database, Lavalink, and the supporting YouTube cipher and PO token services.
|
|
|
|
1. Copy `bot.properties.example` and fill in the values (see [Configuration](#configuration)).
|
|
2. Build and start the stack:
|
|
|
|
```bash
|
|
docker compose build
|
|
docker compose up -d
|
|
```
|
|
|
|
3. View logs:
|
|
|
|
```bash
|
|
docker compose logs -f netneutrality-bot
|
|
```
|
|
|
|
Logs are also written to the `logs` directory.
|
|
|
|
## Running Locally
|
|
|
|
1. Copy `bot.properties.example` to `bot.properties` and fill in the values.
|
|
2. Make sure a database and a Lavalink node are reachable at the configured addresses.
|
|
3. Build the project:
|
|
|
|
```bash
|
|
./mvnw package
|
|
```
|
|
|
|
4. Run the bot:
|
|
|
|
```bash
|
|
java -jar target/netneutrality.jar
|
|
```
|
|
|
|
Dependencies are copied to `target/lib` during packaging and referenced by the jar manifest.
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
./mvnw test
|
|
```
|
|
|
|
Database tests use Testcontainers, so Docker must be running. Checkstyle runs during the `test` phase.
|
|
|
|
## License
|
|
|
|
See the [LICENSE](LICENSE) file.
|