# 🤖 UMB — Telegram Bot **Универсальный бот-модератор с AI-ассистентом "Астра"** [![License: MIT](https://img.shields.io/badge/license-MIT-lightgrey.svg)](LICENSE) [![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg)](https://www.python.org/) [![aiogram 3.x](https://img.shields.io/badge/aiogram-3.x-2CA5E0.svg)](https://docs.aiogram.dev/) [![SQLite](https://img.shields.io/badge/sqlite-async-003B57.svg)](https://www.sqlite.org/) [![Docker](https://img.shields.io/badge/docker-ready-2496ED.svg)](https://www.docker.com/) [![Tests](https://img.shields.io/badge/tests-pytest-brightgreen.svg)](tests/) [![SOCKS5 Proxy](https://img.shields.io/badge/proxy-SOCKS5-orange.svg)](#настройка)
--- 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 # настройка логирования ``` ## 🚀 Установка ```bash cd umb python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` ## ⚙️ Настройка Откройте `.env` и укажите необходимые ключи: ```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`. ## ▶️ Запуск ```bash source .venv/bin/activate python main.py ``` ## 🐳 Запуск в Docker ```bash docker compose up -d --build ``` Модели Whisper сохраняются в `./models`, база данных и логи — в `./bot/data`. ## 🎙️ Распознавание голосовых сообщений Бот автоматически распознаёт все голосовые сообщения с помощью локальной модели [faster-whisper](https://github.com/SYSTRAN/faster-whisper). ### Поведение загрузки модели - При запуске бота проверяется наличие модели в `./models/faster-whisper//`. - Если модель уже скачана — бот сразу готов к работе. - Если модели нет — бот проверяет свободное место на диске и **скачивает модель автоматически** перед началом 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 ``` ## 🧪 Тесты ```bash 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](https://docs.aiogram.dev/) · [SQLAlchemy](https://www.sqlalchemy.org/) · [faster-whisper](https://github.com/SYSTRAN/faster-whisper)