Run aiogram next to Django: write handlers as ordinary Django app code, and send Telegram messages from anywhere in the project.
One container runs the bot. Every other process — web, Celery, a management command — pushes the call onto a Redis list and returns, so a request never waits on Telegram.
web, celery ──bot.send()──▶ Redis list ──▶ start_tgbot ──▶ Telegram
pip install 'django-aiogram[redis]'The transport driver is an extra, so a deployment downloads only the one it uses.
[redis] is the default transport, the one this README shows.
A base pip install django-aiogram is a valid install: it imports, and manage.py
runs. What it cannot do is carry a message, and manage.py check says so — E047,
with the pip install line for whichever BROKER you named. A process with
ENABLED off is not asked for a driver at all, since it reaches no transport, so a
web container that only records the event log needs no extra. A BROKER naming
something that is not a transport is reported either way.
# settings.py
import os
INSTALLED_APPS = [..., 'django_aiogram']
TELEGRAM_BOT = {
'TOKEN': os.environ.get('TELEGRAM_BOT_TOKEN', ''),
'REDIS_URL': os.environ.get('REDIS_URL', ''),
}Both may be empty. Nothing connects or validates credentials at import time, so tests and migrations run without them. Requires Python 3.10–3.14, Django 5.2+, aiogram 3.30+, redis 6.2+.
# myapp/tg_router.py — imported automatically from every installed app
from aiogram import F, types
from django_aiogram import bot
@bot.message(F.text == '/start')
async def start(message: types.Message) -> None:
await message.answer('hi')# anywhere else in the project
from django_aiogram import bot
bot.send(chat_id=CHAT_ID, text='Order approved')python manage.py start_tgbotA router module, a call, and one process running the bot. Everything else — rate limits, per-process opt-out, healthchecks — is configuration, and it is documented rather than required. Webhook mode is the one alternative that also asks for a URL route; Webhook has the four steps.
The wiki is the
documentation. Pages live in docs/wiki/, so they are reviewed in
the same pull request as the code they describe and published from master.
| Installation | install, configure, run |
| Settings | every setting, with defaults and check ids |
| Handlers | routers, filters, FSM, the async ORM |
| Sending messages | routes, keyboards, files, errors |
| Testing | your suite without Redis, asserting what was queued |
| API | the instance, its internals, and what stays public |
| Delivery | how queued messages reach Telegram |
| Webhook | receiving updates over HTTP instead of polling |
| Rate limits | staying inside Telegram's published limits |
| Deployment | compose recipes, healthchecks, per-process opt-out |
| Logging | the logger and its structured fields |
| Event log | recording what the bot did to a table, and a signal to count it without one |
| Serialization | what can be queued |
| Troubleshooting | symptoms and their usual causes |
| Upgrading | what each major release changed, and what you must do |
| AI assistants | the brief to hand a coding agent |
Upgrading to 3.0: the deprecated telegram_bot package name is gone, so
INSTALLED_APPS and imports have to name django_aiogram. The upgrading
page lists everything else that needs attention.
CONTRIBUTING.md for the workflow, AGENTS.md for the same ground in the form coding agents read. Changes are in CHANGELOG.md; security reports go through SECURITY.md.