Files
Botinator/README.md
T
ksan 64a472c540
CI/CD / build (push) Successful in 44s
CI/CD / deploy (push) Successful in 8s
fixed readme
2026-07-10 01:34:33 +02:00

5.1 KiB

Botinator

A hobby Discord bot for personal use. It's a small JDA bot with a few fun slash commands and music playback powered by Lavalink.

Personal project — not intended as a polished, general-purpose bot.

Commands

Command What it does
/hello Sanity-check greeting
/say <message> Bot repeats your message
/rolldice [sides] Roll a die (default 6 sides)
/armeter Measures your "AR" percentage (just for laughs)
/play <query> Play or queue a track/playlist by URL, or search text (YouTube)
/skip Skip the current track
/queue Show the queue as a paginated embed (◀/▶ buttons)
/loop [queue|song|off] Loop playback. Bare /loop toggles looping the whole queue; song loops just the current track; off stops looping
/clear Clear the queue (keeps the current track playing)

How it works

The bot is just a Lavalink client — actual audio is streamed by a separate Lavalink v4 server that runs alongside it (started with Docker). YouTube support comes from the youtube-plugin, configured in lavalink/application.yml.

  • Bot: Java + Gradle (JDA 6, lavalink-client)
  • Music server: Lavalink v4 via docker-compose.yaml

Requirements

  • A JDK (builds on Java 17+; CI and the Docker image use Java 25)
  • Docker + Docker Compose (to run the Lavalink server)
  • A Discord bot token

Configuration

Copy the example env file and fill in your values:

cp .env.example .env
Variable Required Description
BOT_TOKEN Discord bot token (Developer Portal → your app → Bot)
GUILD_ID optional Test server ID for instant command registration. If unset, commands register globally (can take up to an hour)
LAVALINK_URI optional Defaults to ws://localhost:2333 for local runs. In docker-compose.yaml the bot is pointed at ws://lavalink:2333 (the service name)
LAVALINK_PASSWORD Shared secret between the bot and the Lavalink server. Compose passes the same value to the server as LAVALINK_SERVER_PASSWORD, so they always match. The bot exits if it's unset

.env is gitignored, so your token stays local.

Running

./gradlew run reads real environment variables — it does not auto-load .env. So load it into your shell first.

# 1. Start ONLY the Lavalink server — not the bot container — so it doesn't clash
#    with the bot you're running from source. (First run downloads the YouTube
#    plugin; wait for "ready".)
docker compose up -d lavalink
docker compose logs -f lavalink   # wait for "Lavalink is ready to accept connections", then Ctrl+C

# 2. Load your .env and run the bot
set -a; source .env; set +a
./gradlew run

docker compose up -d (no service name) would start the bot container too, giving you two bots. For source development, always pass lavalink explicitly.

When it connects you'll see Bot connected and ready as ... in the console. Then join a voice channel in your server and try /play <song or url>.

TODO — steps to get it running

  • Install a JDK (17+) and Docker
  • Create a Discord application + bot, and copy the bot token
  • Invite the bot to your server with the bot and applications.commands scopes (and the Connect + Speak voice permissions)
  • Enable Developer Mode in Discord and copy your server's Guild ID
  • cp .env.example .env and fill in BOT_TOKEN, LAVALINK_PASSWORD (and GUILD_ID)
  • Start Lavalink only: docker compose up -d lavalink and wait until the logs say it's ready
  • Load env vars: set -a; source .env; set +a
  • Run the bot: ./gradlew run
  • In Discord, run /hello to confirm it responds, then /play from a voice channel

Run with Docker (prebuilt image)

If you'd rather not build from source, docker-compose.yaml pulls the prebuilt bot image and runs it alongside Lavalink. You only need Docker — no JDK.

  1. Create your config and the files the bot reads at runtime, next to the compose file:

    cp .env.example .env        # then fill in BOT_TOKEN and LAVALINK_PASSWORD
    

    Make sure catchphrases.txt, always100.txt, and always90.txt exist as files here. They're mounted into the container — if any is missing, Docker creates an empty directory in its place and the mount breaks.

  2. Pull and start both services:

    docker compose pull        # fetch the bot + Lavalink images
    docker compose up -d       # start in the background
    docker compose logs -f     # watch logs; look for "Bot connected and ready as ..."
    docker compose down        # stop
    

The bot connects to Lavalink over the internal Docker network automatically, so you don't set LAVALINK_URI yourself here.

Notes

  • Queue state is kept in memory, so it resets if the bot restarts.
  • YouTube occasionally breaks playback when Google changes its player. The fix is usually bumping the youtube-plugin version in lavalink/application.yml and restarting the server.