Skip to content
PD
Telegram-боты

aiogram 3: Routers, FSM and Middleware

How to structure an aiogram project, what routers are for, how conversation state works, and what middleware solves in a real bot.

All articles in the guide Telegram-боты · 13

aiogram is the default Python choice, and its strength is less any individual feature than the structure it imposes, which survives the bot growing.

Project structure

An arrangement that withstands growth:

  • An entry point. Creating the bot and dispatcher, registering routers, starting up.
  • Routers by area. One file per concern: registration, catalogue, payments, administration.
  • Keyboards separately. Button labels in one place rather than scattered through handlers - see buttons.
  • Database work separately. A handler should not contain queries.
  • Message texts separately. Otherwise changing a phrase becomes a project-wide search.
  • Settings from the environment. The token and credentials stay out of the code - see the token.

The main rule: a handler should be short. It receives an event, calls logic, replies. Twenty lines of business logic inside a handler belong in a module.

Routers

A router is a group of handlers registered with the dispatcher as a unit.

What that gives you:

Ordering. Handlers are checked in registration order and the first match takes the event. This matters: a catch-all “any message” handler registered early swallows everything and the rest never fire. Such a handler always goes last.

Local filters. A condition can apply to a whole router: the entire admin router works only for administrators, for instance.

A middleware attachment point. Middleware on a router affects only its handlers.

Readability. The file responsible for payments contains only payments.

Conversation state

State is needed when the bot asks several questions in sequence: it must remember which step it is on and what it expects.

Practical rules:

Storage outside process memory. Memory suits development. In production a restart loses every unfinished conversation, and restarts happen on every update.

There must always be an exit. A cancel command that works from any state. A user stuck in a flow with no way out simply leaves.

Validate input at every step. Users send text instead of a number, a file instead of text, or press a button from another menu. Every step must survive that.

Do not store much in state. Intermediate values, yes; full objects belong in the database.

State expires. Continuing a conversation started a week ago is pointless.

Middleware

Middleware runs before and after a handler. Everything shared goes there.

What usually lives in middleware:

  • The user from the database. Fetched once, handed to handlers ready.
  • Rate limiting. Protection against somebody pressing a button twenty times.
  • Logging. Who did what and when.
  • Permission checks, especially on the admin router.
  • Error handling. One reaction instead of a copy in every handler.
  • Bans. A blocked user is stopped before any logic runs.

The practical sign it is time to extract middleware: you copied the same line into a third handler.

Common mistakes

  • A catch-all handler registered early. It swallows everything and the rest never fire.
  • In-memory state in production. A restart loses conversations.
  • Business logic inside handlers. Untestable and hard to read.
  • No cancel. Users get stuck.
  • Blocking calls in async code. A synchronous database or API call hangs the entire bot, not one conversation. This is an async-specific mistake and it shows up immediately under load.

How this runs and lives on a server: deployment and operations. The overview is in the Telegram bots guide.

FAQ

What are routers for in aiogram?

To split handlers across files and register them in groups. Without routers a bot with twenty scenarios becomes one unreadable file where you cannot tell which handler fires first. Routers also give a natural attachment point for middleware scoped to one part of the bot.

What is FSM in a bot and why is it needed?

A conversation state mechanism: the bot remembers what it asked and expects a specific answer. Without it, any multi-question flow has to be assembled from manual flags. State must live outside process memory, or a restart loses every unfinished conversation.

What does middleware do?

Runs shared code before and after a handler: logging, rate limiting, loading the user from the database, permission checks. Anything you would otherwise copy into every handler lives in one place instead.

More on this topic

Done for you

I will build a Telegram bot for your process

Leads, payments, access delivery, broadcasts and a funnel in one bot, with an admin side for you.

from $300 · 3 to 7 days

Similar caseTelegram Sales-Funnel Bot for Online CoursesA Telegram bot that runs the whole funnel - lead magnet → guide → intensive → course - with payment, auto-delivery and an admin panel.

"Genuinely a master of his craft. I learned a lot of new and useful things about Telegram outreach. I had burned a lot of money paying intermediaries before this, and after talking to him I will be doing it all myself."

viktorTR · KworkTranslated from Russian