Пішам telegram бота на мове R (частка 2): Дадаем боту падтрымку каманд і фільтры паведамленняў

В папярэдняй публікацыі мы разабраліся як стварыць бота, ініцыялізавалі асобнік класа Bot і азнаёміліся з метадамі адпраўкі паведамленняў з яго дапамогай.

У гэтым артыкуле я працягваю дадзеную тэму, таму прыступаць да чытання дадзенага артыкула я рэкамендую толькі пасля прачытання першай частцы.

У гэты раз мы разбярэмся як ажывіць нашага робата і дадамо яму падтрымку каманд, а таксама пазнаёмімся з класам. Updater.

У ходзе артыкула мы напішам некалькіх простых ботаў, апошні будзе па зададзенай даце і коду краіны вызначаць ці з'яўляецца дзень у дадзенай краіне выходным ці працоўным паводле вытворчага календара. Але, як і раней мэта артыкула азнаёміць вас з інтэрфейсам пакета telegram.bot для вырашэння вашых уласных задач.

Пішам telegram бота на мове R (частка 2): Дадаем боту падтрымку каманд і фільтры паведамленняў

Усе артыкулы з серыі "Пішам telegram бота на мове R"

  1. Ствараем бота, і адпраўляем з яго дапамогай паведамлення ў telegram
  2. Дадаем боту падтрымку каманд і фільтры паведамленняў

Змест

Калі вы цікавіцеся аналізам дадзеных магчыма вам будуць цікавыя мае тэлеграма и YouTube каналы. Большая частка кантэнту якіх прысвечаны мове R.

  1. Клас Updater
  2. Handlers - апрацоўшчыкі
  3. Дадаем першую каманду боту, апрацоўшчык каманд
  4. Апрацоўшчык тэкставых паведамленняў і фільтры
  5. Даданне каманд з параметрамі
  6. Запускаем бота ў фонавым рэжыме
  7. Заключэнне

Клас Updater

Updater – гэта клас, які спрашчае вам распрацоўку тэлеграм бота, і выкарыстоўвае пад капотам клас Dispetcher. Прызначэнне класа Updater заключаецца ў тым, што б атрымаць абнаўлення ад бота (у папярэднім артыкуле мы выкарыстоўвалі для гэтай мэты метад getUpdates()), і перадаць іх далей у Dispetcher.

У сваю чаргу Dispetcher утрымоўвае ў сабе створаныя вамі апрацоўшчыкі, г.зн. аб'екты класа Handler.

Handlers - апрацоўшчыкі

З дапамогай апрацоўшчыкаў вы дадаеце ў Dispetcher рэакцыі бота на розныя падзеі. На момант напісання артыкула ў telegram.bot дададзены наступныя тыпы апрацоўшчыкаў:

  • MessageHandler – Апрацоўшчык паведамленняў
  • CommandHandler - Апрацоўшчык каманд
  • CallbackQueryHandler - Апрацоўшчык дадзеных якія адпраўляюцца з Inline клавіятур
  • ErrorHandler - Апрацоўшчык памылак пры запыце абнаўленняў ад бота

Дадаем першую каманду боту, апрацоўшчык каманд

Калі вы ніколі раней не выкарыстоўвалі ботаў, і не ў курсе, што такое каманда, то каманды боту неабходна адпраўляць з дапамогай прамога слеша / у якасці прэфікса.

Пачнём мы з простых каманд, г.зн. навучым нашага бота вітацца па камандзе /hi.

Код 1: Вучым бота вітацца

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# Пишем метод для приветсвия
say_hello <- function(bot, update) {

  # Имя пользователя с которым надо поздароваться
  user_name <- update$message$from$first_name

  # Отправка приветственного сообщения
  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Моё почтение, ", user_name, "!"), 
                  parse_mode = "Markdown")

}

# создаём обработчик 
hi_hendler <- CommandHandler('hi', say_hello)

# добаляем обработчик в диспетчер
updater <- updater + hi_hendler

# запускаем бота
updater$start_polling()

Запусціце прыведзены вышэй прыклад кода, папярэдне замяніўшы 'ТОКЕН ВАШАГА БОТА' на рэальны токен, які вы атрымалі пры стварэнні бота праз БотБацька (аб стварэнні бота я распавядаў у першым артыкуле).

метад start_polling() класа Updater, Які выкарыстоўваецца ў канцы кода, запускае бясконцы цыкл запыту і апрацоўкі абнаўленняў ад бота.

Цяпер адкрыем тэлеграм, і напішам нашаму боту першую каманду /hi.

Пішам telegram бота на мове R (частка 2): Дадаем боту падтрымку каманд і фільтры паведамленняў

Цяпер наш бот разумее каманду /hi, і ўмее з намі вітацца.

Схематычна працэс пабудовы такога найпростага робата можна адлюстраваць наступным чынам.

Пішам telegram бота на мове R (частка 2): Дадаем боту падтрымку каманд і фільтры паведамленняў

  1. Ствараем экзэмпляр класа Updater;
  2. Ствараем метады, г.зн. функцыі якія будзе выконваць наш бот. У прыкладзе кода гэта функцыя say_hello(). Функцыі, якія вамі будуць выкарыстоўвацца як метады бота павінны мець два абавязковыя аргументы. бот и абнаўленне, і адзін неабавязковы - аргі. Аргумент бот, гэта і ёсць ваш бот, з яго дапамогай вы можаце адказваць на паведамленні, адпраўляць паведамленні, ці выкарыстоўваць любыя іншыя даступныя боту метады. Аргумент абнаўленне гэта тое, што робат атрымаў ад карыстача, у сутнасці, тое што ў першым артыкуле мы атрымлівалі метадам getUpdates(). Аргумент аргі дазваляе вам апрацоўваць дадатковыя дадзеныя адпраўленыя карыстальнікам разам з камандай, да гэтай тэмы мы яшчэ вернемся крыху пазней;
  3. Ствараем апрацоўшчыкі, г.зн. злучаем нейкія дзеянні карыстача са створанымі на мінулым кроку метадамі. У сутнасці апрацоўшчык гэта трыгер, падзея якое выклікае нейкую функцыю робата. У нашым прыкладзе такім трыгерам з'яўляецца адпраўка каманды /hi, і рэалізуецца камандай hi_hendler <- CommandHandler('hi', say_hello). Першы аргумент функцыі CommandHandler() дазваляе вам задаць каманду, у нашым выпадку hi, на якую будзе рэагаваць бот. Другі аргумент дазваляе паказаць метад бота, мы будзем выклікаць метад say_hello, які будзе выконвацца калі карыстач выклікаў паказаную ў першым аргуменце каманду;
  4. Далей дадаем створаны апрацоўшчык у дыспетчар нашага экзэмпляра класа Updater. Дадаваць апрацоўшчыкі можна некалькімі спосабамі, у прыкладзе вышэй я выкарыстоўваў найпросты, з дапамогай знака +, Г.зн. updater <- updater + hi_hendler. Тое ж самае можна зрабіць з дапамогай метаду add_handler(), які адносіцца да класа Dispatcher, знайсці гэты метад можна так: updater$dispatcher$add_handler();
  5. Запускаем бота з дапамогай каманды start_polling().

Апрацоўшчык тэкставых паведамленняў і фільтры

Як адпраўляць робату каманды мы разабраліся, але часам нам патрабуецца, каб робат рэагаваў не толькі на каманды, але і на нейкія звычайныя, тэкставыя паведамленні. Для гэтага неабходна выкарыстоўваць апрацоўшчыкі паведамленняў Апрацоўшчык паведамленняў.

звычайны Апрацоўшчык паведамленняў будзе рэагаваць на абсалютна ўсе ўваходныя паведамленні. Таму часта апрацоўшчыкі паведамленняў выкарыстоўваюцца разам з фільтрамі. Давайце навучым бота вітацца не толькі па камандзе /hi, Але і заўсёды, калі ў паведамленні адпраўленым робату сустракаецца адно з наступных слоў: прывітанне, добры дзень, салют, хай, банжур.

Пакуль мы не будзем пісаць нейкія новыя метады, т.я. у нас ужо ёсць метад з дапамогай якога бот з намі вітаецца. Ад нас патрабуецца толькі стварыць патрэбны фільтр і апрацоўшчык паведамленняў.

Код 2: Дадаем апрацоўшчык тэкставых паведамленняў і фільтр

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# Пишем метод для приветсвия
## команда приветвия
say_hello <- function(bot, update) {

  # Имя пользователя с которым надо поздароваться
  user_name <- update$message$from$first_name

  # Отправляем приветсвенное сообщение
  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Моё почтение, ", user_name, "!"),
                  parse_mode = "Markdown",
                  reply_to_message_id = update$message$message_id)

}

# создаём фильтры
MessageFilters$hi <- BaseFilter(function(message) {

  # проверяем, встречается ли в тексте сообщения слова: привет, здравствуй, салют, хай, бонжур
  grepl(x           = message$text, 
        pattern     = 'привет|здравствуй|салют|хай|бонжур',
        ignore.case = TRUE)
  }
)

# создаём обработчик 
hi_hendler <- CommandHandler('hi', say_hello) # обработчик команды hi
hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi)

# добаляем обработчики в диспетчер
updater <- updater + 
             hi_hendler +
             hi_txt_hnd

# запускаем бота
updater$start_polling()

Запусціце прыведзены вышэй прыклад кода, папярэдне замяніўшы 'ТОКЕН ВАШАГА БОТА' на рэальны токен, які вы атрымалі пры стварэнні бота праз БотБацька (аб стварэнні бота я распавядаў у першым артыкуле).

Цяпер паспрабуем адправіць боту некалькі паведамленняў, у якіх будуць сустракацца пералічаныя раней словы прывітання:
Пішам telegram бота на мове R (частка 2): Дадаем боту падтрымку каманд і фільтры паведамленняў

Такім чынам, у першую чаргу мы навучылі робата не проста вітацца, а адказваць на прывітанне. Зрабілі мы гэта з дапамогай аргумента reply_to_message_id, які даступны ў метадзе sendMessage(), у які неабходна перадаць id паведамлення на якое патрабуецца адказаць. Атрымаць id паведамленні можна вось так: update$message$message_id.

Але галоўнае, што мы зрабілі – дадалі робату фільтр з дапамогай функцыі BaseFilter():

# создаём фильтры
MessageFilters$hi <- BaseFilter( 

  # анонимная фильтрующая функция
  function(message) {

    # проверяем, встречается ли в тексте сообщения слова приветствия
    grepl(x           = message$text, 
          pattern     = 'привет|здравствуй|салют|хай|бонжур',
          ignore.case = TRUE)
  }

)

Як вы маглі заўважыць, фільтры неабходна дадаваць у аб'ект MessageFilters, у якім першапачаткова ўжо ёсць невялікі набор гатовых фільтраў. У нашым прыкладзе ў аб'ект MessageFilters мы дадалі элемент hi, гэта новы фільтр.

У функцыю BaseFilter() вам неабходна перадаць якая фільтруе функцыю. Па сутнасці, фільтр - гэта проста функцыя, якая атрымлівае асобнік паведамлення і вяртае TRUE, або ХЛУСНЯ. У нашым прыкладзе, мы напісалі найпростую функцыю, якая з дапамогай базавай функцыі grepl() правярае тэкст паведамлення, і калі ён адпавядае рэгулярнаму выразу привет|здравствуй|салют|хай|бонжур вяртае TRUE,.

Далей мы ствараем апрацоўшчык паведамленняў hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi). Першы аргумент функцыі MessageHandler() - метад, які будзе выклікаць апрацоўшчык, а другі аргумент - гэта фільтр па якім ён будзе выклікацца. У нашым выпадку гэта створаны намі фільтр MessageFilters$hi.

Ну і ў выніку, мы дадаем у дыспетчар створаны толькі, што апрацоўшчык hi_txt_hnd.

updater <- updater + 
             hi_hendler +
             hi_txt_hnd

Як я ўжо пісаў вышэй, у пакеце telegram.bot і аб'екце MessageFilters ужо ёсць набор убудаваных фільтраў, якія вы можаце выкарыстоўваць:

  • all — Усе паведамленні
  • text — Тэкставыя паведамленні
  • command - Каманды, г.зн. паведамленні якія пачынаюцца на /
  • reply — Паведамлення, якія з'яўляюцца адказам на іншае паведамленне
  • audio — Паведамленні ў якіх змяшчаецца аўдыё файл
  • document — Паведамленні з дасланым дакументам
  • photo — Паведамленні з адпраўленымі выявамі
  • sticker — Допісы з дасланым стыкерам
  • video — Паведамленні з відэа
  • voice — Галасавыя паведамленні
  • contact — Паведамленні ў якіх змяшчаецца кантант тэлеграм карыстальніка
  • location — Паведамленні з геолокацией
  • venue — Перасланыя паведамленні
  • game - Гульні

Калі вы хочаце сумясціць некаторыя фільтры ў адным апрацоўшчыку проста выкарыстоўвайце знак | - у якасці лагічнага АБО, і знак & у якасці лагічнага И. Напрыклад, калі вы хочаце што б бот выклікаў адзін і той жа метад калі ён атрымлівае відэа, малюнак або дакумент выкарыстоўвайце наступны прыклад стварэння апрацоўшчыка паведамленняў:

handler <- MessageHandler(callback, 
  MessageFilters$video | MessageFilters$photo | MessageFilters$document
)

Даданне каманд з параметрамі

Мы ўжо ведаем, што такое каманды, як іх ствараць і як прымусіць робата выканаць неабходную каманду. Але ў некаторых выпадках апроч назвы каманды, нам неабходна перадаць некаторыя дадзеныя для яе выканання.

Ніжэй прыклад робата, які па зададзенай даце і краіне вяртае вам тып дня з вытворчага календара.

Прыведзены ніжэй бот выкарыстоўвае API вытворчага календара isdayoff.ru.

Код 3: Бот, які паведамляе па даце і краіне

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('1165649194:AAFkDqIzQ6Wq5GV0YU7PmEZcv1gmWIFIB_8')

# Пишем метод для приветсвия
## команда приветвия
check_date <- function(bot, update, args) {

  # входящие данные
  day     <- args[1]  # дата
  country <- args[2]  # страна

  # проверка введённых параметров
  if ( !grepl('\d{4}-\d{2}-\d{2}', day) ) {

    # Send Custom Keyboard
    bot$sendMessage(update$message$chat_id, 
                    text = paste0(day, " - некорреткная дата, введите дату в формате ГГГГ-ММ-ДД"),
                    parse_mode = "Markdown")

  } else {
    day <- as.Date(day)
    # переводим в формат POSIXtl
    y <- format(day, "%Y")
    m <- format(day, "%m")
    d <- format(day, "%d")

  }

  # страна для проверки
  ## проверяем задана ли страна
  ## если не задана устанавливаем ru
  if ( ! country %in% c('ru', 'ua', 'by', 'kz', 'us') ) {

    # Send Custom Keyboard
    bot$sendMessage(update$message$chat_id, 
                    text = paste0(country, " - некорретктный код страны, возможнные значения: ru, by, kz, ua, us. Запрошены данные по России."),
                    parse_mode = "Markdown")

    country <- 'ru'

  }

  # запрос данных из API
  # компоновка HTTP запроса
  url <- paste0("https://isdayoff.ru/api/getdata?",
                "year=",  y, "&",
                "month=", m, "&",
                "day=",   d, "&",
                "cc=",    country, "&",
                "pre=1&",
                "covid=1")

  # получаем ответ
  res <- readLines(url)

  # интрепретация ответа
  out <- switch(res, 
                "0"   = "Рабочий день",
                "1"   = "Нерабочий день",
                "2"   = "Сокращённый рабочий день",
                "4"   = "covid-19",
                "100" = "Ошибка в дате",
                "101" = "Данные не найдены",
                "199" = "Ошибка сервиса")

  # отправляем сообщение
  bot$sendMessage(update$message$chat_id, 
                  text = paste0(day, " - ", out),
                  parse_mode = "Markdown")

}

# создаём обработчик 
date_hendler <- CommandHandler('check_date', check_date, pass_args = TRUE)

# добаляем обработчик в диспетчер
updater <- updater + date_hendler

# запускаем бота
updater$start_polling()

Запусціце прыведзены вышэй прыклад кода, папярэдне замяніўшы 'ТОКЕН ВАШАГА БОТА' на рэальны токен, які вы атрымалі пры стварэнні бота праз БотБацька (аб стварэнні бота я распавядаў у першым артыкуле).

Мы стварылі робата, які ў арсенале мае ўсяго адзін метад check_date, дадзены метад выклікаецца аднайменнай камандай.

Але, акрамя імя каманды, дадзены метад чакае ад вас увядзення двух параметраў, код краіны і дату. Далей робат правяраецца, ці з'яўляецца зададзены дзень у паказанай краіне выходным, скарочаным ці працоўным паводле афіцыйнага вытворчага календара.

Каб створаны метад прымаў дадатковыя параметры разам з камандай, выкарыстоўвайце аргумент pass_args = TRUE у функцыі CommandHandler(), і пры стварэнні метаду, акрамя абавязковых аргументаў бот, абнаўленне стварыце апцыянальны - аргі. Створаны такім чынам метад будзе прымаць параметры, якія вы перадаеце робату пасля назвы каманды. Параметры неабходна паміж сабой падзяляць прабелам, у метад яны паступяць у выглядзе тэкставага вектара.

Давайце запусцім, і пратэстуем нашага робата.

Пішам telegram бота на мове R (частка 2): Дадаем боту падтрымку каманд і фільтры паведамленняў

Запускаем бота ў фонавым рэжыме

Апошні крок які нам засталося выканаць – запусціць робата ў фонавым рэжыме.

Для гэтага прытрымлівайцеся па апісаным ніжэй алгарытме:

  1. Захавайце код робата ў файл з пашырэннем R. Пры працы ў RStudio гэта робіцца праз меню Размовы, камандай Захаваць як….
  2. Дадайце шлях да тэчкі bin, якая ў сваю чаргу знаходзіцца ў тэчцы у якую вы ўсталявалі мову R у зменную Path, інструкцыя тут.
  3. Стварыце звычайны тэкставы файл, у якім прапішыце 1 радок: R CMD BATCH C:UsersAlseyDocumentsmy_bot.R. Замест C:UsersAlseyDocumentsmy_bot.R прапішыце шлях да свайго скрыпту бота. Пры гэтым важна, што б у дарозе не сустракалася кірыліца і прабелы, т.я. гэта можа выклікаць праблемы пры запуску робата. Захавайце яго, і заменіце яго пашырэнне з TXT на кажан.
  4. Адкрыйце планавальнік заданняў Windows, ёсць мноства спосабаў гэта зрабіць, напрыклад адкрыйце любую тэчку і ў адрас увядзіце %windir%system32taskschd.msc /s. Іншыя спосабы запуску можна знайсці тут.
  5. У верхнім правым меню планавальніка націсніце "Стварыць задачу…".
  6. На ўкладцы "Агульныя" задайце адвольнае імя вашай задачы, і перамыкач перабачыце ў стан "Выконваць для ўсіх карыстачоў".
  7. Перайдзіце на ўкладку "Дзеянні", націсніце "Стварыць". У полі "Праграма або сцэнар" націсніце "Агляд", знайдзіце створаны на другім кроку кажан файл, і націсніце ОК.
  8. Ціснем ОК, пры неабходнасці ўводны пароль ад вашага ўліковага запісу аперацыйнай сістэмы.
  9. Знаходзім у планавальніку створаную задачу, вылучаем і ў ніжнім правым куце ціснем кнопку "Выканаць".

Наш бот запушчаны ў фонавым рэжыме, і будзе працаваць да таго часу, пакуль вы не спыніце задачу, ці не выключыце ваш ПК або сервер на якім яго запусцілі.

Заключэнне

У гэтым артыкуле мы разабраліся як напісаць паўнавартаснага робата, які не толькі ўмее адпраўляць паведамленні, але і рэагаваць на ўваходныя паведамленні і каманды. Атрыманых ведаў ужо дастаткова для вырашэння большасці вашых задач.

У наступным артыкуле гаворка пойдзе пра тое, як дадаць робату клавіятуру, для зручнейшай працы.

Падпісваецеся на мой тэлеграма и YouTube каналы.

Крыніца: habr.com

Дадаць каментар