все статьи
28 августа 2026 г.·обновлено 12 октября 2026 г.·12 мин

Production-структура проекта на Aiogram 3: handlers, services и конфигурация

Как разложить Telegram-бота на Aiogram 3 по слоям, чтобы добавлять FSM, платежи и интеграции без единого огромного файла.

AiogramPythonАрхитектураTelegram

Автор: Shcoder, независимый разработчик

Надёжная структура Aiogram 3 отделяет Telegram-слой от бизнес-логики: handlers принимают обновление, services выполняют действие, repositories работают с данными, а config отвечает за окружение. Это не архитектура «ради папок»: границы помогают менять хранение, тестировать правила без Telegram и не переплетать оплату с FSM и уведомлениями.

Минимальная структура

app/
  bot.py
  config.py
  handlers/
    start.py
    orders.py
  services/
    orders.py
  repositories/
    orders.py
  keyboards/
  middlewares/
tests/

bot.py — composition root: здесь создаются конфигурация, хранилища и Dispatcher, после чего подключаются роутеры. В handler не нужно помещать SQL-запросы и сложные расчёты. Он проверяет формат входа, вызывает нужное действие и переводит его результат в ответ Telegram.

Не создавайте папку на каждый класс. На маленьком боте достаточно одного модуля для заявок; разделяйте код по предметной области, когда у неё появились свои сценарии, данные и тесты. Названия services и repositories не важны сами по себе — важно, чтобы направление зависимостей оставалось понятным.

Конфигурация через окружение

Токен и ключи интеграций не должны попадать в код или репозиторий. Установите зависимости и храните только пример переменных в Git:

python -m pip install aiogram pydantic-settings
# .env.example; реальный .env добавьте в .gitignore
BOT_TOKEN=

Минимальная конфигурация проверяет обязательные значения на старте:

from pydantic_settings import BaseSettings, SettingsConfigDict

class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_file=".env", extra="ignore")
    bot_token: str

BaseSettings сопоставит bot_token с BOT_TOKEN. Если появится база, добавьте её URL вместе с выбранным драйвером и проверьте соединение при старте. Реальный .env добавляется на сервере или переменные размещаются в secret storage CI.

Роутеры вместо большого handler-файла

Группируйте обработчики по предметной области: заявки, каталог, профиль, платежи. Роутер не должен знать, где физически хранится заявка. Это позволяет заменить SQLite на PostgreSQL без переписывания Telegram-слоя.

# app/handlers/orders.py
from aiogram import Router
from aiogram.filters import Command
from aiogram.types import Message

router = Router(name="orders")


@router.message(Command("request"))
async def start_request(message: Message) -> None:
    await message.answer("Опишите, что нужно сделать.")

Подключите вложенные роутеры один раз при старте и следите за порядком широких фильтров. Универсальный handler «на любой текст» может перехватить сообщение, которое ожидал FSM. Для последовательной формы с проверками, отменой и несколькими состояниями есть отдельный разбор FSM в Aiogram 3.

Services и repositories

Сервис отвечает на вопрос «что сделать», repository — «как прочитать или сохранить данные». Например, orders.create() проверяет бизнес-правила, а orders_repository.insert() выполняет запрос. Решите, где начинается и завершается транзакция, и не возвращайте ORM-объекты напрямую в Telegram-слой.

Внешние API вызываются из отдельного клиента или gateway с timeout, понятной обработкой ошибок и ограниченными повторными попытками. Повторять безопасно только операции, которые идемпотентны или имеют idempotency key. Для логов используйте request/update ID и технический статус, но не токен, полный текст переписки или платёжные секреты.

Такой разнос особенно важен для оплаты. Webhook может прийти повторно, поэтому обработчик проверяет подпись и внешний ID события, атомарно фиксирует заказ и только после подтверждённого перехода выдаёт доступ. Нельзя считать callback-кнопку или сообщение клиента доказательством оплаты.

Сборка приложения и запуск

Создавайте сетевые ресурсы один раз на время жизни процесса, а не на каждое обновление. При завершении polling закройте HTTP-сессию бота и пул базы данных. Не запускайте два polling-процесса с одним токеном; для webhook отдельно настройте публичный endpoint и проверку секрета.

import asyncio

from aiogram import Bot, Dispatcher

from app.config import Settings
from app.handlers import orders, start


async def main() -> None:
    settings = Settings()
    bot = Bot(token=settings.bot_token)
    dispatcher = Dispatcher()
    dispatcher.include_routers(start.router, orders.router)
    try:
        await dispatcher.start_polling(bot, close_bot_session=False)
    finally:
        await bot.session.close()


if __name__ == "__main__":
    asyncio.run(main())

Экспортируйте BOT_TOKEN в окружение или используйте локальный .env, который исключён из Git. Если добавите async database engine, его dispose() тоже вызывается в finally или lifespan-обработчике.

Что проверить перед деплоем

  • приложение стартует из инструкции на чистом окружении, а не только из IDE;
  • .env.example совпадает с конфигурацией и не содержит действующих секретов;
  • polling и webhook не запущены одновременно для одного бота;
  • ошибки внешних API не скрываются пустым except и безопасно видны в логах;
  • повторный update или webhook не создаёт дубликат заявки, заказа или выдачи;
  • роли и права проверяются сервером, а callback нельзя подделать сменой ID;
  • есть проверка доступности процесса и резервная копия хранилища;
  • критические правила сервисов покрыты тестами без реального Telegram API;
  • для новой версии есть понятные команды миграции и отката.

Не начинайте с микросервисов, очереди и сложного контейнерного окружения, если один процесс и одна база решают текущую задачу. Добавляйте инфраструктуру, когда появляется измеримое требование к нагрузке, отказоустойчивости или независимому масштабированию.

Для первого проекта можно начать с бесплатного практикума Aiogram 3, а затем перейти к полному курсу по Telegram-ботам, где разбираются платежи, Mini App, webhook, Docker и production-проверки.

Если нужна такая архитектура для реального продукта, опиши задачу в заявке: достаточно указать основной сценарий, интеграции и предполагаемую нагрузку.

Собрать production-бота целиком

В полном курсе есть PostgreSQL, платежи, Mini App, тесты и Docker. Начать можно с бесплатного первого урока.

Открыть пробный урок

Нужна разработка Telegram-бота?

Разрабатываю ботов, Mini Apps, платежи и автоматизацию под ключ.