Инструкция: Как создавать ботов в Telegram

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

Прежде всего, бот для Telegram — это по-прежнему приложение, запущенное на вашей стороне и осуществляющее запросы к Telegram Bot API. Причем API довольное простое — бот обращается на определенный URL с параметрами, а Telegram отвечает JSON объектом.

Рассмотрим API на примере создания тривиального бота:

1. Регистрация

Прежде чем начинать разработку, бота необходимо зарегистрировать и получить его уникальный id, являющийся одновременно и токеном. Для этого в Telegram существует специальный бот — @BotFather .

Пишем ему /start и получаем список всех его команд.

Первая и главная — /newbot — отправляем ему и бот просит придумать имя нашему новому боту. Единственное ограничение на имя — в конце оно должно оканчиваться на «bot». В случае успеха BotFather возвращает токен бота и ссылку для быстрого добавления бота в контакты, иначе придется поломать голову над именем.

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

Не забудьте проверить полученный токен с помощью ссылки api. telegram. org/bot<TOKEN>/getMe. говорят, не всегда работает с первого раза.

2. Программирование

Создавать бота буду на Python3, однако благодаря адекватности этого языка алгоритмы легко переносятся на любой другой.

Telegram позволяет не делать выгрузку сообщений вручную, а поставить webHook, и тогда они сами будут присылать каждое сообщение. Для Python, чтобы не заморачиваться с cgi и потоками, удобно использовать какой-нибудь реактор, поэтому я для реализации выбрал tornado. web. (для GAE удобно использовать связку Python2+Flask)

Каркас бота:

Здесь мы при запуске бота устанавливаем вебхук на наш адрес и отлавливаем сигнал выхода, чтобы вернуть поведение с ручной выгрузкой событий.

Приложение торнадо для обработки запросов принимает класс tornado. web. RequestHandler, в котором и будет логика бота.

Здесь CMD — словарь доступных команд, а send_reply — функция отправки ответа, которая на вход принимает уже сформированный объект Message .

Собственно, её код довольно прост:

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

3. Команды

Перво-наперво, необходимо соблюсти соглашение Telegram и научить бота двум командам: /start и /help:

Структура message[‘from’] — это объект типа User. она предоставляет боту информацию как id пользователя, так и его имя. Для ответов же полезнее использовать message[‘chat’][‘id’] — в случае личного общения там будет User, а в случае чата — id чата. В противном случае можно получить ситуацию, когда пользователь пишет в чат, а бот отвечает в личку.

Команда /start без параметров предназначена для вывода информации о боте, а с параметрами — для идентификации. Полезно её использовать для действий, требующих авторизации.

После этого можно добавить какую-нибудь свою команду, например, /base64:

Для пользователей мобильного Telegram, будет полезно сказать @BotFather, какие команды принимает наш бот:

I: /setcommands

BotFather. Choose a bot to change the list of commands.

I: @******_bot

BotFather: OK. Send me a list of commands for your bot. Please use this format:

command1 — Description

command2 — Another description

whoisyourdaddy — Information about author

base64 — Base64 decode

BotFather: Success! Command list updated. /help

C таким описанием, если пользователь наберет /, Telegram услужливо покажет список всех доступных команд.

4. Свобода

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

UPD: Как верно подсказали, такое пройдет только при личном общении. В чатах боту доставляются только сообщения, начинающиеся с команды (/<command>) (https://core. telegram. org/bots#privacy-mode)

  • All messages that start with a slash ‘/’ (see Commands above)
  • Messages that mention the bot by username
  • Replies to the bot’s own messages
  • Service messages (people added or removed from the group, etc.)

Чтобы бот получал все сообщения в группах пишем @BotFather команду /setprivacy и выключаем приватность.

Для начала в Handler добавляем обработчик:

А потом в список команд добавляем псевдо-речь:

Здесь эмпирическая константа 75 относительно неплохо отражает вероятность того, что пользователь всё-таки хотел сказать. А format_map — удобна для одинакового описания строк как требующих подстановки, так и без нее. Теперь бот будет отвечать на приветствия и иногда даже обращаться по имени.

5. Не текст.

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

И будем отлавливать текст <at_sticker>:

Видно, что теперь структура Message уже не содержит текст, поэтому необходимо модифицировать send_reply:

6. Возможности

Благодаря удобству API и быстрому старту боты Telegram могут стать хорошей платформой для автоматизации своих действий, настройки уведомлений, создания викторин и task-based соревнований (CTF, DozoR и прочие).

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

7. Ограничения

К сожалению, на данный момент существует ограничение на использование webHook — он работает только по https и только с валидным сертификатом, что, например для меня пока критично за счет отсутствия поддержки сертифицирующими центрами динамических днс.

К счастью, Telegram также умеет работать и по ручному обновлению, поэтому не меняя кода можно создать еще одну службу Puller, которая будет выкачивать их и слать на локальный адрес:

P. S. По пункту 7 нашел удобное решение — размещение бота не у себя, а на heroku, благо все имена вида *.herokuapp. com защищены их собственным сертификатом.

UPD: Telegram улучшили Бот Апи, из-за чего, теперь не обязательно иметь отдельную функцию для отправки сообщений при установленном вебхуке, а в ответ на POST запрос можно отвечать тем же сформированным JSON с ответным сообщением, где одно из полей устанавливается как ч ‘method’: ‘sendMessage’ (или любой другой метод, используемый ботом).