Продвинутый курс по созданию Telegram-ботов на aiogram 3.x для senior-разработчиков. Охватывает архитектурные паттерны, масштабируемость, интеграцию с БД, webhook, очереди задач, тестирование, безопасность и мониторинг. Упор на практику и production-ready решения.
Бот, который отвечает вам в личке, и бот, который ведёт десять тысяч диалогов, отличаются не кодом обработчиков. Отличается всё остальное: где лежит состояние диалога и переживает ли оно рестарт, что происходит, когда апдейты приходят быстрее, чем вы их обрабатываете, и как выглядит первая встреча с лимитами Telegram на рассылке.
Курс из 10 тем для тех, кто уже писал ботов и упёрся в потолок: файл на тысячу строк с @dp.message(), состояние в словаре в памяти, деплой через screen. Разбирается структура проекта на роутерах и middleware, внедрение зависимостей, кастомные фильтры и порядок обработчиков; FSM с хранением в Redis; callback factory и пагинация вместо ручного парсинга callback_data; SQLAlchemy с asyncpg, репозитории и пул соединений; webhook с nginx и SSL вместо long polling; Celery и rate limiting при горизонтальном масштабировании; тесты с моками Bot API; валидация webhook и работа с секретами; структурные логи и метрики в Prometheus.
Уровень — senior. Предполагается, что async/await не вызывают вопросов, а BotFather и первый echo-бот остались далеко позади: с них курс не начинается.
Версия 1.0, март 2026.
Проектирование архитектуры бота: роутинг, middleware, dependency injection, модульная структура
Кастомные фильтры, приоритеты обработчиков, флаги, цепочки ответственности
Конечные автоматы, кастомные storage, Redis, контексты диалогов
SQLAlchemy, asyncpg, миграции Alembic, паттерн Repository, connection pooling
Callback factories, pagination, динамические клавиатуры, обработка нажатий
Настройка webhook, SSL, nginx, Docker, CI/CD, production-деплой
Celery, Redis queues, rate limiting, горизонтальное масштабирование
pytest, моки, интеграционные тесты, дебаггинг, локальное тестирование
Валидация webhook, защита от XSS/injection, секреты, rate limiting
Структурированное логирование, метрики, Prometheus, Grafana, алерты
Доступен после всех тем (0 из 10)
Доступен после зачёта
Уникальный ключ доступа к Telegram Bot API, выдаваемый @BotFather. Формат: цифры, двоеточие, строка (например, 123456789:ABCdefGHIjklMNOpqrsTUVwxyz).
Пример
BOT_TOKEN = '123456789:ABCdefGHIjklMNOpqrsTUVwxyz'Связанные термины
Официальный бот Telegram для создания и управления другими ботами. Через него получается токен, настраивается имя, описание, avatar.
Пример
@BotFather в Telegram → /newbot → следуйте инструкциямСвязанные термины
HTTP-интерфейс для взаимодействия с Telegram-серверами от имени бота. Поддерживает отправку/получение сообщений, файлов, управление клавиатурами и т.д.
Пример
https://api.telegram.org/bot<token>/sendMessageСвязанные термины
Режим получения обновлений от Telegram, при котором бот периодически запрашивает новые сообщения через getUpdates. Прост в настройке, но менее эффективен для продакшена.
Пример
await dp.start_polling(bot)Связанные термины
Режим получения обновлений, при котором Telegram отправляет POST-запросы на указанный URL при каждом новом событии. Рекомендуется для продакшена.
Пример
await bot.set_webhook('https://example.com/webhook')Связанные термины
Объект, представляющий событие в Telegram (сообщение, callback, редактирование сообщения и т.д.). Все обновления приходят в Dispatcher для обработки.
Пример
@dp.message() async def handle(msg: Message): ...Связанные термины
Тип обновления, представляющий текстовое сообщение, фото, видео, документ или другой контент в чате.
Пример
from aiogram.types import Message
@dp.message() async def echo(msg: Message): await msg.answer(msg.text)Связанные термины
Событие, возникающее при нажатии на inline-кнопку. Содержит данные (data), переданные при создании кнопки.
Пример
@dp.callback_query(F.data == 'btn_click') async def handle(cb: CallbackQuery): ...Связанные термины
Центральный компонент aiogram, распределяющий входящие обновления по зарегистрированным обработчикам на основе фильтров и роутинга.
Пример
dp = Dispatcher()
@dp.message() async def handler(msg: Message): ...Связанные термины
Модуль для группировки обработчиков по функциональности. Позволяет разбивать бота на независимые компоненты (например, по фичам или модулям).
Пример
router = Router(name='users')
@router.message(Command('start')) async def start(msg: Message): ...
dp.include_router(router)Связанные термины
Асинхронная функция, вызываемая при совпадении обновления с определёнными условиями (фильтрами). Обработчики регистрируются через декораторы.
Пример
@dp.message(Command('start'))
async def start_handler(msg: Message):
await msg.answer('Hello!')Связанные термины
Объект или функция, определяющая, должен ли обработчик реагировать на данное обновление. Фильтры могут проверять текст, тип сообщения, пользователя и т.д.
Пример
@dp.message(F.text == 'hello')
@dp.message(lambda msg: msg.from_user.id == 123)
async def handler(msg: Message): ...Связанные термины
Декларативный способ построения фильтров в aiogram через объект F. Позволяет создавать сложные условия проверки через атрибуты и операторы.
Пример
from aiogram import F
@dp.message(F.text.startswith('/'))
@dp.callback_query(F.data.func(lambda x: x.isdigit()))Связанные термины
Промежуточный слой, через который проходят все обновления до и после обработки. Используется для логирования, аутентификации, rate limiting, injection зависимостей.
Пример
class AuthMiddleware(BaseMiddleware):
async def __call__(self, handler, event, data):
data['user'] = await get_user(event.from_user.id)
return await handler(event, data)Связанные термины
Паттерн передачи зависимостей (сервисов, репозиториев, соединений с БД) в обработчики через middleware или фабричные функции. Упрощает тестирование и поддержку.
Пример
middleware = DatabaseMiddleware(session_factory)
dp.message.middleware(middleware)
@dp.message()
async def handler(msg: Message, session: AsyncSession):
# session injected automatically
...Связанные термины
Паттерн абстракции доступа к данным. Репозиторий инкапсулирует логику работы с БД, предоставляя чистый интерфейс для бизнес-логики.
Пример
class UserRepository:
def __init__(self, session: AsyncSession):
self.session = session
async def get_by_id(self, user_id: int) -> User:
...Связанные термины
Синтаксис асинхронного программирования в Python. async объявляет корутину, await приостанавливает выполнение до завершения асинхронной операции.
Пример
async def fetch_data():
result = await db.query()
return resultСвязанные термины
Стандартная библиотека Python для асинхронного программирования. Предоставляет event loop, корутины, задачи и асинхронные примитивы.
Пример
import asyncio
await asyncio.gather(task1, task2, task3)Связанные термины
Ядро asyncio, управляющее выполнением корутин. Планирует задачи, обрабатывает I/O операции и колбэки.
Пример
loop = asyncio.get_event_loop()
loop.run_until_complete(main())Связанные термины
Специальная функция, объявленная через async def, которая может приостанавливать выполнение через await. Возвращает coroutine object.
Пример
async def fetch():
await asyncio.sleep(1)
return 'done'Связанные термины
Обёртка над корутиной, планируемая в event loop. Позволяет запускать корутины конкурентно и отслеживать их выполнение.
Пример
task = asyncio.create_task(fetch_data())
result = await taskСвязанные термины
Функция для параллельного выполнения нескольких корутин. Возвращает результаты в порядке передачи аргументов.
Пример
results = await asyncio.gather(fetch1(), fetch2(), fetch3())Связанные термины
Механизм переиспользования соединений с БД. Создаёт фиксированное количество соединений, которые распределяются между запросами.
Пример
engine = create_async_engine(
DATABASE_URL,
pool_size=10,
max_overflow=20
)Связанные термины
ORM и SQL-тулкит для Python. Поддерживает синхронный и асинхронный режимы (asyncio). В aiogram используется async-версия.
Пример
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
engine = create_async_engine(DATABASE_URL)
async with AsyncSession(engine) as session:
session.add(user)Связанные термины
Техника преобразования данных между объектами Python и таблицами БД. SQLAlchemy ORM позволяет работать с БД через классы и атрибуты.
Пример
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)Связанные термины
Инструмент миграций для SQLAlchemy. Позволяет версионировать схему БД и применять изменения через CLI.
Пример
alembic revision --autogenerate -m 'Add users table'
alembic upgrade headСвязанные термины
In-memory хранилище ключ-значение. Используется для кэширования, очередей задач, хранения сессий FSM и rate limiting.
Пример
redis = Redis(host='localhost', port=6379, db=0)
await redis.set('key', 'value', ex=3600)Связанные термины
Хранилище состояний для Finite State Machine в aiogram. Поддерживает MemoryStorage (для тестов) и RedisStorage (для продакшена).
Пример
from aiogram.fsm.storage.redis import RedisStorage
storage = Redis(redis=redis, key_prefix='fsm')
dp = Dispatcher(storage=storage)Связанные термины
Конечный автомат для управления диалогами с пользователем. Позволяет запоминать состояние пользователя между сообщениями.
Пример
class Form(StatesGroup):
name = State()
age = State()
@dp.message(Form.name)
async def save_name(msg: Message, state: FSMContext):
await state.update_data(name=msg.text)
await state.set_state(Form.age)Связанные термины
Текущий этап диалога пользователя в FSM. Определяется через StatesGroup и State из aiogram.fsm.state.
Пример
class Registration(StatesGroup):
email = State()
password = State()Связанные термины
Клавиатура, кнопки которой отображаются под сообщением. Используется для навигации, выбора опций, callback-действий.
Пример
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text='Click', callback_data='action')]
])Связанные термины
Механизм aiogram для типизированной генерации и парсинга callback_data. Использует dataclasses для объявления структуры данных.
Пример
from aiogram.filters.callback_data import CallbackData
class ProductCallback(CallbackData, prefix='product'):
id: int
action: str
ProductCallback(id=123, action='buy').pack()Связанные термины
Цифровой сертификат для HTTPS. Требуется для webhook — Telegram отправляет обновления только на HTTPS-эндпоинты.
Пример
# Self-signed для тестов:
openssl req -newkey rsa:2048 -sha256 -nodes -x509 -days 365 \
-keyout private.key -out public.crt -subj '/CN=your-domain.com'Связанные термины
Платформа контейнеризации. Упаковывает бота со всеми зависимостями в изолированный контейнер для консистентного деплоя.
Пример
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD python bot.pyСвязанные термины
Инструмент для оркестрации мультиконтейнерных приложений. Позволяет запускать бота, БД, Redis одной командой.
Пример
version: '3.8'
services:
bot:
build: .
depends_on: [db, redis]
db:
image: postgres:15
redis:
image: redis:7Связанные термины
Веб-сервер и reverse proxy. В связке с webhook принимает HTTPS-запросы от Telegram и проксирует их на бота.
Пример
server {
listen 443 ssl;
location /webhook {
proxy_pass http://bot:8000;
}
}Связанные термины
Распределённая очередь задач. Используется для фоновых операций: отложенные сообщения, внешние API-вызовы, тяжёлые вычисления.
Пример
@celery_app.task
async def send_notification(user_id: int, text: str):
await bot.send_message(user_id, text)Связанные термины
Ограничение частоты запросов от пользователя. Защищает от спама, злоупотреблений и исчерпания ресурсов.
Пример
from aiogram.dispatcher.middlewares.rate_limit import RateLimitMiddleware
dp.message.middleware(RateLimitMiddleware(limit=5, interval=1))Связанные термины
Проверка и санитизация пользовательских данных перед обработкой. Предотвращает injection-атаки, некорректные состояния.
Пример
from pydantic import BaseModel, EmailStr
class RegistrationData(BaseModel):
email: EmailStr
age: int = Field(ge=18, le=120)Связанные термины
Библиотека валидации данных через type hints. Используется для проверки входных данных, настроек, callback-параметров.
Пример
from pydantic import BaseModel, Field
class UserInput(BaseModel):
name: str = Field(min_length=2, max_length=50)
age: int = Field(ge=0)Связанные термины
Логирование в машиночитаемом формате (JSON). Позволяет агрегировать логи в ELK, Loki, CloudWatch.
Пример
import structlog
logger = structlog.get_logger()
logger.info('user_registered', user_id=123, email='test@example.com')Связанные термины
Система мониторинга и сбора метрик. Собирает метрики из бота (количество сообщений, ошибки, latency) через HTTP-эндпоинт.
Пример
from prometheus_client import Counter, Histogram
MESSAGE_COUNT = Counter('bot_messages_total', 'Total messages', ['type'])
MESSAGE_COUNT.labels(type='text').inc()Связанные термины
Платформа визуализации метрик. Строит дашборды на основе данных из Prometheus, показывает графики, алерты.
Пример
# datasource: Prometheus
# query: rate(bot_messages_total[5m])Связанные термины
Состав курса, уровни, практика и способы проверки знаний.
Курс включает 10 тем и 100 вопросов с разбором ответа. Начать можно с первой темы курса.
Маршрут охватывает уровни Senior. Темы расположены от основы к более сложным инженерным задачам, поэтому можно начать с подходящего места и не пропускать важные зависимости.
После прохождения тем доступен зачёт по курсу «Telegram Bot Development with aiogram 3.x» — 20 случайных вопросов с порогом 80%. После зачёта открывается экзамен с развёрнутыми ответами и автоматической оценкой, приближённый к техническому собеседованию.
Да, курс полностью бесплатный: все 10 тем доступны без оплаты.