Production-ready шаблон для Telegram-ботов на aiogram 3.x
Современный, быстрый, масштабируемый и полностью готовый к продакшену с PostgreSQL, Redis и Docker.
Полностью на webhook, поэтому для разработки советую использовать ngrok или CloudPub
- aiogram 3.x — асинхронный Telegram Bot API
- FastAPI — webhook-эндпоинт
- PostgreSQL + Tortoise ORM — база данных с миграциями (Aerich)
- Redis — FSM-хранилище и кэширование
- aiogram-i18n + Fluent — мультиязычность
- Docker Compose — dev/prod окружения
- Loguru — структурированное логирование
Команды, которые предоставлены ниже работают только на Linux. Если вы занимаетесь разработкой на Windows, то рекомендую использовать WSL + VS Code
# Клонируйте и настройте окружение
git clone https://github.com/Er1one/telegram-bot-template.git && cd bot-template
# Синхронизируйте зависимости и виртуальное окружение при помощи uv
uv sync
# Активируйте виртуальное окружение
source .venv/bin/activate
# Скопируйте файл настроек .env
cp .env.example .env
# Отредактируйте .env (BOT_TOKEN, пароли, WEBHOOK_URL)
# Запустите
make dev # разработка (hot reload, pgadmin)
# или
make prod # продакшен (оптимизировано)
# Инициализируйте БД
make aerich-init
make aerich migrate
make aerich upgradebot/
├── core/ # Конфигурация, loader, логирование
├── handlers/ # Роутеры (private/, groups/)
├── filters/ # Кастомные фильтры
├── keyboards/ # Inline клавиатуры
├── middlewares/ # User registration, i18n
├── models/ # Tortoise ORM модели
├── services/ # Бизнес-логика (UserService, BroadcastService)
├── managers/ # Database, Redis, i18n менеджеры
├── routes/ # FastAPI webhook endpoint
├── locales/ # Переводы (ru/en)
└── utils/ # Template, хелперы
make dev/prod # Переключить окружение и запустить
make up/down # Запустить/остановить
make logs [service] # Просмотр логов
make shell service # Войти в контейнер
make rebuild # Пересобратьmake aerich-init # Первая инициализация
make aerich migrate # Создать миграцию
make aerich upgrade # Применить миграции
make aerich downgrade # Откат миграции
make aerich history # История
make db-backup # Бэкап БД# 1. Измените модель в bot/models/
# 2. Создайте миграцию
make aerich migrate
# 3. Примените
make aerich upgrade# Откатить последнюю
make aerich downgrade
# Посмотреть историю
make aerich historybot/handlers/private/my_handler.py:
from aiogram import Router
from aiogram.filters import Command
from aiogram.types import Message
from filters import IsPrivateChat
router = Router()
@router.message(Command("test"), IsPrivateChat())
async def cmd_test(message: Message):
await message.answer("Test!")Зарегистрируйте в bot/handlers/private/__init__.py:
from .my_handler import router as my_router
routers = [..., my_router]bot/models/chat.py:
from tortoise import Model, fields
class Chat(Model):
id = fields.BigIntField(primary_key=True)
title = fields.CharField(max_length=255)
class Meta:
table = "chats"Импортируйте в bot/models/__init__.py и создайте миграцию:
make aerich migrate
make aerich upgradebot/filters/my_filter.py:
from aiogram.filters import BaseFilter
from aiogram.types import Message
class MyFilter(BaseFilter):
async def __call__(self, message: Message) -> bool:
return message.text.startswith("!")from services import BroadcastService
from utils import Template
template = Template(
text="Привет всем!",
photo="https://example.com/image.jpg"
)
stats = await BroadcastService.broadcast_template(
bot=bot,
template=template,
exclude_banned=True,
delay=0.05
)
# stats = {total, success, failed, blocked}from utils import Template
# Простое сообщение
template = Template(text="Привет!")
await template.send(message)
# С фото
template = Template(text="Описание", photo="photo.jpg")
await template.send(message)
# Несколько фото (media group)
template = Template(
text="Галерея",
photos=["1.jpg", "2.jpg", "3.jpg"]
)
await template.send(message)
# Редактирование
template = Template(text="Обновлено", buttons=keyboard)
await template.edit(callback_query)Обязательные:
BOT_TOKEN— токен от @BotFatherPG_PASSWORD— пароль PostgreSQLREDIS_PASSWORD— пароль RedisWEBHOOK_URL— публичный URL для webhookADMIN_IDS— список ID админов через запятую в квадратных скобках
Опциональные:
DEFAULT_LANGUAGE— ru/en (default: ru)APP_PORT— порт webhook (default: 5000)LOGGING_ENABLED— отправка ошибок в TG (default: False)REDIS_CACHE_TTL— TTL кэша в днях (default: 7)
Полный список в .env.example.
- Батчинг рассылок — загрузка пользователей по 100 шт (экономия RAM)
- Индексы БД —
is_bannedдля быстрых фильтров - Redis connection pool — max_connections=10
- Middleware на уровне dispatcher — один экземпляр для всех событий
- Автоматический разбан — пользователи разбаниваются при возвращении
- Измените пароли в
.env - Настройте
WEBHOOK_URLс SSL - Включите логирование:
LOGGING_ENABLED=True - Настройте reverse proxy (nginx/caddy)
- Бэкапы БД через cron:
0 2 * * * cd /path && make db-backup
location /webhook {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}handle /webhook* {
reverse_proxy localhost:5000 {
header_up Host {host}
header_up X-Real-IP {remote_host}
}
}- Фильтры:
IsPrivateChat,IsGroupChat,IsChatAdmin,IsAdmin,HasMedia,HasLinks,TextLengthFilter - Template: единый интерфейс для send/edit с поддержкой фото, медиагрупп, документов
- BroadcastService: массовая рассылка с обработкой rate limits
- Автоматическая регистрация: middleware регистрирует пользователей в БД
- i18n: автоопределение языка с кэшированием в Redis
# Проверить статус
make ps
# Логи
make logs
make logs bot
# Пересобрать
make rebuild
# Полная очистка
make clean-allЕсли шаблон сэкономил тебе часы или дни — буду рад чашке кофе! ❤️
USDT (TRC20): TWk5A9j6vzuA4jK1fZm5AqJUPnDj76zP9U
BTC: bc1qmz95699k6azw828kvlamj0hl5utynq09pjv48v
MIT