Создаём Telegram-бота на Python с помощью pyTelegramBotAPI (telebot)

Создаём Telegram-бота на Python с помощью pyTelegramBotAPI (telebot)

Сегодня будем учиться создавать ботов в Telegram с помощью Python. 
Попробуем заставить бота присылать сводку погоды по нашему городу.

Нам потребуется:

  1. Компьютер или ноутбук (При должном усердии можно попробовать на телефоне).
  2. Python 3 (Мы будем работать на версии 3.10).
  3. Редактор кода (Я использую PyCharm).
  4. Соединение с интернетом.

У всех на слуху две библиотеки для разработки telegram-ботов, это: 
- telebot (он же pyTelegramBotAPI),
- aiogram. 

Мы будем использовать telebot как более простой инструмент для личного пользования. Посмотрим как запустить первого бота, что для этого нужно и на что он способен.

Как и aiogram, telebot является адаптацией API telegram для взаимодействия с ответами от сайта. Со справкой API telegram можно ознакомиться тут https://core.telegram.org/. Там же вы сможете узнать подробнее об ответах API.

Получение токена для Telegram-бота

Чтобы создать нашего первого бота на Python надо обратиться к официальному боту от Telegram - BotFather. Там можно создать бота и получить его токен. Токен – это аналог пароля, который позволит нам управлять ботом изнутри и программировать его ответы.

Переходим в BotFather - https://t.me/BotFather и нажимаем «Запустить»:

Дальше выбираем команду /newbot и следуем всем указанием, и в конце мы получаем токен нашего бота:

Установка библиотеки telebot и знакомство с pyTelegramBotAPI

После получения токена нужно скачать библиотеку telebot:

pip install pyTelegramBotAPI 

если вы на macOS, то:

pip3 install pyTelegramBotAPI

Мы не будем раскладывать проект по модулям, поэтому у нас будет один исполнимый файл main.py. После создания файла надо импортировать библиотеку и наш токен:

import telebot
api_token = 'Ваш токен вставлять сюда'

Первым делом следует инициализировать бота, передав в него токен, полученный от BotFather:

bot = telebot.TeleBot(api_token)

Дальше убедимся, что все корректно работает и заставим отправлять полученное сообщение обратно:

@bot.message_handler(content_types=['text'])
def echo(message):
    bot.send_message(message.chat.id, text=f"{message.text}")

Бот работает за cчёт декораторов, которые указывают, что мы хотим от него. Message handler – это обработчик всех сообщений, которые отправляет пользователь. В списке content_types перечисляем типы сообщений, которые хотим принимать. Можно указать text, audio, image и document. 

У объекта bot есть множество методов, частью которых мы будем пользоваться. Основной из них - send message.

Чтобы заставить бота принимать сообщение, в конце файла пропишем:

bot.polling(none_stop=True)

Параметр none_stop указывает, что мы хотим принимать сообщения постоянно. 
В стандартном положении параметр равен False, но мы ставим True.

После всех манипуляций получаем свое же сообщение:

Работа с API Яндекс Погоды

Перейдем к добавлению нужных функций - получению данных о погоде. 

Для погоды мы будем пользоваться услугами бесплатного API от Яндекс Погоды: 
https://yandex.ru/dev/weather/. Следует отметить, что бесплатный API от Яндекса ограничен 50 запросам в сутки. Если вас такое количество не устраивает, можно воспользоваться OpenWeather. 

Запрос будет выглядеть так:

https://api.weather.yandex.ru/v2/informers?lat=55.75222&lon=37.61556

Запрос состоит из местоположения - в данном случае указаны координаты Москвы. Далее можно просить у пользователя геолокацию и присылать ему погоду по его координатам.

Для отправки GET-запроса к API Яндекс.Погоды нам поможет библиотека requests, а для обработки ответа - библиотека json. 

Устанавливаем requests:

pip install requests

для macOS:

pip3 install requests 

Библиотека requests предназначена для работы с GET и POST запросами, которые обычный пользователь делает через браузер. Теперь же мы можем общаться с сервером через python оставляя браузер за скобками. Часто используют requests вместе с BS4 (beautiful soup 4), чтобы удобно получать и анализировать информацию из html кода. Но в наш случае другая задача.

Анонсы всех видео, статей и полезностей - в нашем Telegram-канале🔥
Присоединяйтесь, обсуждайте и автоматизируйте!

API Яндекс.Погоды отдаёт данные в формате JSON, поэтому библиотека json подойдёт лучше всего. JSON основан на JavaScript объекте и часто используется при обмене данными. Раньше он использовался только на сайтаx для работы с текстовыми данными. Сейчас его используют почти везде для удобного обмена данными. JSON принимают все языки программирования, что является его большим плюсом. В python библиотека json уже установлена и не требует отдельной команды.

Добавляем импорт нужных библиотек:

import requests
import json

До этого мы не затрагивали тему, как именно обрабатывать команды через слеш. Для этого у декоратора есть метод message_handlers, внутрь которого мы передаем название команд:

@bot.message_handler(commands=['get_weather', 'weather', 'pogoda']):
def get_weather(message):
    pass

Для удобства выносим токен Яндекс.Погоды и ссылку в отдельные переменные:

url = "https://api.weather.yandex.ru/v2/informers?lat=55.75222&lon=37.61556"
headers = {"X-Yandex-API-Key": "weather token"}

Отправим себе в Telegram полный ответ от API Яндекс.Погоды и проверим что все работает:

@bot.message_handler(commands=['get_weather', 'weather', 'pogoda'])
def get_weather(message):
    r = requests.get(url=url, headers=headers)
    bot.send_message(message.chat.id, r.text)

После получения ответа сформируем нормальный ответ для пользователя. Сразу сделаем проверку на status_code, чтобы оповестить пользователя, если проблемы на стороне API. После получения ответа от API в текстовом формате, надо перевести его в словарь. Для этого подключаем библиотеку json - в функцию loads мы передаем текст ответа, а на выходе получаем объект типа dict (словарь):

@bot.message_handler(commands=['get_weather', 'weather', 'pogoda'])
def get_weather(message):
    r = requests.get(url=url, headers=headers)
    bot.send_message(message.chat.id, r.text)
    if r.status_code == 200:
        data = json.loads(r.text)
        fact = data["fact"]
        bot.send_message(message.chat.id, text=f'Now in Moscow {fact["temp"]}°, feels like {fact["feels_like"]}°. Now on the street {fact["condition"]}')
    else:
        bot.send_message(message.chat.id, 'Problems on weather API')

Теперь бот отправляет температуру, как она ощущается и какая сейчас погода:

Настройка команд для telegram-бота

Нам осталось сделать реакцию на команду /start. Она будет выводить команду для получения данных о погоде:

@bot.message_handler(commands=['start'])
def get_weather(message):
	bot.send_message(message.chat.id, text=f'Hello,	
	{message.from_user.username}!
	\n\nI can show you the weather with: 
	\n/weather\n/pogoda\n/get_weather')

Мы обращаемся к информации, которая приходит нам в сообщении пользователя, чтобы получить из нее имя пользователя. Подробнее узнать о сообщениях пользователей можно тут https://core.telegram.org/constructor/message.

Теперь создадим подсказки для пользователей. Библиотека pyTElegramBotAPI не позволяет из кода редактировать подсказки для написания команды. Чтобы это сделать нам потребуется несколько операций в BotFather: 

  1. кликаем на меню
  2. выбираем команду /mybots
  3. ищем нашего бота
  4. edit bot
  5. и выбираем edit commands
  6. дальше вводим нашу команду (Пример: команда – описание)

  После всех манипуляций у нас появится всплывающая менюшка с командами:

Финальный код Telegram-бота на Python

Мы с вами затронули лишь малу часть того, что можно сделать с помощью python и Telegram. Telebot - не самая лучшая библиотека для создания ботов под большую аудитории. Если вы хотите писать бот для магазинов, вам потребуется более сильные инструменты разработки, которые есть в aiogram. 

Если вам хочется потренироваться самостоятельно - попробуйте написать бота со следующими функциями: конвертор валюты, сводка по курсу валюты.

Весь код из урока:

import telebot
import requests
import json

api_token = '5347819163:********lZu1qWQc5f55DPk'

url = "https://api.weather.yandex.ru/v2/informers?lat=55.75222&lon=37.61556"
headers = {"X-Yandex-API-Key": "43e3e725-*******-0750c87d0d54"}

bot = telebot.TeleBot(api_token)

@bot.message_handler(commands=['start'])
def get_weather(message):
    bot.send_message(message.chat.id, text=f'Hello, 
    {message.from_user.username}!
    \n\nI can show you the weather with: 
    \n/weather\n/pogoda\n/get_weather')

@bot.message_handler(commands=['get_weather', 'weather', 'pogoda'])
def get_weather(message):
    r = requests.get(url=url, headers=headers)
    bot.send_message(message.chat.id, r.text)
    if r.status_code == 200:
        data = json.loads(r.text)
        fact = data["fact"]
        bot.send_message(message.chat.id, text=f'Now in Moscow {fact["temp"]}°, feels like {fact["feels_like"]}°. Now on the street {fact["condition"]}')
    else:
        bot.send_message(message.chat.id, 'Problems on weather API')

bot.polling(none_stop=True)

Полезные ссылки:

Yandex Weather: https://yandex.ru/dev/weather/

Документация Yandex API: https://yandex.ru/dev/weather/doc/dg/concepts/forecast-info.html

pyTealegramBotAPI на Guthub: https://github.com/eternnoir/pyTelegramBotAPI

Комментарии