# Senator Sperma (Rust) A Discord bot rebuilt in Rust from the original Python implementation. Music playback via songbird, AI chat via OpenRouter or anything OpenAI compatible (ollama.cpp and such), TTS, web/file search scheduled jobs, per-server triggers, QR codes, media conversion, and misc utilities. Built on poise 0.6 + serenity 0.12 + songbird 0.6, with async SQLite (sqlx 0.9) for persistence. ## Setup ### 1. Clone ```bash git clone https://codeberg.org/salmonik/senator-sperma cd senator-sperma ``` ### 2. System Dependencies The following binaries must be available on `PATH`: - `ffmpeg` — audio decoding/encoding for playback, conversion, and compression - `qalc` (Qalculate) — used by `/math` to evaluate expressions - `yt-dlp` (optional) — used by `/download` Unlike the Python version, QR encode/decode is handled by the pure-Rust `qrcode`/`rxing` crates — no `zbar` system library required. ### 3. Build Requires a recent Rust toolchain (edition 2024). ```bash cargo build --release ``` ### 4. Configure Environment Create a `.env` in the project root look at `.env.example` on what to put there On launch, missing variables are reported via tracing (`error!` for required, `warn!` for optional with defaults). The database and schema migrations are created automatically on first run. ### 5. Run ```bash cargo run --release ``` ## Commands Slash commands are autoregistered globally on startup. Some are registered under their original Polish verb names to match the UI expected by existing servers. ### AI - `/senator` — chat with the OpenRouter model ### Music (songbird) - `/grajcuj` — play from Copyparty search, a direct URL, or an uploaded file - `/stop` — stop playback and leave voice - `/join` — join the caller's voice channel ### TTS - `/tts` — Google Translate TTS (Polish), sent as a file or played in voice ### Search & Web - `/web` — DuckDuckGo HTML scrape (soon to use 4get) - `/search` — search Copyparty and return a direct download URL - `/download` — fetch media from any yt-dlp-supported URL ### Media Tools - `/compress` (alias `kompresja`) — compress a media attachment to low quality - `/convert` (alias `konwersja`) — convert media between formats ### Utilities - `/upload` — push Discord attachments into Copyparty - `/say` — repeat the given text as the bot - `/math` — evaluate an ASCII math expression through `qalc` - `/qr generowanie` / `/qr dekodowanie` — QR encode / decode ### Triggers - `/trigger create` — new trigger group - `/trigger add` — add keywords/responses to a group - `/trigger remove` — remove a keyword/response - `/trigger delete` — delete a group - `/trigger list` — list a group's keywords and responses - `/trigger help` — usage info ### Cron - `/cron dodaj_audio` — schedule audio playback - `/cron dodaj_wiadomość` — schedule a periodic message - `/cron pokaż` — list all cron jobs - `/cron usuń` — remove a cron job - `/cron pauza` — pause a job - `/cron wznów` — resume a job ### Message Context Menu - "Wyślij załączniki" (right-click message) — upload attachments to Copyparty - "kompresja" (right-click message) — compress all attachments ## Architecture The runtime is organised around a shared `Data` struct (poise `user_data`) that holds the DB pool, HTTP client, Copyparty client, voice manager, the in-memory trigger cache, autocomplete cache, and per-guild music track handles. - `src/main.rs` — boot: tracing, dotenvy, Config, DB pool, framework, cron task - `src/config.rs` — env-driven `Config` + variable validation - `src/commands/` — one module per command group - `src/copyparty/` — Copyparty search/upload client - `src/openrouter/` — OpenRouter chat client - `src/database/` — sqlx pool, migrations, query helpers (6 tables) - `src/voice/` — `VoiceManager`, mp3 → songbird input - `src/events/` — `handle_ready`, voice-state, message (trigger matching) - `src/tasks/` — 30s cron scheduler poll loop - `src/lang.rs` — user-facing Polish strings All temporary files go through `crate::config::TEMP_PATH` (`/tmp/senator_sperma`).