Перейти к содержанию

Telegram API

Telegram API и боты

Привет! Наконец-то подобрались к первому самостоятельному проекту. В этом уроке будет ещё немного теории, а потом ты самостоятельно запилишь проект — телеграм-бота.

Немного о том, как внутри работает Телеграм.

С одной стороны есть серверы Телеграма.

С другой стороны есть программы-клиенты, которые с этими серверами взаимодействуют. Например, официальное мобильное приложение Telegram в твоем телефоне — это клиент, официальное приложение Telegram на твоем ноуте — это тоже клиент.

Ещё существует специальный критпографический протокол MTProto (https://core.telegram.org/mtproto), который используется для их взаимодействия.

Клиенты построены на основе библиотеки TDLib. Разработчики Телеграма выложили в открытый доступ исходный код TDLib (https://github.com/tdlib/td), чтобы другие разработчики на его основе могли создавать собственные клиенты. Так появился, например, популярный Telegram X.

У Телеграма есть API, которое позволяет совершать действия как через свой аккаунт (например, отправлять сообщения в личку), так и через бота.

Бот (сокращение от "робот") — это специальный сервисный аккаунт с немного ограниченным функционалом, который может совершать какие-то полезные действия, никого не напрягая.

В этом уроке мы создадим собственного бота-попугая, который повторяет сообщение, которое ему отправляет пользователь. А в качестве практики ты создашь бота с нормальным функционалом и оформишь его как проект на GitHub'е.

Как создать бота

Чтобы создать своего первого бота, нужно пойти к @BotFather и попросить его это сделать (с уважением).

Найди в Телеграме бота @BotFather и напиши ему команду /start. В ответ он скинет список доступных команд и ссылку на https://core.telegram.org/bots

Нам нужна команда /newbot, отправь её. BotFather попросит ввести имя твоего будущего бота, это то имя, которое будет отображаться сверху, оно может быть любым. Придумай и нажми Enter.

После этого введи юзернейм для бота, обязательное условие — юзернейм должен оканчиваться на "bot" и быть уникальным.

Отлично, после этого ты получишь токен и ссылку на Telegram Bot API: https://core.telegram.org/bots/api. Их нужно использовать для работы с ботом.

Работа с ботом

Бот не начинает диалог первым, поэтому обязательно найди его по юзернейму и отправь /start, чтобы он мог отправлять тебе сообщения.

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

Например, чтобы сделать простейшую штуку — отправить сообщение, можно поступить так:

import requests

BOT_TOKEN = ''

def send_message(text, chat_id):
    params = {
        'text': text,
        'chat_id': chat_id,
    }
    response = requests.get(f'https://api.telegram.org/bot{BOT_TOKEN}/sendMessage', params=params)

if __name__ == "__main__":
    send_message('Привет', 123456)  # пользователю 123456 ушло сообщение "Привет"

Но как обрабатывать те сообщения, которые приходят боту? Существуют разные способы, например, Long Polling и Web Hooks.

Вкратце, что это за способы:

Long Polling — это когда мы постоянно спрашиваем у сервера Телеграм про обновления каждые n секунд: "А не пришло ли мне чего-нибудь? Нет? А сейчас? А сейчас тоже? А теперь?" Для этого используется метод https://core.telegram.org/bots/api#getupdates

Web Hooks — когда мы поднимает собственный сервер с сертификатом и настраиваем специальный URL, на который будут приходить обновления, когда они появятся. Для этого используется метод https://core.telegram.org/bots/api#setwebhook

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

https://github.com/python-telegram-bot/python-telegram-bot

https://github.com/LonamiWebs/Telethon

https://github.com/eternnoir/pyTelegramBotAPI

https://github.com/aiogram/aiogram

С большим отрывом лидирует python-telegram-bot, но мы в курсе будем использовать Telethon, потому что он обладает рядом преимуществ. Почитать про Telethon можно здесь: https://docs.telethon.dev/

Телетон построен на TDLib и работает как клиент, поэтому тебе нужно зарегистрировать приложение на https://my.telegram.org/ и получить API ID и API Hash. Там просто, поэтому разберешься.

Вот пример телеграм-бота, который приветствует тебя после активации и повторяет в ответ то, что ты ему пишешь:

from telethon import TelegramClient, events

BOT_TOKEN = ''
API_ID = 
API_HASH = ''

bot = TelegramClient('bot', API_ID, API_HASH).start(bot_token=BOT_TOKEN)

@bot.on(events.NewMessage(pattern='/start'))
async def start(event):
    """Send a message when the command /start is issued."""
    await event.respond('Привет! Я бот-попугай, повторяю твои сообщения)')
    raise events.StopPropagation

@bot.on(events.NewMessage)
async def echo(event):
    """Echo the user message."""
    await event.respond(event.text)

def main():
    """Start the bot."""
    bot.run_until_disconnected()

if __name__ == '__main__':
    main()

Попробуй самостоятельно разобраться, что здесь происходит. Из незнакомых понятий здесь только async и await, они про асинхронный запуск функций.

Подробнее можно почитать здесь: https://docs.telethon.dev/en/latest/concepts/asyncio.html#mastering-asyncio

Некоторые примеры можно посмотреть здесь: https://github.com/LonamiWebs/Telethon/tree/master/telethon_examples

В целом, все ответы есть здесь, в официальной документации: https://docs.telethon.dev/

А ещё в нашем чате, так что не стесняйся туда писать.

Хостинг для бота

Тебе уже стало понятно, что постоянно держать запущенного бота на своём домашнем компьютере — такой себе вариант. Что делать?

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

Можно купить плату Raspberry PI и запустить на ней. Ну хз...

Лучше всего отправить бота жить на удаленный сервер. В идеале нужно иметь свой облачный сервер, на котором будет запущен бот, но администрирование сервера — тема отдельной недели, поэтому на данном этапе мы возьмём готовое решение, Heroku или PythonAnywhere. А свой сервер поднимем во второй части курса.

Зарегистрируйся на https://www.heroku.com

Пройди на https://dashboard.heroku.com/apps и создай приложение (New → Create New App, справа-сверху).

Открой созданное приложение и пройди во вкладку Deploy. Проще всего задеплоить бота напрямую с Гитхаба, поэтому выбери GitHub как Deployment method. Нужно будет подключить твой аккаунт, согласись на это. Возможно, попросят ввести пароль. Затем введи название репозитория, на котором будет лежать код с ботом.

Есть пара замечаний о коде. Во-первых, в репо должен лежать файл requirements.txt со списком зависимостей, которые используются в проекте. Во-вторых, в репо должен лежать файл Procfile в котором указана точка входа — имя файла с ботом. Пример оформленного для деплоя репо от Хероку, после которого всё станет ясно: https://github.com/heroku/python-sample. Сделай по аналогии.

Переменные окружения. Мы помним, что хранить в репо токены и прочие секретные данные нельзя, но как тогда прокинуть их на Хероку? Зайди в Settings, найди Config Vars и нажми Reveal Config Vars. Затем проставь нужные переменные окружения. Считай это аналогом файла .env. Они подтянутся аналогичным образом.

Затем нажми Deploy Branch. Как просто, не правда ли?

Практика (проект)

Проект должен использовать Telegram Bot API и интерфейс телеграм-бота для взаимодействия с пользователем. Взаимодействовать с API рекомендуется через библиотеку Telethon.

Проект нужно оформить на GitHub'е.

Примеры проектов (но нужно придумать свой)

Python 101 Coding Challenge

Телеграм-бот python101 coding challenge. По аналогии с Leetcode Coding Challende, каждый день в 9 утра предлагает решить задачку. Код решения нужно отправить боту (продумать механику), оно прогоняется на тестах и в случае успеха засчитывается.

Есть кнопки или команды для вступления в челлендж. Если три дня не присылаешь задания, то ты автоматически выбываешь. Может быть таблица с результатами.

Who is molodec

Что-нибудь с рандомом: например, кто сегодня молодец. Бот после команды /molodec_today вытаскивает список людей в чате, рандомно выбирает пользователя и тегает его в чате со словами "Поздравляю, ты сегодня молодец!"

Karma bot

Карма-бот, ты можешь плюсовать участника чата, например если он тебе в чем-то помог, у каждого есть количество баллов. Можно вывести рейтинг.

Kick bot

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

Cat gif

Бот, который скидывает гифку с котиком. Найти какой-нибудь сервис с гифками, рандомно выбирать одну и скидывать по запросу. Гифки не должны повторяться.

Идея от пользователя trapwalker с Хабра

"Можно сделать бота, который притворяясь человеком бдит денно и нощно и детектит все отредактированные и удалённые сообщения, чтобы переслать их хозяину в отдельный канал в первозданном виде прямо в момент редактирования или удаления.Наверно такое можно даже за деньги предлагать=).Идею дарю. Хотя 100% уже кто-то додумался и сделал.Всегда же интересно всякие паблики и каналы помониторить на предмет нечаянных сливов и зашкваров, которые долго в истории не провисят."

Геокодер бот

Скидывать адрес по координатам. Взять Яндекс.Геокодер API и обернуть в бота.

Пинг-бот

Пинг-бот, проверяющий состояние сервера. Присылает уведомление о том, что сервер упал. Просто взять задание с прошлой недели и обернуть в бота.