1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
# 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`).
|