Введение
В данной статье рассматривается создание телеграмм бота с помощью это асинхронной библиотеки aiogram.
Особенности реализации:
- бот будет реализован отдельным классом
- бот будет запрашивать геолокацию смартфона пользователя
- полученную геолокацию будет передавать в Yandex Weather API
- бот будет выводить пользователю текущую погоду + ссылку на яндекс карту с погодой
За пределами статьи:
- получение токена для телеграмм бота (как это сделать можно прочитать тут https://core.telegram.org/bots/tutorial#obtain-your-bot-token)
- получение ключа доступа к Yandex Weather API (на день публикации Яндекс дает возможность получить 1 раз бесплатный тестовый доступ на 7 дней: https://yandex.ru/pogoda/b2b/console/keys/create)
- заранее были подготовлены файлы для работы с виртуальной средой (как их подготавливать я описывал тут: https://dzen.ru/a/aEKVHTM_GULyazKa)
- в рамках статьи объясняется как клонировать файлы из git для работы со статьей, но не объясняется как установить программу для работы с git. Если с git не работаете, можно просто скачать архив: https://gitlab.com/pytechnotes1/tg_bot_yandex_weather_aio/-/tree/d5af23db72daa8047cc783313d9d78eaa12c0349
В конце статьи есть ссылка в GitLab на финальную версию программы.
Используемые технологии
ОС: Windows 10
Язык: Python 3.12
Основные библиотеки: aiogram, requests
План работы
- Клонируем репозиторий с GitLab
- Настраиваем виртуальную среду
- Правим файлы конфигураций
- Делаем бота
- Запускаем бота
Клонируем репозиторий с GitLab
Создадим папку "WEATHER_BOT", куда будем клонировать репозиторий
mkdir WEATHER_BOT
Клонируем репозиторий
git clone https://gitlab.com/pytechnotes1/tg_bot_yandex_weather_aio WEATHER_BOT
Заходим в папку
cd WEATHER_BOT/
Делаем чекаут версии коммита, который я сделал специально для статьи
git checkout d5af23db72daa8047cc783313d9d78eaa12c0349
Настраиваем виртуальную среду
Открываем в cmd наш проект WEATHER_BOT и создать виртуальную среду
py -3.12 -m venv venv
Активируем среду
venv\Scripts\activate
Производим установку библиотек из файла, который я подготовил заранее
pip install -r requirements.txt
Выходим из виртуальной среды
deactivate
Правим файлы конфигураций
В папке data открываем файл tg_bot
Для переменной bot_token указываем токен, который был присвоен ботом @BotFather. Как получить токен смотрим тут: https://core.telegram.org/bots/tutorial#obtain-your-bot-token
В папке data открываем файл ya_weather
Для переменной weather_acc_key указываем ключ, который Яндекс дал для работы с его API. Как получить ключ смотрим тут: https://yandex.ru/pogoda/b2b/console/keys/create
Остальное менять не надо. Переходим к коддингу бота.
Делаем бота
Пробежимся по файлам и папкам программы:
- файл app.py основной файл, который мы будем в конце запускать. Файл менять не надо.
- папка venv была создана в рамках раздела "Настраиваем виртуальную среду" этой статьи.
- папка data содержит 2 файла, которые мы уже поправили в рамках предыдущего раздела этой статьи
- папка config содержит конфиги, которые уже настроены. Как создавать такие конфиги сказано в статье https://dzen.ru/a/aD1wIQ4l3nuUGV5o
- папка bot содержит то, над чем мы будем работать в рамках этой статьи
Откроем папку bot и начнем работу с файла constants.py
Данный файл будет содержать константы:
- FIRST_GEO_MSG (текст сообщения, который бот пользователю будет отправлять с предложением передать свою геолокацию.)
- BTN_GEO_TEXT (название кнопки, на которую пользователь будет нажимать для отправки геолокации)
- TEMPERATURE_MSG (шаблон текста, который будет отправлять пользователю при передаче текущей температуры)
Теперь откроем файл telbot.py
Для него запланирована определенная архитектура
Данный файл и будет содержать нашего бота.
Из архитектуры видно, что:
- класс содержит асинхронные методы
- будет только один внешний метод "run"
- будет метод "_init_commands", который будет инициализировать команды бота
- будет 2 команды: start и weather. И у каждой команды будет свой метод
Первым делом укажем библиотеки, которые будем использовать
from config import Config
from .telbot_worker import TelbotWorker
from .constants import FIRST_GEO_MSG
import asyncio
from aiogram import Bot, Dispatcher, types, F
from aiogram.filters.command import Command
from aiogram.utils.keyboard import ReplyKeyboardBuilder
Класс Config уже был создан заранее.
Класс TelbotWorker создадим позже
Константу FIRST_GEO_MSG мы уже создали
А также укажем внешние библиотеки:
- aiogram - как основную библиотеку для этой статьи.
- asyncio - для работы с асинхронностью т.к. aiogram асинхронная библиотека
Заполним конструктор класса
Мы извлекли из конфига необходимые параметры для работы с телеграмм ботом и api Яндекса.
В рамках строки self.bot: Bot = Bot(token=tg_token) мы создали переменную с нашим ботом.
В рамках строки self.dp: Dispatcher = Dispatcher() мы создали переменную, через которую мы будем получать и передавать команды бота.
Теперь реализуем логику для метода _init_commands
В методе указываем, что
- при отправке боту команды "/start" должна срабатывать функция _start_command
- при получении геолокации должна срабатывать функция _weather_command
Реализуем логику метода _start_command
Метод обращается к TelbotWorker, который нашему методу возвращает builder c кнопкой для передачи геолокации. Саму кнопку сделаем позже.
Метод просит TelbotWorker передать сообщение пользователю и отобразить кнопку.
Необходимо указать await для вызова метода send_mesg. Мы его еще не реализовали, но реализуем асинхронным.
Так как метод _start_command содержит await нам необходимо указать для этого метода async.
Реализуем логику метода _weather_command
Метод _weather_command просит TelbotWorker достать из сообщения параметры геолокации и подготавливает url для api Яндекса.
Потом обращается к TelbotWorker за погодой и просит передать сообщение о погоде пользователю.
Необходимо указать await для вызова метода send_mesg.
Так как метод _weather_command содержит await нам необходимо указать для этого метода async.
Класс TelbotWorker перегружен различной работой. Вместо одного класса надо было сделать 2 или 3 класса. Но на этом функционал этого бота заканчивается, поэтому не стал плодить классы.
Добавим вызов инициализатора команд в конструктор __init__.
Реализуем логику метода run
Метод вызывает start_polling, за счет чего бот ждет команд для их дальнейшей обработки.
Необходимо указать await для вызова start_polling , т.к. он является асинхронным.
Так как метод run содержит await нам необходимо указать для этого метода async.
Перейдем к файлу __init__.py
добавим короткий код
from .telbot import Telbot
Т.е. импортируем класс Telbot из файла telbot
Теперь перейдем к файлу telbot_worker.py
Как я писал выше, надо TelbotWorker класс разбить на 2-3 класса, но т.к. функционал данного бота небольшой, то пусть класс TelbotWorker выполняет всю грязную работу один.
Укажем библиотеки, которые будем использовать
import requests
from aiogram import types
from aiogram.utils.keyboard import ReplyKeyboardBuilder
from .constants import BTN_GEO_TEXT, TEMPERATURE_MSG
Конструктора в классе нет, поэтому сразу переходим к методам.
Реализуем статический метод create_builder
Метод создает кнопку для запроса геолокации пользователя и добавляет её в builder.
Незабываем указать, что метод статический.
Реализуем статический метод send_mesg
Метод является оберткой над message.answer. Может передавать несколько сообщений.
Незабываем указать, что метод статический.
Необходимо указать await для вызова метода answer, т.к. он является асинхронным.
Так как метод send_mesg содержит await нам необходимо указать для этого метода async.
Реализуем статический метод get_lat_lon
Метод принимает на вход Message и извлекает оттуда геолокацию. В реальном проекте надо реализовать обработчик ошибок на случай, если не будет в сообщении геолокации.
Незабываем указать, что метод статический.
Реализуем статический метод get_weather
Метод обращается к Yandex Weather API и получает json с различными параметрами погоды. Мы в рамках данного примера извлекаем только текущую температуру и url на карту с погодой. В реальном проекте данный метод должен иметь обработчик ошибок.
Незабываем указать, что метод статический.
Запускаем бота
Можем запускать бота. Заходим в папку WEATHER_BOT и в cmd прописываем команду
py app.py
Заходим в телеграмм бот. Передаем команду "/start" и нажимаем на кнопку "Отправить местоположение".
Исходники проекта
Подписывайтесь на Дзен, а также приглашаю в мой телеграмм канал, там публикую другой, но не менее интересный контент.