Сообщить об ошибке.

Чистый интерфейс Python для Telegram Bot API

Пакет python-telegram-bot предоставляет чистый интерфейс Python для Telegram Bot API. Он совместим с версиями Python 3.7+. Пакет python-telegram-bot также может работать с PyPy3 (официально не поддерживается), хотя раньше было много проблем.

!!! Очень важный момент. API предоставляется через класс telegram.Bot. Методы, определенные в telegram.Bot являются эквивалентами в виде методов snake_case, описанных в официальной документации Telegram Bot API. Для удобства, также доступны точные названия методов в виде camelCase, указанные в официальной документации Telegram. Так, например, вызов telegram.Bot.send_message совпадает с вызовом метода telegram.Bot.sendMessage официальной документации Telegram Bot API. Другими словами подмодуль telegram является оберткой Python официального API Telegram.

Все классы объектов Telegram Bot API расположены в основном модуле пакета telegram, например, класс объекта Message доступен как telegram.Message.

Чтобы сгенерировать токен доступа, необходимо пообщаться с @BotFather и выполнить несколько простых шагов, описанных в разделе Команды и оповещения @BotFather в Telegram.

Внимание! Модуль python-telegram-bot-raw версии 13.x будут придерживаться многопоточной парадигмы программирования (на данный момент актуальна версия 13.15). Модуль версий 20.x и новее предоставляют чистый асинхронный Python интерфейс для Telegram Bot API. Дополнительно смотрите основные изменения в пакете python-telegram-bot версии 20.x.

Содержание:


Установка модуля python-telegram-bot-raw в виртуальное окружение:

Модуль python-telegram-bot-raw предоставляет только интерфейс Python для Telegram Bot API, без дополнительных вспомогательных пакетов типа telegram.ext (фильтры, обработчики, планировщик, вебхук и т.д.).

Другими словами, ставим только основной модуль telegram (API Telegram) пакета python-telegram-bot:

# создаем виртуальное окружение, если нет
$ python3 -m venv .telegram --prompt TelegramBot
# активируем виртуальное окружение 
$ source .telegram/bin/activate
# ставим многопоточную версию python-telegram-bot-raw
(TelegramBot):~$ python3 -m pip install python-telegram-bot-raw==13.15 -U
# или установка асинхронной версии python-telegram-bot-raw
(TelegramBot):~$ python3 -m pip install python-telegram-bot-raw -U

Многопоточный интерфейс Python для Telegram Bot API (версия 13.x).

Сначала создаем экземпляр telegram.Bot. Константу TOKEN следует заменить токеном API, который был получен от @BotFather:

>>> import telegram
>>> TOKEN = 'Замените эту строку на token, полученный от @BotFather'
>>> bot = telegram.Bot(token=TOKEN)
# Чтобы проверить правильность учетных данных, вызываем метод bot.getMe():
>>> print(bot.get_me())
# {"first_name": "Toledo's Palace Bot", "username": "ToledosPalaceBot"}

Примечание: боты не могут самостоятельно инициировать разговоры с пользователями. Пользователь должен либо добавить их в группу, либо сначала отправить им сообщение. Для подключения к боту или каналу люди в основном используются ссылки, такие как https://telegram.me/bot_username или можно попробовать найти бота по имени в своем десктопном или мобильном приложении Telegram.

Как отвечать/получать сообщения на чистом API?

Для получения сообщений, отправленных боту, можно использовать метод API bot.getUpdates.

На чистом API это выглядит следующим образом:

updates = bot.get_updates()
print([upd.message.text for upd in updates])

Получение изображения, отправленного боту:

updates = bot.get_updates()
print([upd.message.photo for upd in updates if upd.message.photo])

Для отправки сообщения всегда нужен будет chat_id:

chat_id = bot.get_updates()[-1].message.chat_id
message = bot.send_message(chat_id=chat_id, text="Я бот, поговори со мной!")

Примечание. Метод .send_message, как и любой из методов .send_* класса Bot возвращает экземпляр класса Message, поэтому его можно использовать в коде позже.

Ответ на конкретное сообщение, полученное в обновлении:

updates = bot.get_updates()
updates.message.reply_text("Прости, я не могу этого сделать.")

Примечание. Существуют эквиваленты этого метода для ответа с фотографиями, аудио и т. д., а так же аналогичные эквиваленты встречаются по всей библиотеке python-telegram-bot.

Пример бота для ответа на сообщения на чистой реализации API Telegram.

Простой бот для ответа на сообщения Telegram. Пример построен на чистом API Telegram.

import logging
from time import sleep

import telegram
from telegram.error import NetworkError, Unauthorized

UPDATE_ID = None

def echo(bot):
    """Эхо сообщение отправленное пользователем."""
    global UPDATE_ID
    # Запрашиваем обновление после последнего update_id
    for update in bot.get_updates(offset=UPDATE_ID, timeout=10):
        UPDATE_ID = update.update_id + 1

        # бот может получать обновления без сообщений
        if update.message:
            # не все сообщения содержат текст
            if update.message.text:
                # Ответ на сообщение
                update.message.reply_text(f'ECHO: {update.message.text}')


if __name__ == '__main__':
    """Запускаем бота."""
    global UPDATE_ID
    # Токен авторизации бота Telegram
    bot = telegram.Bot('TOKEN')

    # получаем первый ожидающий `update_id`
    try:
        UPDATE_ID = bot.get_updates()[0].update_id
    except IndexError:
        UPDATE_ID = None

    logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    # запускаем бесконечный цикл, который будет 
    # ждать новые сообщения с тайм аутом в 1 сек
    while True:
        sleep(1)
        try:
            # вызываем функцию "Эхо сообщения"
            echo(bot)
        except NetworkError:
            # ошибка сети, ждем 5 секунд
            sleep(5)
        except Unauthorized:
            # Пользователь удалил или заблокировал бота.
            UPDATE_ID += 1

Асинхронный интерфейс Python для Telegram Bot API (версия 20.x).

Чтобы получить представление об асинхронном интерфейс Python для Telegram Bot API и о том, как его использовать с python-telegram-bot версии 20.x, создадим новый файл async-bot.py.

Сначала создадим экземпляр telegram.Bot и проверим правильность учетных данных. Константу TOKEN следует заменить токеном Telegram Bot API, который был получен от @BotFather.

import asyncio
import telegram

TOKEN = 'Замените эту строку на token, полученный от @BotFather'

async def main():
    bot = telegram.Bot(TOKEN)
    async with bot:
        # проверка правильности учетных данных
        print(await bot.get_me())

if __name__ == '__main__':
    asyncio.run(main())

Здесь вызываем метод API bot.get_me(). Асинхронный менеджер контекста - строка: async with bot: гарантирует, что python-telegram-bot сможет правильно получать и освобождать ресурсы. Если запустить файл, то получим вывод:

$ python3 async-bot.py
# {"first_name": "Toledo's Palace Bot", "username": "ToledosPalaceBot"}

Теперь можно попытаться что-то сделать, например, отправить сообщение.

Примечание: боты не могут самостоятельно инициировать разговоры с пользователями. Пользователь должен либо добавить их в группу, либо сначала отправить им сообщение. Для подключения к боту или каналу люди в основном используются ссылки, такие как https://telegram.me/bot_username или можно попробовать найти бота по имени в своем десктопном или мобильном приложении Telegram.

Нужно сначала отправить сообщение боту. Если это сделано, то можно получить обновление. Перепишем функцию main() в файле async-bot.py:

async def main():
    bot = telegram.Bot("TOKEN")
    async with bot:
        # получение обновления 
        print((await bot.get_updates())[0])

Вывод теперь должен выглядеть примерно так (вывод немного сокращен):

$ python3 async-bot.py
# {'update_id': 218946040, 
#   'message': {'message_id': 23833, 'date': 1626017436, 'text': 'Hi!', 
#     'chat': {'type': 'private', 'last_name': 'Doe', 'username': 'JohnDoe', 'id': 1234567890, 'first_name': 'John'}, 
#     'from': {'last_name': 'Doe', 'username': 'JohnDoe', 'id': 1234567890, 'is_bot': False, ...}, 
#     ...
#   }
# }

Из полученного сообщения нужно извлечь идентификатор чата, здесь это 1234567890. Обратите внимание, что можно получить к нему доступ также как update[0].message.from_user.id, так как update[0] является экземпляром класса Update. Теперь, когда идентификатор чата получен, можно отправить сообщение. Для этого снова перепишем функцию main():

async def main():
    bot = telegram.Bot("TOKEN")
    async with bot:
        # отправка сообщения
        await bot.send_message(text='Hi John!', chat_id=1234567890)