Skribante telegram-bot en R (parto 3): Kiel aldoni klavarsubtenon al bot

Ĉi tiu estas la tria artikolo en la serio "Skribi telegram-bot en R". En antaŭaj publikaĵoj, ni lernis kiel krei telegraman roboton, sendi mesaĝojn per ĝi, aldonis komandojn kaj mesaĝajn filtrilojn al la roboto. Tial, antaŭ ol vi komencas legi ĉi tiun artikolon, mi tre rekomendas, ke vi legu antaŭa, ĉar Ĉi tie mi ne plu traktos la antaŭe priskribitajn bazojn de robotkonstruado.

En ĉi tiu artikolo, ni plibonigos la uzeblecon de nia bot aldonante klavaron, kiu faros la botinterfacon intuicia kaj facile uzebla.

Skribante telegram-bot en R (parto 3): Kiel aldoni klavarsubtenon al bot

Ĉiuj artikoloj de la serio "Skribante telegram-bot en R"

  1. Ni kreas bot kaj uzas ĝin por sendi mesaĝojn en telegramo
  2. Aldonu komandan subtenon kaj mesaĝajn filtrilojn al la bot
  3. Kiel aldoni klavaran subtenon al bot

Enhavo

Se vi interesiĝas pri datuma analizo, vi eble interesiĝos pri mia telegramo и youtube kanaloj. La plej granda parto de kies enhavo estas dediĉita al la R-lingvo.

  1. Kiajn klavarojn subtenas la telegrambot?
  2. Responda klavaro
  3. Enlinia klavaro
    3.1. Ekzemplo de simpla bot kun subteno por InLine-butonoj
    3.2. Ekzemplo de bot, kiu raportas la nunan veteron por elektita urbo
    3.3. Ekzemplo de bot, kiu montras liston de la plej novaj artikoloj kun ligiloj al la specifita Nabo de habr.com
  4. konkludo

Kiajn klavarojn subtenas la telegrambot?

En la momento de ĉi tiu skribado telegram.bot permesas krei du specojn de klavaroj:

  • Respondo - La ĉefa, regula klavaro, kiu situas sub la mesaĝa teksta eniga panelo. Tia klavaro simple sendas tekstmesaĝon al la bot, kaj kiel la teksto ĝi sendos la tekston, kiu estas skribita sur la butono mem.
  • Enlinia - Klavaro asociita kun specifa robotmesaĝo. Ĉi tiu klavaro sendas la robotajn datumojn asociitajn kun la butono premita; ĉi tiuj datumoj povas diferenci de la teksto skribita sur la butono mem. Kaj tiaj butonoj estas procesitaj CallbackQueryHandler.

Por ke la bot malfermu la klavaron, necesas kiam vi sendas mesaĝon per la metodo sendMessage(), pasigu la antaŭe kreitan klavaron kiel argumenton reply_markup.

Malsupre ni rigardos plurajn ekzemplojn.

Responda klavaro

Kiel mi skribis supre, ĉi tiu estas la ĉefa klavaro pri bot-kontrolo.

Ekzemplo de kreado de Responda klavaro el la oficiala helpo

bot <- Bot(token = "TOKEN")
chat_id <- "CHAT_ID"

# Create Custom Keyboard
text <- "Aren't those custom keyboards cool?"
RKM <- ReplyKeyboardMarkup(
  keyboard = list(
    list(KeyboardButton("Yes, they certainly are!")),
    list(KeyboardButton("I'm not quite sure")),
    list(KeyboardButton("No..."))
  ),
  resize_keyboard = FALSE,
  one_time_keyboard = TRUE
)

# Send Custom Keyboard
bot$sendMessage(chat_id, text, reply_markup = RKM)

Ĉi-supra estas ekzemplo de la oficiala helpo de la pako telegram.bot. Por krei klavaron, uzu la funkcion ReplyKeyboardMarkup(), kiu siavice prenas liston de listoj de butonoj kiuj estas kreitaj per la funkcio KeyboardButton().

Kial en ReplyKeyboardMarkup() Ĉu vi bezonas pasigi ne nur liston, sed liston de listoj? La fakto estas, ke vi pasas la ĉefan liston, kaj en ĝi vi difinas ĉiun vicon da butonoj en apartaj listoj, ĉar Vi povas meti plurajn butonojn en unu vico.

argumenton resize_keyboard permesas vin aŭtomate elekti la optimuman grandecon de klavarbutonoj, kaj la argumenton one_time_keyboard permesas al vi kaŝi la klavaron post ĉiu premo de butono.

Ni skribu simplan roboton, kiu havos 3 butonojn:

  • Babilejo ID - Petu babilejan ID de dialogo kun bot
  • Mia nomo - Petu vian nomon
  • Mia ensaluto - Petu vian uzantnomon en telegramo

Kodo 1: Simpla bot kun Responda klavaro

library(telegram.bot)

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

# создаём методы
## метод для запуска клавиатуры
start <- function(bot, update) {

  # создаём клавиатуру
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Чат ID")),
      list(KeyboardButton("Моё имя")),
      list(KeyboardButton("Мой логин"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
  )

  # отправляем клавиатуру
  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

}

## метод возвразающий id чата
chat_id <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Чат id этого диалога: ", update$message$chat_id),
                  parse_mode = "Markdown")

}

## метод возвращающий имя
my_name <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Вас зовут ", update$message$from$first_name),
                  parse_mode = "Markdown")

}

## метод возвращающий логин
my_username <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Ваш логин ", update$message$from$username),
                  parse_mode = "Markdown")

}

# создаём фильтры
## сообщения с текстом Чат ID
MessageFilters$chat_id <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Чат ID"

}
)

## сообщения с текстом Моё имя
MessageFilters$name <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Моё имя"

}
)

## сообщения с текстом Мой логин
MessageFilters$username <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Мой логин"
)

# создаём обработчики
h_start    <- CommandHandler('start', start)
h_chat_id  <- MessageHandler(chat_id, filters = MessageFilters$chat_id)
h_name     <- MessageHandler(my_name, filters = MessageFilters$name)
h_username <- MessageHandler(my_username, filters = MessageFilters$username)

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

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

Rulu la kodekzemplon supre, post anstataŭigi 'VIA BOT TOKEN' per la reala ĵetono, kiun vi ricevis dum kreado de la bot per BotPatro (Mi parolis pri kreado de bot en unua artikolo).

Post lanĉo, donu komandon al la bot /start, ĉar Ĝuste ĉi tion ni difinis por lanĉi la klavaron.

Skribante telegram-bot en R (parto 3): Kiel aldoni klavarsubtenon al bot

Se nuntempe estas malfacile por vi analizi la donitan kodan ekzemplon, kun la kreado de metodoj, filtriloj kaj pritraktiloj, tiam vi devus reveni al la antaŭa artikolo, en kiu mi detale priskribis ĉion ĉi.

Ni kreis 4 metodojn:

  • start — Lanĉu la klavaron
  • chat_id — Petu babilejon ID
  • mia_nomo — Petu vian nomon
  • mia_uzantnomo — Petu vian ensaluton

Obĵeti Mesaĝfiltriloj aldonis 3 mesaĝajn filtrilojn laŭ ilia teksto:

  • chat_id — Mesaĝoj kun teksto "Чат ID"
  • nomo — Mesaĝoj kun teksto "Моё имя"
  • uzantnomo — Mesaĝoj kun teksto "Мой логин"

Kaj ni kreis 4 manipulilojn kiuj, surbaze de donitaj komandoj kaj filtriloj, ekzekutos la specifitajn metodojn.

# создаём обработчики
h_start    <- CommandHandler('start', start)
h_chat_id  <- MessageHandler(chat_id, filters = MessageFilters$chat_id)
h_name     <- MessageHandler(my_name, filters = MessageFilters$name)
h_username <- MessageHandler(my_username, filters = MessageFilters$username)

La klavaro mem estas kreita ene de la metodo start() teamo ReplyKeyboardMarkup().

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Чат ID")),
      list(KeyboardButton("Моё имя")),
      list(KeyboardButton("Мой логин"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

En nia kazo, ni metis ĉiujn butonojn unu sub la alian, sed ni povas aranĝi ilin en unu vico farante ŝanĝojn al la listo de butonlistoj. Ĉar unu vico ene de la klavaro estas kreita per nestita listo de butonoj, tiam por montri niajn butonojn en unu vico ni devas reverki parton de la kodo por konstrui la klavaron jene:

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
          KeyboardButton("Чат ID"),
          KeyboardButton("Моё имя"),
          KeyboardButton("Мой логин")
     )
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

Skribante telegram-bot en R (parto 3): Kiel aldoni klavarsubtenon al bot

La klavaro estas sendita al la babilejo per la metodo sendMessage(), en la argumento reply_markup.

  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

Enlinia klavaro

Kiel mi skribis supre, la Inline-klavaro estas ligita al specifa mesaĝo. Ĝi estas iom pli malfacile labori kun ol la ĉefa klavaro.

Komence, vi devas aldoni metodon al la bot por voki la Inline-klavaron.

Por respondi al Inline-butono klako, vi ankaŭ povas uzi la bot-metodon answerCallbackQuery(), kiu povas montri sciigon en la telegrama interfaco al la uzanto, kiu premas la Inline-butonon.

La datumoj senditaj de la Inline-butono ne estas teksto, do por prilabori ĝin, vi devas krei specialan pritraktilon per la komando CallbackQueryHandler().

La kodo por konstrui Inline-klavaron kiu estas donita en la oficiala helpo de la pakaĵo telegram.bot.

Kodo por konstrui Inline-klavaron el la oficiala helpo

# Initialize bot
bot <- Bot(token = "TOKEN")
chat_id <- "CHAT_ID"

# Create Inline Keyboard
text <- "Could you type their phone number, please?"
IKM <- InlineKeyboardMarkup(
  inline_keyboard = list(
    list(
      InlineKeyboardButton(1),
      InlineKeyboardButton(2),
      InlineKeyboardButton(3)
    ),
    list(
      InlineKeyboardButton(4),
      InlineKeyboardButton(5),
      InlineKeyboardButton(6)
    ),
    list(
      InlineKeyboardButton(7),
      InlineKeyboardButton(8),
      InlineKeyboardButton(9)
    ),
    list(
      InlineKeyboardButton("*"),
      InlineKeyboardButton(0),
      InlineKeyboardButton("#")
    )
  )
)

# Send Inline Keyboard
bot$sendMessage(chat_id, text, reply_markup = IKM)

Vi devas konstrui Enlinian klavaron uzante la komandon InlineKeyboardMarkup(), laŭ la sama principo kiel la Respondo-klavaro. EN InlineKeyboardMarkup() necesas pasigi liston de listoj de Inline-butonoj, ĉiu individua butono estas kreita de la funkcio InlineKeyboardButton().

Enlinia butono povas aŭ transdoni iujn datumojn al la roboto uzante argumenton callback_data, aŭ malfermu ajnan HTML-paĝon specifitan per la argumento url.

La rezulto estos listo, en kiu ĉiu elemento ankaŭ estas listo de Inline-butonoj, kiuj devas esti kombinitaj en unu vicon.

Poste ni rigardos plurajn ekzemplojn de robotoj kun Inline-butonoj.

Ekzemplo de simpla bot kun subteno por InLine-butonoj

Unue, ni skribos roboton por rapidaj provoj pri covid-19. Per ordono /test, ĝi sendos al vi klavaron kun du butonoj, depende de la butono premita ĝi sendos al vi mesaĝon kun la rezultoj de via testado.

Kodo 2: La plej simpla roboto kun Inline-klavaro

library(telegram.bot)

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

# метод для отправки InLine клавиатуры
test <- function(bot, update) {

  # создаём InLine клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Да", callback_data = 'yes'),
        InlineKeyboardButton("Нет", callback_data = 'no')
      )
    )
  )

  # Отправляем клавиатуру в чат
  bot$sendMessage(update$message$chat_id, 
                  text = "Вы болете коронавирусом?", 
                  reply_markup = IKM)
}

# метод для обработки нажатия кнопки
answer_cb <- function(bot, update) {

  # полученные данные с кнопки
  data <- update$callback_query$data

  # получаем имя пользователя, нажавшего кнопку
  uname <- update$effective_user()$first_name

  # обработка результата
  if ( data == 'no' ) {

    msg <- paste0(uname, ", поздравляю, ваш тест на covid-19 отрицательный.")

  } else {

    msg <- paste0(uname, ", к сожалени ваш тест на covid-19 положительный.")

  }

  # Отправка сообщения
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # сообщаем боту, что запрос с кнопки принят
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# создаём обработчики
inline_h      <- CommandHandler('test', test)
query_handler <- CallbackQueryHandler(answer_cb)

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

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

Rulu la kodekzemplon supre, post anstataŭigi 'VIA BOT TOKEN' per la reala ĵetono, kiun vi ricevis dum kreado de la bot per BotPatro (Mi parolis pri kreado de bot en unua artikolo).

Rezulto:
Skribante telegram-bot en R (parto 3): Kiel aldoni klavarsubtenon al bot

Ni kreis du metodojn:

  • testo — Por sendi al babili Enline klavaron
  • respondi_cb — Por prilabori datumojn senditajn de la klavaro.

La datumoj kiuj estos senditaj de ĉiu butono estas specifitaj en la argumento callback_data, kiam oni kreas butonon. Vi povas ricevi la datumojn senditajn de la butono uzante la konstruaĵon update$callback_query$data, ene de la metodo respondi_cb.

Por ke la bot reagu al la Inline-klavaro, metodo respondi_cb prilaborita de speciala prizorganto: CallbackQueryHandler(answer_cb). Kiu rulas la specifitan metodon kiam la Enlinia butono estas klakita. Pritraktanto CallbackQueryHandler prenas du argumentojn:

  • callback — La metodo, kiun oni devas funkcii
  • pattern — Filtru laŭ datumoj, kiuj estas ligitaj al la butono per argumento callback_data.

Sekve, uzante la argumenton pattern Ni povas skribi apartan metodon por premi ĉiun butonon:

Kodo 3: Apartaj metodoj por ĉiu Inline-butono

library(telegram.bot)

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

# метод для отправки InLine клавиатуры
test <- function(bot, update) {  

  # создаём InLine клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Да", callback_data = 'yes'),
        InlineKeyboardButton("Нет", callback_data = 'no')
      )
    )
  )

  # Отправляем клавиатуру в чат
  bot$sendMessage(update$message$chat_id, 
                  text = "Вы болете коронавирусом?", 
                  reply_markup = IKM)
}

# метод для обработки нажатия кнопки Да
answer_cb_yes <- function(bot, update) {

  # получаем имя пользователя, нажавшего кнопку
  uname <- update$effective_user()$first_name

  # обработка результата
  msg <- paste0(uname, ", к сожалени ваш текст на covid-19 положительный.")

  # Отправка сообщения
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # сообщаем боту, что запрос с кнопки принят
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# метод для обработки нажатия кнопки Нет
answer_cb_no <- function(bot, update) {

  # получаем имя пользователя, нажавшего кнопку
  uname <- update$effective_user()$first_name

  msg <- paste0(uname, ", поздравляю, ваш текст на covid-19 отрицательный.")

  # Отправка сообщения
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # сообщаем боту, что запрос с кнопки принят
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# создаём обработчики
inline_h          <- CommandHandler('test', test)
query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no  <- CallbackQueryHandler(answer_cb_no, pattern = 'no')

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

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

Rulu la kodekzemplon supre, post anstataŭigi 'VIA BOT TOKEN' per la reala ĵetono, kiun vi ricevis dum kreado de la bot per BotPatro (Mi parolis pri kreado de bot en unua artikolo).

Nun ni skribis 2 apartajn metodojn t.e. unu metodo, por ĉiu butono premo, kaj uzis la argumenton pattern, dum kreado de iliaj prizorgantoj:

query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no  <- CallbackQueryHandler(answer_cb_no, pattern = 'no')

Metoda kodo finiĝas respondi_cb teamo bot$answerCallbackQuery(callback_query_id = update$callback_query$id), kiu rakontas al la roboto ke datumoj de la enlinia klavaro estis ricevitaj.

Ekzemplo de bot, kiu raportas la nunan veteron por elektita urbo

Ni provu skribi bot, kiu petas veterajn datumojn.

La logiko de ĝia laboro estos jena. Komence de la teamo /start vi vokas la ĉefan klavaron, kiu havas nur unu butonon "Vetero". Alklakante ĉi tiun butonon vi ricevos mesaĝon per la Inline-klavaro por elekti la urbon, por kiu vi volas ekscii la nunan veteron. Elektu unu el la urboj kaj ricevu la nunan veteron.

En ĉi tiu koda ekzemplo ni uzos plurajn pliajn pakaĵojn:

  • httr — pako por labori kun HTTP-petoj, surbaze de kiu laboro kun iu ajn API estas konstruita. En nia kazo ni uzos la senpagan API openweathermap.org.
  • stringr — pako por labori kun teksto, en nia kazo ni uzos ĝin por generi mesaĝon pri la vetero en la elektita urbo.

Kodo 4: bot, kiu raportas la nunan veteron por la elektita urbo

library(telegram.bot)
library(httr)
library(stringr)

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

# создаём методы
## метод для запуска основной клавиатуры
start <- function(bot, update) {

  # создаём клавиатуру
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Погода")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # отправляем клавиатуру
  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

}

## Метод вызова Inine клавиатуры
weather <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'Москва', callback_data = 'New York,us'),
        InlineKeyboardButton(text = 'Санкт-Петербург', callback_data = 'Saint Petersburg'),
        InlineKeyboardButton(text = 'Нью-Йорк', callback_data = 'New York')
      ),
      list(
        InlineKeyboardButton(text = 'Екатеринбург', callback_data = 'Yekaterinburg,ru'),
        InlineKeyboardButton(text = 'Берлин', callback_data = 'Berlin,de'),
        InlineKeyboardButton(text = 'Париж', callback_data = 'Paris,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Рим', callback_data = 'Rome,it'),
        InlineKeyboardButton(text = 'Одесса', callback_data = 'Odessa,ua'),
        InlineKeyboardButton(text = 'Киев', callback_data = 'Kyiv,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Токио', callback_data = 'Tokyo'),
        InlineKeyboardButton(text = 'Амстердам', callback_data = 'Amsterdam,nl'),
        InlineKeyboardButton(text = 'Вашингтон', callback_data = 'Washington,us')
      )
    )
  )

  # Send Inline Keyboard
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Выберите город", 
                  reply_markup = IKM)
}

# метод для сообщения погоды
answer_cb <- function(bot, update) {

  # получаем из сообщения город
  city <- update$callback_query$data

  # отправляем запрос
  ans <- GET('https://api.openweathermap.org/data/2.5/weather', 
             query = list(q     = city,
                          lang  = 'ru',
                          units = 'metric',
                          appid = '4776568ccea136ffe4cda9f1969af340')) 

  # парсим ответ
  result <- content(ans)

  # формируем сообщение
  msg <- str_glue("{result$name} погода:n",
                  "Текущая температура: {result$main$temp}n",
                  "Скорость ветра: {result$wind$speed}n",
                  "Описание: {result$weather[[1]]$description}")

  # отправляем информацию о погоде
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text    = msg)

  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# создаём фильтры
## сообщения с текстом Погода
MessageFilters$weather <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Погода"

}
)

# создаём обработчики
h_start         <- CommandHandler('start', start)
h_weather       <- MessageHandler(weather, filters = MessageFilters$weather)
h_query_handler <- CallbackQueryHandler(answer_cb)

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

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

Rulu la kodekzemplon supre, post anstataŭigi 'VIA BOT TOKEN' per la reala ĵetono, kiun vi ricevis dum kreado de la bot per BotPatro (Mi parolis pri kreado de bot en unua artikolo).

Kiel rezulto, nia bot funkcios kiel ĉi tio:
Skribante telegram-bot en R (parto 3): Kiel aldoni klavarsubtenon al bot

Skeme, ĉi tiu roboto povas esti prezentita jene:
Skribante telegram-bot en R (parto 3): Kiel aldoni klavarsubtenon al bot

Ni kreis 3 metodojn disponeblajn ene de nia veterbot:

  • komenco — Lanĉu la ĉefan bot-klavaron
  • vetero — Lanĉu Enlinian klavaron por elekti urbon
  • respondi_cb — La ĉefa metodo, kiu petas la veteron de la API por difinita urbo kaj sendas ĝin al la babilejo.

Metodo komenco ni lanĉas ĝin per la komando /start, kiu estas efektivigita de la prizorganto CommandHandler('start', start).

Kuri metodon vetero ni kreis filtrilon de la sama nomo:

# создаём фильтры
## сообщения с текстом Погода
MessageFilters$weather <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Погода"

}
)

Kaj ni nomas ĉi tiun metodon per la sekva mesaĝtraktilo: MessageHandler(weather, filters = MessageFilters$weather).

Kaj finfine, nia ĉefa metodo respondi_cb reagas al premado de Inline-butonoj, kiu estas efektivigita de speciala prizorganto: CallbackQueryHandler(answer_cb).

Ene de metodo respondi_cb, ni legas la datumojn senditajn de la klavaro kaj skribas ĝin al variablo city: city <- update$callback_query$data. Poste ni petas veterajn datumojn de la API, generas kaj sendas mesaĝon, kaj fine uzas la metodon answerCallbackQuery por informi la roboton, ke ni prilaboris la klakon de la Inline-butono.

Ekzemplo de bot, kiu montras liston de la plej novaj artikoloj kun ligiloj al la specifita Hub de www.habr.com.

Mi prezentas ĉi tiun roboton por montri al vi kiel montri Inline-butonojn, kiuj kondukas al retpaĝoj.

La logiko de ĉi tiu bot estas simila al la antaŭa; komence ni lanĉas la ĉefan klavaron per la komando /start. Poste, la roboto donas al ni liston de 6 naboj por elekti, ni elektas la nabon, pri kiu ni interesiĝas, kaj ricevas la 5 plej lastatempajn publikaĵojn de la elektita Nabo.

Kiel vi komprenas, en ĉi tiu kazo ni bezonas ricevi liston de artikoloj, kaj por tio ni uzos specialan pakaĵon habR, kiu permesas peti artikolojn de Habra kaj kelkajn statistikojn pri ili en R.

Instalu pakon habR nur eblas de github, por kiu vi bezonos plian pakaĵon devtools. Por instali, uzu la suban kodon.

install.packages('devtools')
devtools::install_github('selesnow/habR')

Nun ni rigardu la kodon por konstrui la roboton priskribitan supre:

Kodo 5: bot, kiu montras liston de la plej lastatempaj artikoloj pri la elektita Nabo

library(telegram.bot)
library(habR)

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

# создаём методы
## метод для запуска основной клавиатуры
start <- function(bot, update) {

  # создаём клавиатуру
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Список статей")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # отправляем клавиатуру
  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

}

## Метод вызова Inine клавиатуры
habs <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'R', callback_data = 'R'),
        InlineKeyboardButton(text = 'Data Mining', callback_data = 'data_mining'),
        InlineKeyboardButton(text = 'Data Engineering', callback_data = 'data_engineering')
      ),
      list(
        InlineKeyboardButton(text = 'Big Data', callback_data = 'bigdata'),
        InlineKeyboardButton(text = 'Python', callback_data = 'python'),
        InlineKeyboardButton(text = 'Визуализация данных', callback_data = 'data_visualization')
      )
    )
  )

  # Send Inline Keyboard
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Выберите Хаб", 
                  reply_markup = IKM)
}

# метод для сообщения погоды
answer_cb <- function(bot, update) {

  # получаем из сообщения город
  hub <- update$callback_query$data

  # сообщение о том, что данные по кнопке получены
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id, 
                          text = 'Подождите несколько минут, запрос обрабатывается') 

  # сообщение о том, что надо подождать пока бот получит данные
  mid <- bot$sendMessage(chat_id = update$from_chat_id(),
                         text    = "Подождите несколько минут пока, я соберу данные по выбранному Хабу")

  # парсим Хабр
  posts <- head(habr_hub_posts(hub, 1), 5)

  # удаляем сообщение о том, что надо подождать
  bot$deleteMessage(update$from_chat_id(), mid$message_id) 

  # формируем список кнопок
  keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))

  # формируем клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard =  keys 
    )

  # отправляем информацию о погоде
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text    = paste0("5 наиболее свежих статей из Хаба ", hub),
                  reply_markup = IKM)

}

# создаём фильтры
## сообщения с текстом Погода
MessageFilters$hubs <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Список статей"

}
)

# создаём обработчики
h_start         <- CommandHandler('start', start)
h_hubs          <- MessageHandler(habs, filters = MessageFilters$hubs)
h_query_handler <- CallbackQueryHandler(answer_cb)

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

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

Rulu la kodekzemplon supre, post anstataŭigi 'VIA BOT TOKEN' per la reala ĵetono, kiun vi ricevis dum kreado de la bot per BotPatro (Mi parolis pri kreado de bot en unua artikolo).

Kiel rezulto, ni ricevos ĉi tiun rezulton:
Skribante telegram-bot en R (parto 3): Kiel aldoni klavarsubtenon al bot

Ni hardkodis la liston de Naboj disponeblaj por elekto en la metodo habs:

## Метод вызова Inine клавиатуры
habs <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'R', callback_data = 'r'),
        InlineKeyboardButton(text = 'Data Mining', callback_data = 'data_mining'),
        InlineKeyboardButton(text = 'Data Engineering', callback_data = 'data_engineering')
      ),
      list(
        InlineKeyboardButton(text = 'Big Data', callback_data = 'bigdata'),
        InlineKeyboardButton(text = 'Python', callback_data = 'python'),
        InlineKeyboardButton(text = 'Визуализация данных', callback_data = 'data_visualization')
      )
    )
  )

  # Send Inline Keyboard
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Выберите Хаб", 
                  reply_markup = IKM)
}

Ni ricevas liston de artikoloj de la specifita Nabo kun la komando habr_hub_posts(), el la pakaĵo habR. Samtempe ni atentigas, ke ni ne bezonas liston de artikoloj por la tuta tempo, sed nur la unuan paĝon, sur kiu troviĝas 20 artikoloj. El la rezulta tabelo uzante la komandon head() Ni lasas nur la suprajn 5, kiuj estas la plej freŝaj artikoloj.

  # парсим Хабр
  posts <- head(habr_hub_posts(hub, 1), 5)

La logiko estas tre simila al la antaŭa bot, sed ĉi-kaze ni generas Inline-klavaron kun listo de artikoloj dinamike uzante la funkcion lapply().

  # формируем список кнопок
  keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))

  # формируем клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard =  keys 
    )

Ni enmetas la titolon de la artikolo en la butontekston posts$title[x], kaj en la argumento url ligo al artikolo: url = posts$link[x].

Poste, ni kreas filtrilon, prizorgantojn kaj lanĉas nian bot.

konkludo

Nun la robotoj, kiujn vi skribas, estos multe pli oportunaj por uzi, pro la fakto, ke ili estos kontrolitaj de la klavaro, prefere ol per enigo de komandoj. Minimume, interagante kun bot per inteligenta telefono, la klavaro signife simpligos la procezon de uzado de ĝi.

En la sekva artikolo ni eltrovos kiel konstrui logikan dialogon kun bot kaj labori kun datumbazoj.

fonto: www.habr.com

Aldoni komenton