Files
Bot-Template/README.md
T
2026-05-29 09:51:18 +03:00

303 lines
11 KiB
Markdown

# 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`, если экспорт БД реально не нужен.
- Для нового проекта сначала менять тексты, команды и клавиатуры под свою логику, а потом уже добавлять бизнес-код.