Play from YouTube, Spotify and Deezer straight into your voice channel. Autocomplete search, one player card per track, and nothing posted unprompted.
Deploy nowAudio never touches the main Python bot process. A dedicated Lavalink node handles decoding and playback streaming while Alfred manages your server requests.
Stream directly from YouTube, Spotify, and Deezer. Tracks, full albums, playlists, and raw audio URLs all resolve the same way.
Instant suggestions inside Discord's slash command input. Narrow by track, artist, album, or playlist before you ever hit enter.
One reactive card per track. Pause, Skip and cycle Loop from Discord buttons, and the card redraws in place on every press.
Every message is a reply to a command, or the now playing card that follows the current track. Alfred posts nothing else, ever.
Alfred disconnects the moment the last listener leaves, queue or no queue. It never lingers in an empty room holding a voice slot.
While a track plays, Alfred's status shows the song and artist under its name. A glance at the member list tells you what is on.
`/play` connects to your voice channel automatically - there is no `/join`. Loop and shuffle are options on the command rather than commands of their own. Try the buttons below to test the reactive panel state machine.
| Group | Command | Description |
|---|---|---|
| MUSIC | /play | Add track, playlist or URL to queue with auto voice join |
| MUSIC | /search | Live autocomplete across tracks, artists, and playlists |
| QUEUE | /now | Show the track playing right now as a card |
| QUEUE | /queue | Open the interactive button panel and track list |
| QUEUE | /skip | Move forward to the next queued track |
| QUEUE | /remove | Drop a specific track from the queue index |
| VOICE | /leave | Disconnect bot from voice and clear player state |
Alfred isolates control logic from audio transport, guaranteeing high responsiveness even under heavy server load.
flowchart TD
subgraph Discord["Discord Platform"]
User["User / Discord Client"]
VC["Voice Channel"]
end
subgraph Bot["Alfred Bot"]
Hikari["hikari Gateway & lightbulb"]
Service["Alfred Service & Player State"]
end
subgraph Node["Lavalink Audio Node (JVM)"]
Lavalink["Lavalink Server Engine"]
Plugins["LavaSrc · LavaSearch · YouTube Plugin"]
end
subgraph Daemon["Signature Daemon"]
Cipher["yt-cipher Container"]
end
subgraph Sources["Audio Sources"]
YT["YouTube"]
SP["Spotify"]
SC["SoundCloud / Deezer / Bandcamp"]
end
User -->|"Slash commands & panel buttons"| Hikari
Hikari --> Service
Service -->|"REST / WebSocket (lavalink.py)"| Lavalink
Lavalink --- Plugins
Plugins -->|"JavaScript decipher requests"| Cipher
Plugins -->|"Audio stream extraction"| Sources
Lavalink ==>|"Direct voice UDP stream"| VC
Choose Docker Compose for production deployments or uv for local development.
# 1. Clone & prepare environment files cp .env.example .env cp lavalink/application.yml.example lavalink/application.yml # 2. Set DISCORD_TOKEN & CIPHER_PASSWORD in .env # Linux permissions (first run only): chown -R 322:322 lavalink/logs lavalink/plugins # 3. Start all three services (yt-cipher, Lavalink, Alfred) docker compose up -d
yt-cipher, Lavalink, and the bot in ordered sequence. To rebuild after local edits, run docker compose up -d --build bot.
# Requires Java 21+ for Lavalink winget install --id Microsoft.OpenJDK.21 -e # Terminal 1: Run Lavalink node .\scripts\lavalink.ps1 # Terminal 2: Run Alfred bot with uv uv sync --frozen uv run alfred
LAVALINK_HOST=127.0.0.1. Run checks with uv run pytest and uv run ruff check ..
# Check VPS deployment guide for machine hardening & OAuth git clone https://github.com/nauqh/alfred.git /opt/alfred cd /opt/alfred # Follow docs/deploy.md for YouTube OAuth token generator # and systemd/docker restart configurations
/search returns nothing until clientId and clientSecret are set.deezer: true and an empty masterDecryptionKey, so enable it in the same edit that fills the key.
Production operations, how the codebase is put together, and the decisions behind it.
Step-by-step VPS server preparation, secrets management, automatic updates, and YouTube OAuth authentication.
The three-way split between the music layer, the UI layer and the commands, and the two rules that hold it together.
What is settled and why: the voice-receive limit, what was deliberately removed, and what not to re-open.