2026-05-19 14:28:40 -04:00
2026-04-08 09:15:01 -04:00
2026-04-08 09:15:01 -04:00
2026-04-05 10:49:22 -04:00
2024-10-13 20:24:05 -04:00
2026-04-08 09:15:01 -04:00
2026-05-19 14:28:40 -04:00
2026-04-04 12:22:17 -04:00
2026-04-04 14:33:07 -04:00
2026-04-04 12:22:17 -04:00
2026-04-04 12:22:17 -04:00
2026-04-08 09:15:01 -04:00
2026-04-03 23:04:51 -04:00
2026-04-05 10:49:22 -04:00

Siren

Siren

A D&D-focused Discord bot written in Rust


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

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

  1. Visit the Discord Developer Portal and create a new application.

  2. 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.

    Token location

  3. 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

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 <0100> 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
No description provided
Readme 2.9 MiB
Languages
Rust 48.4%
TypeScript 40.8%
CSS 10%
Dockerfile 0.5%
JavaScript 0.2%