Тема 2 из 6

Первый бот

aiogram — популярная библиотека для Telegram-ботов на Python. Она асинхронная: один бот спокойно обслуживает тысячи чатов одновременно.

В курсе вы соберёте бота-напоминалку: команды, кнопки, диалоги и список напоминаний.

async и await

Бот всё время ждёт: новых сообщений, ответа Telegram на отправку. Чтобы ожидание не останавливало всё остальное, обработчики пишут асинхронными:

async def start(message):
    await message.answer("Привет!")      # пока идёт отправка, бот занят другими чатами
  • async def объявляет корутину — функцию, которую можно приостанавливать;
  • await ждёт результат, отдавая управление другим задачам;
  • запускает всё asyncio.run(main()).

Минимальный бот

import asyncio
from aiogram import Bot, Dispatcher, Router, F
from aiogram.filters import CommandStart, Command
from aiogram.types import Message

router = Router()


@router.message(CommandStart())
async def start(message: Message):
    await message.answer(f"Привет, {message.from_user.first_name}!")


@router.message(Command("help"))
async def help_cmd(message: Message):
    await message.answer("Я умею: /start, /help")


@router.message(F.text)
async def echo(message: Message):
    await message.answer(message.text)


dp = Dispatcher()
dp.include_router(router)
asyncio.run(dp.start_polling(Bot("ТОКЕН")))
  • Bot — подключение к Telegram по токену. Токен выдаёт @BotFather: команда /newbot. Токен — как пароль: не публикуйте его и не храните в коде, а берите из переменной окружения (os.getenv("BOT_TOKEN"));
  • Router — набор обработчиков; Dispatcher — главный роутер, который получает обновления и раздаёт их обработчикам;
  • start_polling постоянно спрашивает Telegram о новых сообщениях.

Сообщение

message.text — текст, message.from_user.first_name — имя отправителя (username есть не у всех!), message.chat.id — номер чата. await message.answer(текст) отвечает в тот же чат, message.reply(текст) — ответом на сообщение.

Фильтры и порядок

В декоратор передают фильтры — условия, при которых сработает обработчик:

  • CommandStart(), Command("help") — команды (Command не путает /help с /helpme);
  • F.text — есть текст; F.text == "привет", F.text.lower() == "привет", F.text.startswith("/"), F.text.regexp(r"^\d+$"), F.photo — «магические фильтры»;
  • без фильтров — любое сообщение.

Обработчики проверяются в порядке регистрации, срабатывает первый подходящий. Общие обработчики («всё остальное») ставят в конец. Регистрировать можно и без декоратора: router.message.register(функция, фильтры).

Как проверяются задачи

Проверка подаёт боту готовые сообщения напрямую — без Telegram и без токена — и печатает его ответы. Чтобы запустить бота по-настоящему, получите токен у @BotFather, задайте переменную окружения BOT_TOKEN и нажмите «Запустить у себя».

Итог

  • async def и await message.answer(...);
  • Bot, Dispatcher, Router, include_router, start_polling;
  • фильтры CommandStart(), Command("…"), F.text…;
  • срабатывает первый подходящий обработчик — общий ставят последним.