Skip to content

About

A hassle-free, highly performant, host-it-yourself Discord music bot with YouTube and Spotify support. Powered by yt-dlp and crackling Rust code.

Topics

Resources

Stars

26 stars

Watchers

2 watching

Forks

Latest commit

 

History

802 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CrackTunes

A hassle-free, highly performant, host-it-yourself, cracking smoking Discord music bot

builds.sr.ht status GitHub CI workflow status Dependency status MIT License Rust Version

Aknowledgements

Thanks to the guys over at alwaysdata for hosting the website, web portal, email, etc for this project for free, in their Open Source program.

Deployment

Usage

  • Create a bot account.
  • Put its token in a .env as DISCORD_TOKEN. That is the only required variable — the bot starts and plays music with nothing else set.

Everything below is optional, and the bot degrades rather than failing without it:

variable what you lose without it
DATABASE_URL play history, track reactions, playlist storage, guild settings that survive a restart, /gp games that survive one too, and the autoplay cache
SLEEVENOTE_BASE_URL Spotify links in /play, /gp submit, /spotify and /playlist loadspotify
MUSICATLAS_API_KEY musicatlas as autoplay's last resort, asked only when YouTube's Mix and Deezer both have nothing. It also needs DATABASE_URL, where its daily budget is counted
OPENAI_API_KEY ChatGPT commands
VIRUSTOTAL_API_KEY OSINT URL checking

COMMAND_REGISTRATION decides how the slash commands reach Discord. global, the default, registers every command globally at startup. manual registers only /register globally, for members with Manage Server: a server gets the rest when one of them runs /register and presses Register in guild, and keeps them (refreshed at each startup) until Delete in guild. Before switching a bot back to global, press Delete in guild in each server that registered, while it is still manual: those servers keep their own copy of the commands, and Discord would show every command twice. TuneTitan, the beta bot, runs manual, so it only shows up in the servers testing it.

Autoplay (/autoplay) is off by default and lasts until the bot restarts. It picks the next track from the one that just ended: YouTube's own Mix for that video first (listed through yt-dlp, which playback already needs), then Deezer's radio for its artist, then musicatlas when MUSICATLAS_API_KEY and a database are both set. None of them needs Spotify, and only musicatlas needs a key.

Spotify needs no credentials. It is served by sleevenote rather than the Spotify Web API — which matters, because Spotify stopped accepting new Web API app registrations around December 2025, so SPOTIFY_CLIENT_ID and SPOTIFY_CLIENT_SECRET are not obtainable for a new self-hoster even if the old path were still wanted.

What it does need is somewhere to reach sleevenote. SLEEVENOTE_BASE_URL defaults to http://127.0.0.1:3000, which is right if you run the service beside the bot and wrong everywhere else — in Docker Compose, for instance, the bot's own localhost is not the sleevenote container. Without it a Spotify link says Spotify support is not set up, and the rest of the bot is unaffected: searches and YouTube links play as normal.

Spotify is never the audio source, with or without it. sleevenote supplies the title and artists; the track itself is found on YouTube, so a Spotify link plays whatever YouTube has. Local files in a playlist cannot be resolved at all, and podcast episodes are skipped rather than guessed at.

DATABASE_URL is the only database variable the bot reads. If you run the bundled Postgres from docker-compose-postgres.yml, POSTGRES_USER and POSTGRES_PASSWORD configure that container — the official Postgres image reads them, the bot does not.

Use .env.example as a starting point.

Prebuilt binaries

No Docker, no Rust toolchain. Each release publishes a static x86_64-unknown-linux-gnu build with an installer script and a .sha256 alongside it:

curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/cycle-five/cracktunes/releases/latest/download/cracktunes-installer.sh | sh

Or take the tarball directly from the latest release if you would rather read the script first, or check the .sha256 before running anything. crack-testing and crack-voting ship the same way.

You still need a .env with DISCORD_TOKEN, and yt-dlp on PATH for playback.

Docker

A single image, no database of your own to run:

docker run -d --env-file .env --restart unless-stopped --name cracktunes ghcr.io/cycle-five/cracktunes:latest

Images are published by CI to ghcr.io/cycle-five/cracktunes. Tagged releases get version tags; branch builds get floating ones.

Docker Compose (the full stack)

Use scripts/cracktunes.sh rather than driving docker compose directly — it pins the project name and env file, and refuses on the failure modes that are otherwise silent (wrong Docker context, database password divergence, missing external volumes, missing DISCORD_TOKEN).

cp .env.example .env          # then fill it in
./scripts/cracktunes.sh preflight   # verify without changing anything
./scripts/cracktunes.sh up

To ship a new version, deploy (pull + recreate) rather than restart (recreate only, picks up no new code):

./scripts/cracktunes.sh deploy
./scripts/cracktunes.sh logs cracktunes

./scripts/cracktunes.sh help lists everything. See scripts/README.md for what the other scripts in that directory are, and which of them are broken.

Development

Make sure you've installed Rust. You can install Rust and its package manager, cargo by following the instructions on https://rustup.rs/. After installing the requirements below, simply run cargo run.

Linux/MacOS FIXME

The commands below install a C compiler, GNU autotools and FFmpeg, as well as yt-dlp through Python's package manager, pip.

Linux FIXME

apt install build-essential autoconf automake libtool ffmpeg
pip install -U yt-dlp

MacOS FIXME

brew install autoconf automake libtool ffmpeg
pip install -U yt-dlp

Windows FIXME

If you are using the MSVC toolchain, a prebuilt DLL for Opus is already provided for you.
You will only need to download FFmpeg, and install yt-dlp which can be done through Python's package manager, pip.

pip install -U yt-dlp

If you are using Windows Subsystem for Linux (WSL), you should follow the Linux/MacOS guide, and, in addition to the other required packages, install pkg-config, which you may do by running:

apt install -y pkg-config

Testing

Tests run with cargo-nextest; doctests, which it skips, run with cargo test --doc:

cargo nextest run --workspace
cargo test --doc --workspace

The database tests, template databases, mutation testing and the rest are in docs/testing.md. It's recommended that you run the tests before submitting a Pull Request. Increasing the test coverage is also welcome.

Coverage is measured with cargo-llvm-cov, weekly in CI (.github/workflows/coverage.yml). To measure locally, with a postgres running, use the cargo llvm-cov nextest command in docs/testing.md.

Linting

cargo clippy --all --all-targets -- -D warnings

Build

cargo +nightly build --profile=release --features crack-osint,crack-bf --workspace --locked

Distribution

cargo dist init --hosting github
# make change `pr-run-mode = "upload"`
git add .
git commit -am "chore: cargo-dist"
cargo dist build --profile=release --features crack-bf,crack-osint

Release

git tag vX.X.X
git push --tags

# publish to crates.io (optional)
cargo publish

Building the image locally

docker build -t cracktunes .

Note that docker-compose.yml references the published ghcr.io/cycle-five/cracktunes:master image, not a locally built one — so building with the tag above does not change what docker compose up runs. Retag it or edit the compose file if you want your local build in the stack. Deploying is covered under Deployment above.

Originally forked from Parrot

About

A hassle-free, highly performant, host-it-yourself Discord music bot with YouTube and Spotify support. Powered by yt-dlp and crackling Rust code.

Topics

Resources

Stars

26 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages