13 KiB
13 KiB
UMB — это Telegram-бот для модерации стикеров/GIF, восстановления раскладки, получения погоды и общения с AI-ассистентом Астра.
✨ Функции
- 🛡️ Модерация стикеров и GIF — если пользователь отправляет 25+ стикеров/GIF за 60 секунд, бот удаляет все последующие стикеры и GIF от этого пользователя в течение 5 минут. Текстовые сообщения не затрагиваются.
- ⌨️ Восстановление раскладки (
/res) — ответьте командой/resна сообщение с текстом в неправильной раскладке, и бот переведёт его (например,gbdj→пиво). - 🌤️ Погода (
/weather) — покажет подробную погоду в указанном городе через OpenWeatherMap API. - 🤖 AI-ассистент "Астра" (
/ai) — задайте вопрос, ответьте командой/aiна сообщение или перешлите сообщение, и Astra проанализирует его с учётом контекста и ранее сохранённых выжимок диалогов. - 💬 Диалог с Астрой — после
/aiбез вопроса начинается диалог. Отвечайте на сообщения бота, чтобы продолжать.- Фаза 1: до 50 сообщений.
- Фаза 2: дополнительно до 20 сообщений.
- После исчерпания лимита — перерыв 1 час.
- 🔒 Управление AI (
/aino,/aiyes) — владелец чата может заблокировать/разблокировать пользователя от AI. - 🧦 Поддержка SOCKS5 прокси — настраивается через
.env.
🏗️ Структура проекта
umb/
├── .env # настройки: токен, прокси, API ключи
├── .gitignore
├── requirements.txt
├── main.py # точка входа
├── config.py # конфигурация
├── Dockerfile
├── docker-compose.yml
└── bot/
├── __init__.py
├── bot.py # инициализация бота и сессии
├── setup_commands.py # меню команд
├── routers/
│ ├── __init__.py
│ ├── moderation.py # роутер модерации стикеров/GIF
│ ├── layout.py # роутер /start, /res
│ ├── weather.py # роутер /weather
│ ├── ai.py # роутер /ai, /aino, /aiyes, /aiclear, /aiuser
│ ├── dialogue.py # диалоговый режим с Астрой
│ ├── voice.py # распознавание голосовых сообщений
│ └── yadisk.py # скачивание с Яндекс.Диска
└── utils/
├── __init__.py
├── proxy.py # общий SOCKS5-коннектор
├── layout_converter.py # конвертер раскладки en→ru
├── weather.py # функция получения погоды
├── ai_client.py # OpenRouter/RouterAI клиент
├── memory.py # саммари и эмбеддинги
├── database.py # SQLAlchemy модели и функции БД
├── voice.py # загрузка и транскрибация голоса
├── yadisk_download.py # загрузка файлов с Яндекс.Диска
├── s3_client.py # загрузка больших файлов в S3
└── logging_config.py # настройка логирования
📊 Системные требования
Память (RAM)
| Компонент | Расход |
|---|---|
Whisper base (int8) в памяти |
~600–900 МБ |
| Whisper пик при транскрибации | дополнительно ~200–400 МБ |
| aiogram + SQLAlchemy + aiohttp | ~100–200 МБ |
| SQLite | ~10–50 МБ |
| ffmpeg (пиково) | ~50–100 МБ |
| Рекомендуемый минимум | 2 ГБ |
| Без распознавания голоса | ~512 МБ |
Процессор
| Параметр | Значение |
|---|---|
| Количество ядер | минимум 2, рекомендовано 4+ |
| Нагрузка при транскрибации | ~80–100% на 4 ядрах на 2–8 сек |
| Нагрузка в простое | ~1–5% |
| Архитектура | x86_64 / ARM64 |
Без голосовых сообщений достаточно 1 ядра.
Диск
| Данные | Размер |
|---|---|
Whisper base модель |
~500 МБ на диске |
| SQLite база | ~50–200 МБ (растёт со временем) |
| Голосовые файлы (временно) | ~1–5 МБ на сообщение, удаляются сразу |
| Логи (ротация 5×10 МБ) | ~50–100 МБ |
| Рекомендуемое свободное место | 5–10 ГБ |
Сеть
- Пропускная способность: минимальная (несколько КБ/с в среднем).
- Все API-запросы могут идти через SOCKS5-прокси.
- Для скачивания Whisper-модели через прокси: ~150 МБ одним файлом, нужна стабильность.
Итого
| Ресурс | Минимум | Рекомендовано |
|---|---|---|
| RAM | 2 ГБ | 4 ГБ |
| CPU | 2 ядра | 4+ ядра |
| Disk | 5 ГБ | 10 ГБ |
| ОС | Linux (x86_64) | то же, Python 3.11 |
🚀 Установка
cd umb
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
⚙️ Настройка
Откройте .env и укажите необходимые ключи:
BOT_TOKEN=your_bot_token_here
PROXY_ENABLED=false
PROXY_URL=socks5://user:pass@host:port
API_WEATHER=your_openweather_api_key
OPENROUTER_API_KEY=your_openrouter_api_key
ROUTERAI_API_KEY=your_routerai_api_key
ROUTERAI_BASE_URL=https://routerai.ru/api/v1
# Опционально: периодическая проверка работоспособности бесплатных моделей.
# Внимание: проверка расходует токены API. По умолчанию отключена.
AI_HEALTH_CHECK_ENABLED=false
AI_HEALTH_CHECK_INTERVAL=600
# Настройки модели Whisper для распознавания голоса.
WHISPER_MODEL_SIZE=base
WHISPER_MIN_FREE_SPACE_BYTES=5368709120
Для включения прокси установите PROXY_ENABLED=true и укажите корректный PROXY_URL.
▶️ Запуск
source .venv/bin/activate
python main.py
🐳 Запуск в Docker
docker compose up -d --build
Модели Whisper сохраняются в ./models, база данных и логи — в ./bot/data.
🎙️ Распознавание голосовых сообщений
Бот автоматически распознаёт все голосовые сообщения с помощью локальной модели faster-whisper.
Поведение загрузки модели
- При запуске бота проверяется наличие модели в
./models/faster-whisper/<WHISPER_MODEL_SIZE>/. - Если модель уже скачана — бот сразу готов к работе.
- Если модели нет — бот проверяет свободное место на диске и скачивает модель автоматически перед началом polling.
- Для скачивания используется прокси из
.env, еслиPROXY_ENABLED=true.
Требования к месту
| Модель | Размер модели | Рекомендуемое свободное место |
|---|---|---|
base |
~150 MB архив, ~500 MB на диске | 5 GB (WHISPER_MIN_FREE_SPACE_BYTES=5368709120) |
small |
~500 MB архив, ~1.5 GB на диске | 5 GB+ |
medium |
~1.5 GB архив, ~5 GB на диске | 10 GB+ |
💡 По умолчанию используется модель
base. Для смены модели изменитеWHISPER_MODEL_SIZEв.env.
Логирование
В логах будет видно:
Free disk space: 45.23 GB, required: 5.00 GB
Whisper model 'base' found locally at /app/models/faster-whisper/base
Whisper model 'base' is ready
или при скачивании:
Whisper model 'base' not found locally. Starting download to /app/models/faster-whisper...
Whisper model 'base' downloaded and loaded in 125.4s
Whisper model 'base' is ready
🧪 Тесты
source .venv/bin/activate
pytest tests/ -v
📋 Команды
| Команда | Описание |
|---|---|
/start |
Приветствие и информация о боте |
/res |
Восстановить раскладку (ответить на сообщение) |
/weather <город> |
Погода в указанном городе |
/ai <вопрос> |
Задать вопрос Астре |
/ai (ответом/пересылкой) |
Проанализировать сообщение |
/ai (без вопроса) |
Начать диалоговый режим |
/aiclear |
Очистить диалог и сохранить выжимку |
/aiuser |
Список пользователей чата (только creator) |
/aino @username |
Заблокировать пользователя от AI (только creator, 24ч) |
/aiyes @username |
Разблокировать пользователя от AI (только creator) |
/ydf <ссылка> |
Скачать файл с Яндекс.Диска |
/ydf (new) <ссылка> |
Скачать файл, игнорируя кеш Telegram |
⚖️ Настройки модерации
Изменяются в config.py:
MODERATION_LIMIT = 25— количество стикеров/GIF за окноMODERATION_WINDOW = 60— окно подсчёта в секундахMODERATION_BAN_DURATION = 300— длительность бана в секундах
🧠 AI-ассистент "Астра"
- Бесплатные модели (OpenRouter): пробует по очереди доступные модели с суффиксом
:free. При rate-limit автоматически переключается на следующую. - Платный fallback (RouterAI): если все бесплатные модели недоступны, используется
deepseek/deepseek-v4-flashчерезrouterai.ru. В ответе добавляется уведомление⚡ Обработано через платный API. - Контекст: хранит последние 10 сообщений каждого пользователя в SQLite.
- Долгосрочная память: при переходе между фазами диалога и при
/aiclearсоздаётся краткая выжимка, которая затем подбирается по смыслу к новым вопросам. - Стиль: отвечает кратко и по делу, если не просят развёрнуто.
- Потеря контекста: говорит что-то милое ("я потеряла мысль", "смотри, какая птичка!")
Сделано с помощью aiogram · SQLAlchemy · faster-whisper