Пишем бота для Telegram на Perl

В начале лет telegram.org запустил API для создания ботов. И на данный момент их появилось великое множество, полезных и бесполезных.

Для тех, кто хочет серьезно освоить API советую добавить ссылку https://core.telegram.org/bots в избранное и медленно, на несколько раз, прочитать все. Это старт.

А теперь к делу. В конце августа некто Roberto Frenna, сделал модуль для Perl, реализующий работу с API. Я попробовал его, и выяснил, что на perl 5.8.8 (да, иногда бывает и такое старье в продакшене), он работает некорректно. Один запрос в багтрекер и через 2 дня все работает изумительно.

Модуль есть на https://github.com/Robertof/perl-www-telegram-botapi, либо в CPAN.

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

Инструкция проста.

  • Добавляете @BotFather к себе к контакт лист, читате вывод команды /help
  • Затем /newbot
  • BotFather спросит имя бота
  • Напишите что-то типа myFirstPerlBot (окончание bot обязательно!)
  • Затем BotFather его юзернейм, обычно я дублирую имя
  • В итоге выдаст Use this token to access the HTTP API: 105662123:SS:LSKDLKSLKLKSLDKSL23hEjUT1JEARre9dsf

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

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

Основные правила.

  • Общение с ботом идет путем отправки\получения данных в JSON-виде
  • В описании API рекомендуют не отправлять сообщения быстрее чем 1 в 1 секунду. Кратковременные всплески они прощают,
    но если настаивать, то будет временный бан.

А теперь напишем примитивного бота, который не понимает ничего и на все запросы отвечает лишь «Answer». Для получения данных от телеграмма есть два способа — крутить к цикле метод getUpdates или , на своем сервере реализовать WebHook. Второй метод имеет смысл, когда у вас реально нужный бот промышленного масштаба 🙂 Мы пойдем самым простым путем.

Будем использовать методы getUpdates, SendMessage.

#!/usr/bin/perl
use strict;
use WWW::Telegram::BotAPI;
my $api = WWW::Telegram::BotAPI->new(
# указываем токен вашего бота
token => '1234567:your-token-here-your-token-here-your-token-here-your-token-here'
);
# получаем очередь сообщений. По умолчанию, отдается массив не более 100
$api->getUpdates();

# включаем бесконечный цикл и погнали обрабатывать
while (1) {
# если в очереди ничего нет, делаем задержку на 1 секунду и начинаем все сначала.
if ( scalar @{ ( $api->getUpdates->{result} ) } == 0 ) { sleep 1; next; }

# ----
my $updateid;
#если в очереди что-то есть начинаем обрабатывать этот массив
for ( my $i = 0 ; $i < scalar @{ ( $api->getUpdates->{result} ) } ; $i++ ) {
# просто всем шлем ответ в цитате его запроса
$api->SendMessage(
{
chat_id => $api->getUpdates->{result}[$i]{message}{from}{id},
reply_to_message_id => $api->getUpdates->{result}[$i]{message}->{message_id},
text => 'Answer'
}
);

$updateid = ( $api->getUpdates->{result}[$i]->{update_id} );
sleep 1;
}
# делаем апдейт очереди, пометив обработанные сообщения путем задания offset
$api->getUpdates( { offset => $updateid + 1 } );
next;
}

Запускаем. Радуемся.

Screenshot_2015-09-10-10-39-42

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

Домашнее задание.

Добавить поддержку команд

  • /start — приветствие бота, описание его работы
  • /time — вывод картинки будильника, с подписью текущего времени
  • игнорирование любых сообщений если они не команды

За вопросами в комменты или в телеграм @anton_shevtsov или в публичный канал @bot_devel