Features
- Music playback from YouTube via slash commands
- Dice rolling with D&D notation (e.g.
/roll 2d6+3) - Session scheduling
- REST API with OAuth2 authentication
Prerequisites
Running with Docker (recommended)
| Tool | Notes |
|---|---|
| Docker | Required |
| Task | Optional — used to run convenience commands |
Running locally (development)
| Tool | Notes |
|---|---|
| Rust | Stable toolchain |
| yt-dlp | Audio source extraction |
| ffmpeg | Audio transcoding |
| Docker | Used to run PostgreSQL and Valkey |
| Task | Optional — used to run convenience commands |
yt-dlp note: Keep yt-dlp up to date. YouTube frequently rotates its player, and an outdated yt-dlp will fail to resolve stream URLs.
Configuration
Copy .env.example to .env and fill in the required values:
cp .env.example .env
# or using Task:
task setup
Environment variables
| Variable | Required | Description |
|---|---|---|
DISCORD_BOT_TOKEN |
Yes | Bot token from the Discord Developer Portal |
DISCORD_CLIENT_SECRET |
Yes | OAuth2 client secret |
JWT_SECRET |
Yes | Secret used to sign JWT tokens — change from default |
POSTGRES_USER |
Yes | PostgreSQL username |
POSTGRES_PASSWORD |
Yes | PostgreSQL password — change from default |
POSTGRES_DB |
Yes | PostgreSQL database name |
POSTGRES_HOST |
Yes | PostgreSQL host (localhost for local dev, siren-postgres in Docker) |
POSTGRES_PORT |
PostgreSQL port (default 5432) |
|
VALKEY_HOST |
Valkey host (localhost for local dev, siren-valkey in Docker) |
|
VALKEY_PORT |
Valkey port (default 6379) |
|
API_BASE_URL |
Yes | Base URL of the API (e.g. http://localhost:3000) |
API_PORT |
Port the REST API listens on (default 3000) |
|
API_SESSION_TTL |
OAuth2 session TTL in seconds (default 86400) |
|
CORS_ORIGIN |
Allowed CORS origin (* for dev, specific URL for production) |
|
UI_PORT |
Port the UI dev server listens on (default 5173) |
|
RUST_LOG |
Log filter (e.g. warn,siren=info) |
|
FORCE_COMMAND_REGISTER |
Re-register slash commands with Discord on every startup (true/false) |
|
DATA_DIR_PATH |
Path to optional local data directory | |
DEFAULT_API_KEY |
Seed API key created on startup | |
DEFAULT_GUILD_ID |
Seed Discord guild (server) ID | |
DEFAULT_USER_ID |
Seed Discord user ID |
Discord Application Setup
-
Visit the Discord Developer Portal and create a new application.
-
Go to the Bot tab:
- Click Reset Token to generate your bot token — this is your
DISCORD_BOT_TOKEN. - Enable Message Content Intent under Privileged Gateway Intents.
- Click Reset Token to generate your bot token — this is your
-
Go to the OAuth2 tab to find your Client Secret (
DISCORD_CLIENT_SECRET).
Invite the bot to your server
Required scopes: bot, applications.commands
Required permissions:
| Category | Permissions |
|---|---|
| General | Manage Roles, Change Nickname, View Channels, Manage Events, Create Events |
| Text | Send Messages, Create Public/Private Threads, Send Messages in Threads, Manage Messages, Manage Threads, Embed Links, Attach Files, Read Message History, Mention Everyone, Use External Emojis/Stickers, Add Reactions, Create Polls |
| Voice | Connect, Speak |
Use this invite URL (replace <CLIENT_ID> with your Application ID from the General Information tab):
https://discord.com/oauth2/authorize?client_id=<CLIENT_ID>&permissions=581083641408576&integration_type=0&scope=bot+applications.commands
Running
Docker (recommended)
Build and start all containers:
# Build the Docker image
task docker:build
# or: docker build -f Dockerfile -t siren:latest .
# Start all services (postgres, valkey, and the app)
task docker:up:all
# or: docker compose --profile app up -d
To stop everything:
task docker:down
# or: docker compose --profile app down
Local development
Start the backing services (PostgreSQL and Valkey) in Docker, then run the bot natively:
# Start only the infrastructure containers
task docker:up
# or: docker compose up -d
# Run the bot locally with trace-level logging
task run
# or: cargo run
Commands
Siren uses Discord slash commands.
Music
| Command | Description | Status |
|---|---|---|
/play <track> |
Play a track from YouTube | Done |
/pause |
Pause the current track | Done |
/resume |
Resume the current track | Done |
/skip |
Skip to the next track | Done |
/stop |
Stop playback and clear the queue | Done |
/mute |
Mute/unmute the bot | Done |
/volume <0–100> |
Set the playback volume | Done |
/queue |
Display the current queue | Done |
/nowplaying |
Display the currently playing track | Planned |
/shuffle |
Shuffle the queue | Planned |
/loop |
Toggle looping the current track | Planned |
/clear |
Clear the queue | Planned |
Events
| Command | Description | Status |
|---|---|---|
/schedule |
Schedule a new event | Planned |
/events |
Display all scheduled events | Planned |
Fun
| Command | Description | Status |
|---|---|---|
/roll <dice> |
Roll dice (e.g. 2d6+3) |
Done |
/requestroll <user> <dice> |
Request a dice roll from another user | Done |
Utility
| Command | Description | Status |
|---|---|---|
/ping |
Check the bot's latency | Done |
/help |
Display available commands | Planned |
Development
| Task | Command |
|---|---|
| Type-check (fast) | task check |
| Debug build | task build |
| Release build | task release |
| Run with trace logging | task run |
| Format code | task format |
| Lint (Clippy) | task lint |
| Clean build artifacts | task clean |
| Connect to database | task psql |
Run task with no arguments to list all available tasks.
Description
Languages
Rust
48.4%
TypeScript
40.8%
CSS
10%
Dockerfile
0.5%
JavaScript
0.2%

