Initial commit: UMB Telegram Bot
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# UMB Bot - Agent Quickstart
|
||||
|
||||
## Environment & Setup
|
||||
- `source .venv/bin/activate` before running or testing anything
|
||||
- `.env` is gitignored; API keys and tokens live there (verified read-only)
|
||||
- Database: SQLite at `bot/data/umb.db`; initialized automatically on boot via `init_db()`
|
||||
- **Proxy required**: bot is designed for regions with Telegram blocks (Russia/CIS). All outbound traffic (Telegram API, OpenRouter model fetch, AI requests, Whisper model download) goes through SOCKS5 proxy configured in `.env` via `PROXY_ENABLED=true` and `PROXY_URL`.
|
||||
|
||||
## Exact Command to Run
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
No separate test/lint/formatter/config commands defined in repo.
|
||||
|
||||
## Architecture Snapshot
|
||||
- **Entry**: `main.py` → `asyncio.run(main())`
|
||||
- **Boot sequence**: `init_db()` → proxy setup (if enabled) → `dp.start_polling(bot)`
|
||||
- **Routers** (included in order in `main.py`):
|
||||
1. `moderation.py` — sticker/GIF flood detection (25 in 60s → 5min ban)
|
||||
2. `layout.py` — `/start`, `/res` (en→ru layout converter in `layout_converter.py`)
|
||||
3. `weather.py` — `/weather <city>` via OpenWeatherMap
|
||||
4. `ai.py` — `/ai`, `/aino`, `/aiyes` (AI assistant "Astra")
|
||||
5. `voice.py` — auto-transcribes all voice messages via local faster-whisper (no proxy needed)
|
||||
|
||||
## Voice Recognition
|
||||
- **Local**: faster-whisper model `base` (~2.5 GB) auto-downloaded on first voice message to `models/faster-whisper/` (portable, next to the bot)
|
||||
- **Model download**: uses `ALL_PROXY` env var + PySocks to route through SOCKS5 proxy
|
||||
- **Voice files**: temporarily stored in `bot/data/voice/`, deleted after transcription
|
||||
- **Flow**: download OGG from Telegram → ffmpeg to WAV → transcribe locally → post raw text to chat
|
||||
- **Normalization**: capitalize first letter, trailing period, collapse whitespace
|
||||
- **No proxy** used for actual transcription (fully local on CPU)
|
||||
|
||||
## AI Assistant "Astra" Gotchas
|
||||
- **Free models**: fetched dynamically from OpenRouter API (`:free` suffix), cached 1 hour. Fallback to hardcoded list if API unavailable.
|
||||
- **Paid fallback**: `routerai.ru` if all free fail (adds `⚡ Обработано через платный API` suffix)
|
||||
- **Context**: Last 10 messages per user/chat stored in SQLite (`user_context` table)
|
||||
- **System prompt**: brief, helpful, reply with "я потеряла мысль"/"смотри, какая птичка!" when context lost
|
||||
- **Block system**: `/aino @user` blocks 24h (creator only); `/aiyes @user` unblocks
|
||||
- **Rate-limit behavior**: automatically rotates models on 429 errors
|
||||
|
||||
## DB Tables (source of truth)
|
||||
- `user_context` — messages for AI context (user_id, chat_id, text, role, timestamp)
|
||||
- `ai_blocked_users` — AI bans (user_id, chat_id, blocked_by, blocked_at, expires_at)
|
||||
- `sticker_bans` — sticker flood bans (user_id, chat_id, count, start_time, ban_until, ban_trigger)
|
||||
|
||||
## Run on change
|
||||
1. Edit source
|
||||
2. Restart bot (`Ctrl+C` then `python main.py`)
|
||||
3. DB schema updates via `await init_db()` → `Base.metadata.create_all()` (no migrations)
|
||||
Reference in New Issue
Block a user