Создание Telegram Bot с помощью Python

Перевод статьи Alex Ryabtsev “Introduction or Why You Should Try a Bot”.

Боты повсюду. Кажется, что еще вчера мы даже не подозревали об их существовании, а сейчас уже с трудом можем представить свою жизнь без них. Они стали широко популярны среди многочисленных активных пользователей мессенджеров, поскольку имеют различные сферы применения – от развлекательного контента, включая пошаговые игры и сбор бонусных баллов в ресторанах, до ведения личного плана питания, отслеживания доставки и даже осуществления платежей за различные услуги.

Скачивайте книги ТОЛЬКО на русском языке у нас в телеграм канале: PythonBooksRU

Почему они так популярны? В чем их секрет? Я думаю, что более правильно будет спросить, почему они удобнее, чем приложение. И на это есть несколько причин.

Чем Telegram Bot лучше приложения?

(Этот раздел можно пропустить, если вы и так знаете, почему вам нужен именно бот).

1. Минималистичный и простой дизайн

По сравнению с многочисленными приложениями с различным дизайном, когда приходится запоминать, где и что нажимать, боты более универсальны и просты. Telegram Bot предлагает простое взаимодействие посредством текстов и кнопок.

Вообще, никто не требовал от ботов красочного дизайна. Однако с весны 2022 года Telegram предоставил разработчикам ботов инструменты для создания бесконечно гибких интерфейсов с помощью JavaScript. Теперь, если у вас есть опыт создания ботов для Telegram, знание Python и мотивация, вы можете создать полноценную замену обычному сайту.

2. Минимум рекламы и фокус на потребностях пользователей

Вам не придется устанавливать сотни приложений для каждого сервиса, если всю необходимую помощь вам окажет Telegram Bot. Это особенно полезно для ресторанов и магазинов.

Клиенты редко горят желанием устанавливать приложения из кучи мест, которые они посетили. Из-за этого владельцы бизнеса упускают отзывы клиентов и теряют с ними связь. Если бы у каждого из этих мест был свой бот, доступный в разных мессенджерах, это было бы удобнее и дружелюбнее для пользователей.

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

3. Отсутствие необходимости в регистрации, авторизации и постоянных перелогинах

При настройке Telegram Bot можно использовать Python и его библиотеки для автоматизации авторизации. Это позволяет пользователю пройти авторизацию только один раз при добавлении бота в чат. Клиент может использовать бота столько, сколько нужно, а когда в нем больше нет необходимости, пользователь просто блокирует бота. Вот и все, легко! Больше никаких сбросов пароля.

Не нужно запоминать пароли или используемые логины. Добавление бота на сайт или в приложение увеличивает количество пользовательской аудитории, так как делает общение с клиентами и оказание им помощи намного проще и удобнее.

Кроме того, популярность мессенджера также играет свою роль. А если говорить о ботах в Telegram, то летом 2022 года Telegram объявил, что число ежемесячных активных пользователей превысит 700 миллионов.

Итак, мы описали основные преимущества ботов, и теперь у вас должно появиться желание создать своего собственного бота. Давайте перейдем к практике. Но сначала мы рассмотрим вопросы, которые необходимо решить на этапе проектирования.

Нюансы разработки Telegram Bot

Выше мы определили причины создания бота. В этой части мы планируем рассказать о том, как создать приложение и какие инструменты разработки использовать. Далее мы покажем, как создать Telegram-бота на Python и научим его разворачивать.

Поскольку это статья по Telegram Bot для начинающих, примеры кода не должны быть сложными. Мы запустим сервер с одним эндпоинтом, который будет получать наши сообщения в Telegram и отправлять ответ.

Для этого мы будем использовать следующие инструменты:

  • bottle – для нашего сервера; простой и легкий микро-веб-фреймворк WSGI
  • requests – для отправки запросов в telegram. Библиотека request не нуждается в чрезмерном представлении. Она повсеместно используется во всем мире в самых разных проектах.

Примечание: вам необходимо установить эти инструменты на свой компьютер. Они понадобятся нам позже. Для этого давайте создадим виртуальное окружение в директории проекта и установим необходимые инструменты через pip. Если вы не знакомы с тем, что такое окружение, просто установите необходимые библиотеки, выполнив pip install bottle requests.

python3 -m venv venv
. ./venv/bin/activate
pip install bottle requests
  • ngrok – это приложение, которое предоставляет нам публичные URL-адреса для взаимодействия с Telegram WebHook на этапе разработки (см. информацию о WebHook ниже). Это полезно, так как Telegram не сможет установить соединение с нашим локальным сервером, потому что мы не можем указать наш локальный адрес в конфигурации Telegram API. Необходимо скачать ngrok с официального сайта и поместить установленное приложение в папку с проектом.

Как насчет того, чтобы создать своего первого бота?

В этой части вы найдете подробное руководство по созданию Telegram Bot. Также мы рассмотрим полезные инструменты для его разработки на Python.

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

Откройте приложение Telegram, найдите @BotFather и начните чат. Отправьте команду /newbot и следуйте инструкциям. После выполнения начальных шагов вы получите:

Вот, собственно, и все. На данный момент бот на 100% пассивен.

Вам нужно инициализировать диалог с ботом. Откройте поиск и введите имя вашего бота. Начните диалог, нажав на кнопку /start. Введите что-то вроде “Привет”. Это сообщение очень важно, так как это первое обновление, которое получит ваш бот.

Если это ваш первый опыт создания API, вы можете легко понять идею с помощью веб-браузера. Откройте новую вкладку в браузере и используйте URL Telegram api: api.telegram. org/bot<ваш токен >/getUpdates.

Когда вы открываете этот URL в браузере, вы делаете запрос на сервер Telegram, который отвечает JSON. Ответ напоминает словарь Python. Вы должны увидеть что-то вроде этого:

{"ok":true,"result":[{"update_id":523349956,
"message":{"message_id":51,"from":{"id":303262877,"first_name":"YourName"},"chat":{"id":303262877,"first_name":"YourName","type":"private"},"date":1486829360,"text":"Hello"}}]}

Примечание редакции: кратко о формате JSON можно почитать в статье “Кодирование JSON на Python”.

Если вы откроете документацию бота и посмотрите раздел метода /sendMessage, то заметите, что этот метод требует 2 дополнительных параметра: chat_id и text. В строке поиска браузера вы можете соединить параметры цепочкой, используя ? для первого и & для всех последующих. Отправка сообщения будет выглядеть следующим образом:

/sendMessage?chat_id=303262877&text=test

Попробуйте получить ответ от вашего бота, заменив chat_id на тот, который вы получили, вызвав /getUpdates. В моем случае это 303262877. Текстовый параметр выбирайте сами. Запрос должен выглядеть следующим образом:

api.telegram. org/ bot<ваш-токен>/sendMessage?chat_id=&text=<ваш-текст>

WebHook

(Если вы уже знакомы с концепцией WebHook, эту часть можно пропустить).

Если говорить коротко, WebHook – это концепция API, которая становится все более популярной. Эта концепция проста. WebHook – это обратный вызов HTTP: HTTP POST, который отправляется, когда что-то происходит; простое уведомление о событии через HTTP POST.

Объясню немного подробнее: иногда взаимодействие между приложениями в сети требует немедленной реакции на событие, в то время как решения для постоянных и непрерывных соединений в большинстве случаев громоздки, требовательны и трудно поддерживаются. В этом случае лучшим и самым простым решением является немедленная отправка колбэка через HTTP (чаще всего POST).

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

Такая концепция называется WebHook. Она широко используется для:

  • получения данных в режиме реального времени
  • получения данных и их передачи
  • обработки данных и предоставления чего-то взамен

Кажется, что это лучшее решение для взаимодействия клиента Telegram (приложения Telegram) с нашим проектом.

Схематическая иллюстрация концепции WebHook

Написание кода Telegram Bot

Наконец, мы приступаем к самой практической части, где вы сможете написать Telegram-бота.

Основная задача – научить нашего бота отвечать на полученные сообщения.

Во-первых, создайте папку для нашего проекта бота. Во-вторых, создайте в этой папке файл bot.py для сервера бота.

Файл bot.py:

from bottle import run, post
@post('/')  # our python function based endpoint
def main():
    return
if __name__ == '__main__':
    run(host='localhost', port=8080, debug=True)

1. Давайте попробуем запустить наш сервер. Для этого откройте bash в папке bot.

python bot.py

В результате вы должны увидеть что-то вроде этого:

2. Затем откройте новую вкладку. В ней мы запустим ngrok (./ngrok http <our_server_port>):

./ngrok http 8080

В результате вы увидите что-то вроде этого:

3. Теперь давайте установим WebHook.

Сейчас мы сообщим Телеграму, куда ему отправлять сообщения о событиях в боте. Для этого откройте браузер и перейдите по ссылке

https://api.telegram.org/bot<ваш_токен>/setWebHook?url=https://<ваш ngrok url>.ngrok.io/
  • Примечание: чтобы найти ngrok URL, необходимо запустить ngrok. Затем на экране, подобном приведенному ниже, вы найдете URL (он выделен на нашем скриншоте). Этот URL вы используете в ссылке для установки WebHook.

Ответ на переход по ссылке должен иметь следующий вид:

{"ok":true, "result":true, "description": "Webhook was set"}.

Давайте проверим, удалось ли вам настроить WebHook. Перейдите по этой ссылке, используя ваш токен:

https://api.telegram.org/bot<ваш_токен>/getWebhookInfo

Если все правильно, вы увидите перед ключом URL то же значение адреса ngrok, которое вы указали при настройке.

Поздравляем, it’s alive!

Теперь нам нужно реализовать механизм запроса/ответа на сообщение.

По сути, наш эндпоинт получает данные в формате JSON. Поэтому, как правило, вы должны увидеть сообщение с данными.

from bottle import run, post, request as bottle_request  # <--- we add bottle request
@post('/')
def main():
    data = bottle_request.json  # <--- extract all request data
    print(data)
    return
if __name__ == '__main__':
    run(host='localhost', port=8080, debug=True)

Вы должны увидеть что-то вроде этого на вкладке консоли, где запущен сервер.

{'update_id': <integer>, 'message': {'message_id': <integer>, 'from': {'id': <your telegram id>, 'is_bot': False, 'first_name': '<your telegram name>', 'last_name': '<...>', 'username': '<...>', 'language_code': 'en-En'}, 'chat': {'id': <integer chat id>, 'first_name': '<...>', 'last_name': '<...>', 'username': '<...>', 'type': 'private'}, 'date': 1535022558, 'text': '1'}}

Более подробную информацию о параметрах вы можете найти в официальной документации Telegram.

Теперь нам нужно извлечь chat_id и text, чтобы отправить наше сообщение пользователю.

from bottle import (
    run, post, response, request as bottle_request
)
def get_chat_id(data):
    """
    Method to extract chat id from telegram request.
    """
    chat_id = data['message']['chat']['id']
    return chat_id
def get_message(data):
    """
    Method to extract message id from telegram request.
    """
    message_text = data['message']['text']
    return message_text
def change_text_message(text):
    """
    To turn our message backwards.
    """
    return text[::-1]
@post('/')
def main():
    data = bottle_request.json
    answer_data = prepare_data_for_answer(data)
    return response  # status 200 OK by default

Итак, мы уже подготовили ответ. Давайте отправим его Telegram-боту.

import requests
from bottle import (
    run, post, response, request as bottle_request
)
BOT_URL = 'https://api.telegram.org/bot<YOUR_TOKEN>/' # <--- add your telegram token here; it should be like https://api.telegram.org/bot12345678:SOMErAn2dom/
def get_chat_id(data):
    """
    Method to extract chat id from telegram request.
    """
    chat_id = data['message']['chat']['id']
    return chat_id
def get_message(data):
    """
    Method to extract message id from telegram request.
    """
    message_text = data['message']['text']
    return message_text
def send_message(prepared_data):
    """
    Prepared data should be json which includes at least `chat_id` and `text`
    """
    message_url = BOT_URL + 'sendMessage'
    requests.post(message_url, json=prepared_data)  # don't forget to make import requests lib
def change_text_message(text):
    """
    To enable turning our message inside out
    """
    return text[::-1]
def prepare_data_for_answer(data):
    answer = change_text_message(get_message(data))
    json_data = {
        "chat_id": get_chat_id(data),
        "text": answer,
    }
    return json_data
@post('/')
def main():
    data = bottle_request.json
    answer_data = prepare_data_for_answer(data)
    send_message(answer_data)  # <--- function for sending answer
    return response  # status 200 OK by default
if __name__ == '__main__':
    run(host='localhost', port=8080, debug=True)

После всех настроек и написания, если все работает, давайте попробуем пообщаться с нашим ботом.

Теперь давайте сделаем наш код более читабельным и реализуем структуру ООП.

import requests
from bottle import Bottle, response, request as bottle_request
class BotHandlerMixin:
    BOT_URL = None
    def get_chat_id(self, data):
        """
        Method to extract chat id from telegram request.
        """
        chat_id = data['message']['chat']['id']
        return chat_id
    def get_message(self, data):
        """
        Method to extract message id from telegram request.
        """
        message_text = data['message']['text']
        return message_text
    def send_message(self, prepared_data):
        """
        Prepared data should be json which includes at least `chat_id` and `text`
        """
        message_url = self.BOT_URL + 'sendMessage'
        requests.post(message_url, json=prepared_data)
class TelegramBot(BotHandlerMixin, Bottle):
    BOT_URL = 'https://api.telegram.org/bot000000000:aaaaaaaaaaaaaaaaaaaaaaaaaa/'
    def __init__(self, *args, **kwargs):
        super(TelegramBot, self).__init__()
        self.route('/', callback=self.post_handler, method="POST")
    def change_text_message(self, text):
        return text[::-1]
    def prepare_data_for_answer(self, data):
        message = self.get_message(data)
        answer = self.change_text_message(message)
        chat_id = self.get_chat_id(data)
        json_data = {
            "chat_id": chat_id,
            "text": answer,
        }
        return json_data
    def post_handler(self):
        data = bottle_request.json
        answer_data = self.prepare_data_for_answer(data)
        self.send_message(answer_data)
        return response
if __name__ == '__main__':
    app = TelegramBot()
    app.run(host='localhost', port=8080)

Вот, собственно, и все. Теперь вы создали работающего бота для Telegram, на базе Python и даже умеющего писать фразу “racecar” задом наперед. Поздравляем!

1 комментарий к “Создание Telegram Bot с помощью Python”

  1. Пингбэк: Простой Telegram бот для логирования

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *