# Djimbo Template для Telegram-ботов на aiogram 3 Шаблон для быстрого старта Telegram-бота на `aiogram 3`, `SQLAlchemy`, `aiosqlite`, `Alembic` и `.env`-настройках через `pydantic-settings`. Внутри уже есть базовая структура проекта, подключение роутеров, middleware для пользователя, админские фильтры, логирование, миграции БД и пример пользовательского/админского меню. ## Стек - Python 3.11 - aiogram 3.28.2 - SQLAlchemy 2.x - aiosqlite - Alembic - APScheduler - aiohttp - pydantic-settings - pytz ## Быстрый старт 1. Создание виртуального окружения: ```bash python3.11 -m venv .venv source .venv/bin/activate ``` 2. Установка зависимостей: ```bash pip install -r requirements.txt ``` 3. Создание локального конфига: ```bash cp .env.example .env ``` 4. Заполнение `.env`: ```env BOT_TOKEN=123456:telegram_bot_token BOT_ADMIN_IDS=123456789 BOT_DATABASE_EXPORT=False ``` `BOT_ADMIN_IDS` можно указать через запятую: `123456789,987654321`. 5. Применение миграций: ```bash python migrate.py up ``` Без аргументов `python migrate.py` только показывает подсказки. Бот сам миграции при старте не запускает, чтобы не менять схему базы неожиданно. 6. Запуск бота: ```bash python main.py ``` ## Docker Compose Запуск через compose: ```bash docker compose up --build ``` Остановка: ```bash docker compose down ``` `docker-compose.yml` использует `Dockerfile`: Dockerfile собирает образ, а compose управляет запуском, `.env`, volume и restart-политикой. При запуске контейнер сначала применяет миграции командой `python migrate.py up`, а потом запускает бота через `python main.py`. Volume `./tgbot/data:/app/tgbot/data` нужен, чтобы база и логи не пропадали после остановки контейнера. Если compose не нужен, можно запустить Docker вручную: ```bash docker build -t djimbo-template . docker run --rm --env-file .env -v "$(pwd)/tgbot/data:/app/tgbot/data" djimbo-template ``` ## pyproject.toml `pyproject.toml` описывает проект для современных Python-инструментов. В этом шаблоне он нужен для: - указания версии Python; - описания зависимостей проекта; - установки проекта как пакета через `pip install -e .`; - настройки сборки через `setuptools`. `requirements.txt` оставлен для простого запуска и Docker. Если коротко: `requirements.txt` удобен для установки зависимостей, а `pyproject.toml` описывает сам проект. ## Настройки | Параметр | Что делает | | --- | --- | | `BOT_TOKEN` | Токен Telegram-бота от BotFather | | `BOT_ADMIN_IDS` | Telegram ID админов, один или несколько через запятую | | `BOT_DATABASE_EXPORT` | Разрешает отправку файла БД админам через `/db` и ежедневный автобэкап | | `BOT_STATUS_NOTIFICATION` | Включает уведомление админов о запуске | | `BOT_TIMEZONE` | Временная зона бота | | `BOT_USER_CACHE_TTL` | Время кеширования пользователя в middleware | | `BOT_THROTTLE_RATE` | Базовая задержка антиспама | | `PATH_DATABASE` | Путь к SQLite-базе | | `PATH_LOGS` | Путь к файлу логов | По умолчанию `BOT_DATABASE_EXPORT=False`. Это специально: база может содержать персональные данные, поэтому экспорт надо включать руками и осознанно. ## Структура проекта ```text . ├── main.py # Точка входа ├── migrate.py # Удобная CLI-обертка для Alembic ├── Dockerfile # Запуск шаблона в Docker ├── docker-compose.yml # Удобный запуск Docker-контейнера ├── .dockerignore # Что не попадет в Docker-образ ├── pyproject.toml # Метаданные проекта ├── alembic.ini # Настройки Alembic ├── migrations/ # Миграции базы данных ├── .env.example # Пример локального .env ├── tgbot/ │ ├── data/config.py # Настройки и пути │ ├── database/ # SQLAlchemy-модели и репозитории │ ├── keyboards/ # Reply и inline-клавиатуры │ ├── middlewares/ # Middleware │ ├── routers/ # Обработчики aiogram │ ├── services/ # Внешние сервисы и aiohttp-сессия │ └── utils/ # Общие утилиты └── requirements.txt ``` ## База данных Проект использует SQLite через `aiosqlite`, но работа с таблицами идёт через async `SQLAlchemy`. Ключевые файлы БД: - `core.py` - `Base`, `engine`, `session_factory`, `session_scope` - `repository.py` - базовый репозиторий и проверка готовности БД - `migration_runner.py` - запуск Alembic из кода - `db_users.py` - пользователи Telegram - `db_settings.py` - настройки бота в БД ### UNIQUE В таблице пользователей поле `user_id` уникальное. Это значит, что один Telegram-пользователь не может появиться в таблице два раза. Если пользователь уже есть, база не создаст дубль. ### UPSERT UPSERT - это логика “создай запись, а если она уже есть, обнови”. В шаблоне пользователь добавляется по `user_id`. Если он уже есть, обновляются только изменившиеся поля: username, имя, фамилия и полное имя. Если данные не поменялись, лишнего UPDATE в БД не будет. ## Миграции Миграции управляются через Alembic, но запускать их удобнее через готовый CLI. Показать справку: ```bash python migrate.py ``` Применить все миграции: ```bash python migrate.py up ``` То же самое длинной командой: ```bash python migrate.py upgrade ``` Посмотреть текущую версию БД: ```bash python migrate.py status ``` Посмотреть историю: ```bash python migrate.py history ``` Создать новую миграцию вручную: ```bash python migrate.py new "add payments table" ``` Создать миграцию по изменениям SQLAlchemy-моделей: ```bash python migrate.py auto "add payments table" ``` Откатить последнюю миграцию: ```bash python migrate.py down ``` Полные Alembic-команды тоже доступны: `upgrade`, `downgrade`, `revision`, `current`, `history`, `heads`. Короткие алиасы: `up`, `down`, `new`, `auto`, `autogen`, `cur`, `hist`, `st`. ## Роутеры Роутеры подключаются в `tgbot/routers/__init__.py`. Текущие группы: - `main_start.py` - старт и главное меню - `user/user_menu.py` - пользовательские обработчики - `admin/admin_menu.py` - админские обработчики - `main_missed.py` - fallback на неизвестные сообщения и callback - `main_errors.py` - обработка безопасных Telegram-ошибок Админский роутер уже закрыт фильтром `IsAdmin()` и для сообщений, и для callback query. ## Middleware `ExistsUserMiddleware` добавляет или обновляет пользователя в БД и прокидывает объект пользователя в обработчик как `User`. Чтобы не писать в БД на каждый одинаковый update, middleware кеширует пользователя по `user_id`. Пример: ```python async def handler(message: Message, User: UserModel): await message.answer(User.user_fullname) ``` ## Логирование Логи пишутся в `tgbot/data/logs.log`. Файл не растёт бесконечно: используется `RotatingFileHandler`, который вращает логи по размеру. Админ может получить логи командой: ```text /log ``` Очистить логи: ```text /clear_log ``` ## Админские команды | Команда | Что делает | | --- | --- | | `/log` | Отправляет файл логов | | `/clear_log` | Очищает файлы логов | | `/db` | Отправляет файл БД, только если `BOT_DATABASE_EXPORT=True` | Команда `/db` скрывается из меню команд, если экспорт БД выключен. ## Как добавить новую таблицу 1. Создать модель в `tgbot/database/`. 2. Импортировать её в `tgbot/database/__init__.py`. 3. Создать миграцию: ```bash python migrate.py auto "add new table" ``` 4. Проверить созданный файл в `migrations/versions/`. 5. Применить миграцию: ```bash python migrate.py up ``` ## Важно - Не коммить `.env`, базу данных и логи. - Если токен попал в Git, его надо перевыпустить у BotFather. - Перед деплоем проверь `BOT_DATABASE_EXPORT`: на проде лучше держать `False`, если экспорт БД реально не нужен. - Для нового проекта сначала менять тексты, команды и клавиатуры под свою логику, а потом уже добавлять бизнес-код.