Найти тему

Введение в Telegram-ботов на Python. Часть 1 - Hello, world!

Приветствую, читатель! В этом курсе я объясню, как писать асинхронных ботов на Python, а именно на фреймворке aiogram 3. В этом курсе с нуля мы создадим бота для интернет-магазина. Создадим базу данных SQL, будем делать учеты в Google-таблицах и многое другое. Начнём с того, что вам необходимо пространство для кодинга; выбор велик - можете выбирать, что вам больше по душе, я же выбираю PyCharm и вам советую по нескольким причинам:

  1. PEP-8

PyCharm имеет встроенную проверку PEP-8. Это стандарт написания кода для Python. Он основывается на правиле, которое составил сам создатель языка: код читается намного больше раз, чем пишется. В целом - это необходимость.

2. Git-инструменты

PyCharm имеет встроенную Git-систему, которая пригодится вам в будущем.

3. Удобство при работе с пакетами PyPi

Настраиваем проект

В первую очередь, необходимо получить API-токен бота. По сути - это те же самые логин и пароль от вашего бота, которые нужны для входа вашего кода в систему Telegram. Получить можно тут BotFather. Порядок таков:

1. Создаём бота по команде /newbot

Сначала вводите название бота, затем его @username. После успешного создания вы получите сообщение с API-токеном в виде 123456789:AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrS. На данном этапе переходим в PyCharm и создаём новый проект с виртуальным окружением (.venv). После создания, в терминал пишем команду

pip install -U aiogram

Выглядеть будет примерно так:

Лог терминала
Лог терминала

 После установки aiogram по такому же принципу скачиваете python-dotenv (команда ниже)

 pip install python-dotenv

Поздравляю! Мы готовы к созданию первой версии бота.

Программирование бота

Начнём с создания файла .env

Для чего же нужны такие файлы? Всё донельзя просто - в них вы сможете безопасно хранить свои API-токены ботов, платёжных систем, других HTTP-сервисов и так далее. Оформить его нужно так:

-3

После знака "=" мы вставляем токен бота, который мы уже получили в BotFather. С этим закончили.

Далее необходимо создать папку project_configuration, в ней мы будем хранить конфигурационные файлы проекта, различные хуки для приложения (on_dispatcher_startup.py / on_dispatcher_shutdown.py / другое)

Создадим файл configuration.py и создадим в нём класс Configuration:

Класс конфигурации
Класс конфигурации

Как будет работать наш класс?

При инициализации он подгрузит данные из .env файла в os при помощи load_dotenv()

Далее находится 2 метода класса; Первый - turn_on_logging, нужен для включения логгирования (свою форматизацию оставил ниже, можете ставить другую по своему вкусу)

"{%(name)s} %(asctime)s [%(levelname)s] -> %(message)s"

Второй же возвращает из .env файла токен бота, который пригодится в файле запуска.

Файл запуска

Название можете выбирать на свой вкус, но для удобства рекомендую вам выбрать одно из этих названий - run, main, __main__, app

Далее напишем такой код:

Файл запуска (в примере __main__.py)
Файл запуска (в примере __main__.py)

Что он делает? Разберём по строкам:

Строки 1, 3, 5 - Импортируем необходимые зависимости для старта бота

Строка 8 - создаём асинхронную функцию для старта бота (синхронную создать нельзя, т.к. есть Coroutine-асинхронные функции)

Строки 9 и 10 - Загрузка конфигурации из .env и включение логгирования

Строки 12 и 13 - Загрузка бота

Строка 15 - Создание объекта диспетчера и передача бота в Dependency injection для последующего вызова из route-функций и отсутствия глобальных переменных (если хотите знать почему глобальных переменных быть не должно - напишите в комментариях, я могу написать отдельный пост)

Строка 17 - Вызов функции старта приема запросов на этого бота

Строки 20 и 21 - вызов функции main для работы всего, что находится в ней

На этом моменте можно было бы сказать, что бот уже работает, но мы же хотим написать "Hello, world!", верно? Сейчас начнем писать хэндлер на команду /start, который мог бы отвечать "Hello, world!"

Первый хэндлер

Для этого создаём Python Package (просто директория с файлом __init__.py) с именем handlers и затем создадим пакет user_handlers. Внутри этого пакета мы будем делить хэндлеры по типу; command_handlers - на команды, callback_handlers - на коллбэки и т.д. (если сейчас непонятно-потом поймёте, главное, что вам сейчас нужно создать папку command_handlers и создать в ней файл on_start.py)

Выглядеть всё должно так:

Древо проекта
Древо проекта

Начнём с файла on_start.py

 Файл on_start.py
 Файл on_start.py

Его содержание будет таким; разберём код:

Строки 1-3 - импорт зависимостей библиотеки

Строка 5 - создание объекта роутера или ответвления Dispatcher'а

Строка 8 - указание о приеме ответа на фильтр команды /start (Такой фильтр есть только у команды /start, для остальных мы будем импортировать фильтр Command и в инициализации писать название команды)

Строка 9 - создали асинхронную функцию on_start которая принимает сообщение

Строка 10 - Ответили на сообщение простым текстом "Hello, world!"

И всё! Это вся логика хэндлера.

Импорты в запуск программы

Дальше напишем функцию get_user_router, которая будет создавать один большой роутер, который хранит все роутеры, которые находятся в пакете user_handlers

-8

И необходимо закинуть ее в следующий __init__.py для удобства:

-9

Далее в файле запуска укажем эту функцию в принятых роутерах диспетчера, чтобы она обрабатывалась при вызове пользователем

-10

Теперь давайте запустим и проверим:

В логе видим, что бот запущен
В логе видим, что бот запущен
-12

Как видим бот ответил и всё работает!

Заключение

За эту статью мы создали бота и написали наш первый хэндлер. Спасибо всем, кто прочёл эту статью. Дальше - больше! Жду ваших комментариев и пожеланий.

Github репозиторий урока