11 KiB
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
Быстрый старт
- Создание виртуального окружения:
python3.11 -m venv .venv
source .venv/bin/activate
- Установка зависимостей:
pip install -r requirements.txt
- Создание локального конфига:
cp .env.example .env
- Заполнение
.env:
BOT_TOKEN=123456:telegram_bot_token
BOT_ADMIN_IDS=123456789
BOT_DATABASE_EXPORT=False
BOT_ADMIN_IDS можно указать через запятую: 123456789,987654321.
- Применение миграций:
python migrate.py up
Без аргументов python migrate.py только показывает подсказки. Бот сам миграции при старте не запускает, чтобы не менять схему базы неожиданно.
- Запуск бота:
python main.py
Docker Compose
Запуск через compose:
docker compose up --build
Остановка:
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 вручную:
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. Это специально: база может содержать персональные данные, поэтому экспорт надо включать руками и осознанно.
Структура проекта
.
├── 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_scoperepository.py- базовый репозиторий и проверка готовности БДmigration_runner.py- запуск Alembic из кодаdb_users.py- пользователи Telegramdb_settings.py- настройки бота в БД
UNIQUE
В таблице пользователей поле user_id уникальное.
Это значит, что один Telegram-пользователь не может появиться в таблице два раза. Если пользователь уже есть, база не создаст дубль.
UPSERT
UPSERT - это логика “создай запись, а если она уже есть, обнови”.
В шаблоне пользователь добавляется по user_id. Если он уже есть, обновляются только изменившиеся поля: username, имя, фамилия и полное имя. Если данные не поменялись, лишнего UPDATE в БД не будет.
Миграции
Миграции управляются через Alembic, но запускать их удобнее через готовый CLI.
Показать справку:
python migrate.py
Применить все миграции:
python migrate.py up
То же самое длинной командой:
python migrate.py upgrade
Посмотреть текущую версию БД:
python migrate.py status
Посмотреть историю:
python migrate.py history
Создать новую миграцию вручную:
python migrate.py new "add payments table"
Создать миграцию по изменениям SQLAlchemy-моделей:
python migrate.py auto "add payments table"
Откатить последнюю миграцию:
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 на неизвестные сообщения и callbackmain_errors.py- обработка безопасных Telegram-ошибок
Админский роутер уже закрыт фильтром IsAdmin() и для сообщений, и для callback query.
Middleware
ExistsUserMiddleware добавляет или обновляет пользователя в БД и прокидывает объект пользователя в обработчик как User.
Чтобы не писать в БД на каждый одинаковый update, middleware кеширует пользователя по user_id.
Пример:
async def handler(message: Message, User: UserModel):
await message.answer(User.user_fullname)
Логирование
Логи пишутся в tgbot/data/logs.log.
Файл не растёт бесконечно: используется RotatingFileHandler, который вращает логи по размеру.
Админ может получить логи командой:
/log
Очистить логи:
/clear_log
Админские команды
| Команда | Что делает |
|---|---|
/log |
Отправляет файл логов |
/clear_log |
Очищает файлы логов |
/db |
Отправляет файл БД, только если BOT_DATABASE_EXPORT=True |
Команда /db скрывается из меню команд, если экспорт БД выключен.
Как добавить новую таблицу
- Создать модель в
tgbot/database/. - Импортировать её в
tgbot/database/__init__.py. - Создать миграцию:
python migrate.py auto "add new table"
- Проверить созданный файл в
migrations/versions/. - Применить миграцию:
python migrate.py up
Важно
- Не коммить
.env, базу данных и логи. - Если токен попал в Git, его надо перевыпустить у BotFather.
- Перед деплоем проверь
BOT_DATABASE_EXPORT: на проде лучше держатьFalse, если экспорт БД реально не нужен. - Для нового проекта сначала менять тексты, команды и клавиатуры под свою логику, а потом уже добавлять бизнес-код.