Programujeme telegram bota v jazyce R (část 3): Jak přidat botovi podporu klávesnice

Toto je třetí článek ze série "Píšeme telegramového bota v jazyce R". V předchozích publikacích jsme se naučili vytvářet telegramového bota, posílat přes něj zprávy, přidali jsme botovi příkazy a filtry zpráv. Proto než se pustíte do čtení tohoto článku, důrazně doporučuji se seznámit s předchozími, protože se už nebudu zastavovat u dříve popsaných základech vytváření botů.

V tomto článku zvýšíme použitelnost našeho bota přidáním klávesnice, která učiní rozhraní bota intuitivnějším a snadnějším na používání.

Programujeme telegram bota v jazyce R (část 3): Jak přidat botovi podporu klávesnice

Všechny články ze série "Píšeme telegramového bota v jazyce R"

  1. Vytváříme bota a pomocí něj posíláme zprávy na telegram
  2. Přidáváme botovi podporu příkazů a filtry zpráv
  3. Jak přidat botovi podporu klávesnice

Obsah

Pokud se zajímáte o analýzu dat, možná vás zaujmou mé telegram a youtube kanály. Většina obsahu je věnována jazyku R.

  1. Jaké typy klávesnic podporuje telegramový bot
  2. Reply klávesnice
  3. Inline klávesnice
    3.1. Příklad nejjednoduššího bota s podporou inline tlačítek
    3.2. Příklad bota, který oznamuje aktuální počasí ve vybraném městě
    3.3. Příklad bota, který zobrazuje seznam nejnovějších článků se odkazy na zadaném Habu z habr.com
  4. Závěr

Jaké typy klávesnic podporuje telegramový bot

V době psaní tohoto článku telegram.bot umožňuje vytvářet klávesnice dvou typů:

  • Reply — Hlavní, obyčejná klávesnice, která se nachází pod panelem pro zadávání textu zprávy. Tato klávesnice jednoduše posílá botovi textovou zprávu, přičemž jako text odešle text, který je napsán na samotném tlačítku.
  • Inline — Klávesnice připojená k konkrétní zprávě bota. Tato klávesnice posílá botovi údaje spojené s kliknutým tlačítkem, tyto údaje se mohou lišit od textu napsaného na samotném tlačítku. A taková tlačítka se zpracovávají pomocí CallbackQueryHandler.

Aby bot otevřel klávesnici, je třeba při odesílání zprávy pomocí metody sendMessage(), předat dříve vytvořenou klávesnici jako argument reply_markup.

Níže projdeme několik příkladů.

Reply klávesnice

Jak jsem již zmínil výše, to je hlavní klávesnice pro ovládání bota.

Příklad vytvoření Reply klávesnice z oficiální dokumentace

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

# Vytvoření vlastní klávesnice
text <- "Není ta vlastní klávesnice skvělá?"
RKM <- ReplyKeyboardMarkup(
  keyboard = list(
    list(KeyboardButton("Ano, určitě!")),
    list(KeyboardButton("Nejsem si tím úplně jistý")),
    list(KeyboardButton("Ne..."))
  ),
  resize_keyboard = FALSE,
  one_time_keyboard = TRUE
)

# Odeslat vlastní klávesnici
bot$sendMessage(chat_id, text, reply_markup = RKM)

Výše uvedený příklad pochází z oficiální dokumentace balíčku telegram.bot. Pro vytvoření klávesnice se používá funkce ReplyKeyboardMarkup(), která na oplátku přijímá seznam seznamů tlačítek, které jsou vytvořeny funkcí KeyboardButton().

Proč v ReplyKeyboardMarkup() je třeba předávat nejen seznam, ale seznam seznamů? Jde o to, že předáváte hlavní seznam, a v něm jako jednotlivé seznamy určujete každou řadu tlačítek, protože do jedné řady můžete umístit více tlačítek.

Argument resize_keyboard umožňuje automaticky přizpůsobit optimální velikost tlačítek klávesnice, a argument one_time_keyboard umožňuje skrýt klávesnici po každém stisknutí tlačítka.

Napišme nejjednoduššího bota, který bude mít 3 tlačítka:

  • Chat ID — Žádat chat ID dialogu s botem
  • Moje jméno — Žádat své jméno
  • Můj login — Žádat své uživatelské jméno v Telegramu

Kód 1: Jednoduchý bot s Reply klávesnicí

library(telegram.bot)

# vytvoříme instanci třídy Updater
updater <- Updater('TOKEN VAŠEHO BOTA')

# vytvoříme metody
## metoda pro spuštění klávesnice
start <- function(bot, update) {

  # vytvoříme klávesnici
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Chat ID")),
      list(KeyboardButton("Moje jméno")),
      list(KeyboardButton("Můj login"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
  )

  # posíláme klávesnici
  bot$sendMessage(update$message$chat_id,
                  text = 'Vyberte příkaz', 
                  reply_markup = RKM)

}

## metoda vracející id chatu
chat_id <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Chat id tohoto dialogu: ", update$message$chat_id),
                  parse_mode = "Markdown")

}

## metoda vracející jméno
my_name <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Jmenujete se ", update$message$from$first_name),
                  parse_mode = "Markdown")

}

## metoda vracející login
my_username <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Váš login ", update$message$from$username),
                  parse_mode = "Markdown")

}

# vytváříme filtry
## zprávy s textem Chat ID
MessageFilters$chat_id <- BaseFilter(function(message) {

  # kontrolujeme text zprávy
  message$text == "Chat ID"

}
)

## zprávy s textem Moje jméno
MessageFilters$name <- BaseFilter(function(message) {

  # kontrolujeme text zprávy
  message$text == "Moje jméno"

}
)

## zprávy s textem Můj login
MessageFilters$username <- BaseFilter(function(message) {

  # kontrolujeme text zprávy
  message$text == "Můj login"
)

# vytváříme zpracovatele
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)

# přidáváme zpracovatele do dispatcheru
updater <- updater + 
            h_start +
            h_chat_id +
            h_name +
            h_username

# spouštíme bota 
updater$start_polling()

Spusťte výše uvedený příklad kódu, než nahradíte 'VAŠE BOT TOKEN' skutečným tokenem, který jste získali při vytváření bota přes BotFather (o vytváření bota jsem mluvil v v prvním článku).

Po spuštění zadejte botovi příkaz /start, protože právě tu jsme určili pro spuštění klávesnice.

Programujeme telegram bota v jazyce R (část 3): Jak přidat botovi podporu klávesnice

Pokud je pro vás v tuto chvíli obtížné pochopit uvedený příklad kódu se vytvářením metod, filtrů a obslužných funkcí, měli byste se vrátit k předchozí článku, v níž jsem to podrobně popsal.

Vytvořili jsme 4 metody:

  • start — Spuštění klávesnice
  • chat_id — Dotaz na identifikátor chatu
  • my_name — Dotaz na vaše jméno
  • my_username — Dotaz na vaše uživatelské jméno

V objektu MessageFilters jsme přidali 3 filtry zpráv podle jejich textu:

  • chat_id — Zprávy s textem "ID chatu"
  • name — Zprávy s textem "Moje jméno"
  • username — Zprávy s textem "Moje uživatelské jméno"

A vytvořili jsme 4 obslužné funkce, které na základě zadaných příkazů a filtrů provedou uvedené metody.

# создаём обработчики
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)

Samotná klávesnice se vytváří uvnitř metody start() příkazem ReplyKeyboardMarkup().

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("ID chatu")),
      list(KeyboardButton("Moje jméno")),
      list(KeyboardButton("Moje uživatelské jméno"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

V našem případě jsme všechny tlačítka položili pod sebe, ale můžeme je uspořádat do jednoho řadu tím, že provedeme změny v seznamu seznamů tlačítek. Protože jeden řádek uvnitř klávesnice se vytváří prostřednictvím vnořeného seznamu tlačítek, musíme část kódu pro konstrukci klávesnice přepsat takto:

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
          KeyboardButton("ID chatu"),
          KeyboardButton("Moje jméno"),
          KeyboardButton("Moje uživatelské jméno")
     )
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

Programujeme telegram bota v jazyce R (část 3): Jak přidat botovi podporu klávesnice

Klávesnice se odesílá do chatu metodou sendMessage(), v argumentu reply_markup.

  bot$sendMessage(update$message$chat_id,
                  text = 'Vyberte příkaz', 
                  reply_markup = RKM)

Inline klávesnice

Jak jsem již zmínil výše, Inline klávesnice je spojena s konkrétní zprávou. Práce s ní je trochu složitější než s hlavní klávesnicí.

Nejdříve musíte přidat botu metodu pro vyvolání Inline klávesnice.

Pro odpověď na stisknutí Inline tlačítka je také možné použít metodu bota answerCallbackQuery(), která může zobrazit oznámení v rozhraní Telegramu uživateli, který stiskl Inline tlačítko.

Data odeslaná s Inline tlačítkem nejsou textem, proto je třeba vytvořit speciální obslužnou funkci pomocí příkazu CallbackQueryHandler().

Kód pro konstrukci Inline klávesnice uvedený v oficiální dokumentaci balíčku telegram.bot.

Kód pro konstrukci Inline klávesnice z oficiální dokumentace

# 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)

Inline klávesnici je třeba sestavit pomocí příkazu InlineKeyboardMarkup(), stejným způsobem jako klávesnice Reply. V InlineKeyboardMarkup() je nutné předat seznam, seznamů Inline tlačítek, každé jednotlivé tlačítko se vytváří funkcí InlineKeyboardButton().

Inline tlačítko může buď předávat bota nějaká data pomocí argumentu callback_data, nebo otevřít nějakou HTML stránku, která je nastavena pomocí argumentu url.

Výsledkem bude seznam, kde každý prvek je rovněž seznamem Inline tlačítek, které je třeba sloučit do jednoho řádku.

Dále se podíváme na několik příkladů botů s Inline tlačítky.

Příklad nejjednoduššího bota s podporou inline tlačítek

Nejprve napíšeme bota pro rychlý test na covid-19. Po příkazu /test, vám pošle klávesnici se dvěma tlačítky, v závislosti na stisknutém tlačítku vám pošle zprávu s výsledky vašeho testování.

Kód 2: Nejjednodušší bot s Inline klávesnicí

library(telegram.bot)

# vytváříme instanci třídy Updater
updater <- Updater('TOKEN VAŠEHO BOTA')

# metoda pro odeslání Inline klávesnice
test <- function(bot, update) {

  # vytváříme Inline klávesnici
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Ano", callback_data = 'yes'),
        InlineKeyboardButton("Ne", callback_data = 'no')
      )
    )
  )

  # Odesíláme klávesnici do chatu
  bot$sendMessage(update$message$chat_id, 
                  text = "Máte covid-19?", 
                  reply_markup = IKM)
}

# metoda pro zpracování stisknutí tlačítka
answer_cb <- function(bot, update) {

  # získaná data z tlačítka
  data <- update$callback_query$data

  # získáváme jméno uživatele, který stiskl tlačítko
  uname <- update$effective_user()$first_name

  # zpracování výsledku
  if (data == 'no') {

    msg <- paste0(uname, ", gratuluji, váš test na covid-19 je negativní.")

  } else {

    msg <- paste0(uname, ", bohužel, váš test na covid-19 je pozitivní.")

  }

  # Odeslání zprávy
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # informujeme bota, že požadavek z tlačítka byl přijat
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# vytváříme obslužné rutiny
inline_h <- CommandHandler('test', test)
query_handler <- CallbackQueryHandler(answer_cb)

# přidáváme obslužné rutiny do správce
updater <- updater + inline_h + query_handler

# spouštíme bota
updater$start_polling()

Spusťte výše uvedený příklad kódu, než nahradíte 'VAŠE BOT TOKEN' skutečným tokenem, který jste získali při vytváření bota přes BotFather (o vytváření bota jsem mluvil v v prvním článku).

Result:
Programujeme telegram bota v jazyce R (část 3): Jak přidat botovi podporu klávesnice

Vytvořili jsme dvě metody:

  • test — Pro odeslání Inline klávesnice do chatu
  • answer_cb — Pro zpracování dat odeslaných z klávesnice.

Data, která budou odeslána z každého tlačítka, jsou nastavena v argumentu callback_data, při vytváření tlačítka. Odeslaná data lze získat pomocí konstrukce update$callback_query$data, uvnitř metody answer_cb.

Aby bot reagoval na Inline klávesnici, metoda answer_cb zpracovává se speciálním zpracovatelem: CallbackQueryHandler(answer_cb). Který spouští určenou metodu při stisknutí inline tlačítka. Zpracovatel CallbackQueryHandler přijímá dva argumenty:

  • callback — Metoda, kterou je třeba spustit
  • pattern — Filtr na základě dat, které jsou přiřazeny k tlačítku pomocí argumentu callback_data.

Díky argumentu pattern můžeme pro stisk každého tlačítka napsat samostatnou metodu:

Kód 3: Rozdělujeme metody pro každé inline tlačítko

library(telegram.bot)

# vytváříme instanci třídy Updater
updater <- Updater('TOKEN VÁŠHO BOTU')

# metoda pro odesílání inline klávesnice
test <- function(bot, update) {  

  # vytváříme inline klávesnici
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Ano", callback_data = 'yes'),
        InlineKeyboardButton("Ne", callback_data = 'no')
      )
    )
  )

  # Odesíláme klávesnici do chatu
  bot$sendMessage(update$message$chat_id, 
                  text = "Máte covid-19?", 
                  reply_markup = IKM)
}

# metoda pro zpracování stisknutí tlačítka Ano
answer_cb_yes <- function(bot, update) {

  # získáme jméno uživatele, který stiskl tlačítko
  uname <- update$effective_user()$first_name

  # zpracování výsledku
  msg <- paste0(uname, ", bohužel váš test na covid-19 je pozitivní.")

  # Odeslání zprávy
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # informujeme bota, že požadavek z tlačítka byl přijat
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# metoda pro zpracování stisknutí tlačítka Ne
answer_cb_no <- function(bot, update) {

  # získáme jméno uživatele, který stiskl tlačítko
  uname <- update$effective_user()$first_name

  msg <- paste0(uname, ", gratuluji, váš test na covid-19 je negativní.")

  # Odeslání zprávy
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # informujeme bota, že požadavek z tlačítka byl přijat
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# vytváříme zpracovatele
inline_h          <- CommandHandler('test', test)
query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no  <- CallbackQueryHandler(answer_cb_no, pattern = 'no')

# přidáváme zpracovatele do správce
updater <- updater + 
            inline_h + 
            query_handler_yes +
            query_handler_no

# spouštíme bota
updater$start_polling()

Spusťte výše uvedený příklad kódu, než nahradíte 'VAŠE BOT TOKEN' skutečným tokenem, který jste získali při vytváření bota přes BotFather (o vytváření bota jsem mluvil v v prvním článku).

Nyní jsme napsali 2 samostatné metody, t.j. po jedné metodě pro stisk každého tlačítka, a použili argument pattern, při vytváření jejich zpracovatelů:

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

Kód metody končí answer_cb příkazem bot$answerCallbackQuery(callback_query_id = update$callback_query$id), která informuje bota, že data z inline klávesnice byla přijata.

Příklad bota, který oznamuje aktuální počasí ve vybraném městě

Pojďme se pokusit napsat bota, který dotazuje údaje o počasí.

Logika jeho fungování bude následující. Nejprve příkazem /start vyvoláte hlavní klávesnici, ve které je pouze jedno tlačítko "Počasí". Po stisknutí tohoto tlačítka obdržíte zprávu s inline klávesnicí pro výběr města, pro které chcete zjistit aktuální počasí. Vyberete jedno z měst a získáte aktuální počasí.

V tomto příkladu kódu budeme používat několik dalších balíčků:

  • httr — balíček pro práci s HTTP dotazy, na jejichž základě funguje jakékoliv API. V našem případě budeme používat bezplatné API openweathermap.org.
  • stringr — balíček pro práci s textem, v našem případě ho budeme používat k formulaci zprávy o počasí ve zvoleném městě.

Kód 4: Bot, který hlásí aktuální počasí pro vybrané město

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

# Vytváříme instanci třídy Updater
updater <- Updater('TOKEN VAŠEHO BOTU')

# Vytváříme metody
## metoda pro spuštění hlavní klávesnice
start <- function(bot, update) {

  # Vytváříme klávesnici
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Počasí")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # Posíláme klávesnici
  bot$sendMessage(update$message$chat_id,
                  text = 'Vyberte příkaz', 
                  reply_markup = RKM)

}

## Metoda pro volání Inline klávesnice
weather <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'Moskva', callback_data = 'New York,us'),
        InlineKeyboardButton(text = 'Petrohrad', callback_data = 'Saint Petersburg'),
        InlineKeyboardButton(text = 'New York', callback_data = 'New York')
      ),
      list(
        InlineKeyboardButton(text = 'Jekatěrinburg', callback_data = 'Yekaterinburg,ru'),
        InlineKeyboardButton(text = 'Berlín', callback_data = 'Berlin,de'),
        InlineKeyboardButton(text = 'Paříž', callback_data = 'Paris,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Řím', callback_data = 'Rome,it'),
        InlineKeyboardButton(text = 'Odesa', callback_data = 'Odessa,ua'),
        InlineKeyboardButton(text = 'Kyjev', callback_data = 'Kyiv,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Tokio', callback_data = 'Tokyo'),
        InlineKeyboardButton(text = 'Amsterdam', callback_data = 'Amsterdam,nl'),
        InlineKeyboardButton(text = 'Washington', callback_data = 'Washington,us')
      )
    )
  )

  # Odeslat Inline klávesnici
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Vyberte město", 
                  reply_markup = IKM)
}

# metoda pro zaslání zprávy o počasí
answer_cb <- function(bot, update) {

  # Získáváme město z zprávy
  city <- update$callback_query$data

  # Odesíláme požadavek
  ans <- GET('https://api.openweathermap.org/data/2.5/weather', 
             query = list(q     = city,
                          lang  = 'cs',
                          units = 'metric',
                          appid = '4776568ccea136ffe4cda9f1969af340')) 

  # Parsujeme odpověď
  result <- content(ans)

  # Formujeme zprávu
  msg <- str_glue("{result$name} počasí:n",
                  "Aktuální teplota: {result$main$temp}n",
                  "Rychlost větru: {result$wind$speed}n",
                  "Popis: {result$weather[[1]]$description}")

  # Posíláme informace o počasí
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text    = msg)

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

# Vytváříme filtry
## zprávy s textem Počasí
MessageFilters$weather <- BaseFilter(function(message) {

  # Kontrolujeme text zprávy
  message$text == "Počasí"

}
)

# Vytváříme obsluhy
h_start         <- CommandHandler('start', start)
h_weather       <- MessageHandler(weather, filters = MessageFilters$weather)
h_query_handler <- CallbackQueryHandler(answer_cb)

# Přidáváme obsluhy do správce
updater <- updater + 
              h_start +
              h_weather +
              h_query_handler

# Spouštíme bota
updater$start_polling()

Spusťte výše uvedený příklad kódu, než nahradíte 'VAŠE BOT TOKEN' skutečným tokenem, který jste získali při vytváření bota přes BotFather (o vytváření bota jsem mluvil v v prvním článku).

Výsledkem bude, že náš bot bude fungovat zhruba takto:
Programujeme telegram bota v jazyce R (část 3): Jak přidat botovi podporu klávesnice

Schematicky můžeme tohoto bota znázornit takto:
Programujeme telegram bota v jazyce R (část 3): Jak přidat botovi podporu klávesnice

Vytvořili jsme 3 metody, které jsou dostupné v našem weather botovi:

  • start — Spuštění hlavní klávesnice bota
  • weather — Spuštění Inline klávesnice pro výběr města
  • answer_cb — Hlavní metoda, která podle zadaného města dotazuje API na počasí a posílá ho do chatu.

Metoda start spouštíme příkazem /start, což je realizováno správcem CommandHandler('start', start).

Pro spuštění metody weather jsme vytvořili shodný filtr:

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

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

}
)

A voláme tuto metodu pomocí následujícího správce zpráv: MessageHandler(weather, filters = MessageFilters$weather).

A nakonec, naše hlavní metoda answer_cb reaguje na stisknutí Inline tlačítek, což je realizováno speciálním správcem: CallbackQueryHandler(answer_cb).

Uvnitř metody answer_cb, načítáme data odeslaná z klávesnice a zapisujeme je do proměnné city: city <- update$callback_query$data. Poté dotazujeme API na data o počasí, vytváříme a odesíláme zprávu, a nakonec používáme metodu answerCallbackQuery abychom informovali bota, že jsme zpracovali stisknutí Inline tlačítka.

Příklad bota, který zobrazuje seznam nejnovějších článků se odkazy podle zadaného Habu z habr.com.

Tento bot uvádím, abych vám ukázal, jak zobrazit Inline tlačítka, která vedou na webové stránky.

Logika tohoto bota je podobná předchozímu, nejprve spouštíme hlavní klávesnici příkazem /start. Dále bot nabízí výběr ze 6 habů, vybereme zajímavý hub a dostaneme 5 nejnovějších publikací z vybraného Habu.

Jak chápete, v tomto případě potřebujeme získat seznam článků, a k tomu budeme používat speciální balíček habR, který umožňuje dotazovat se na články a některé statistiky k nim na Habr v R.

Balíček habR lze nainstalovat pouze z github, k čemuž potřebujete další balíček devtools. Pro instalaci použijte níže uvedený kód.

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

Nyní se podívejme na kód pro vytvoření výše popsaného bota:

Kód 5: Bot, který zobrazuje seznam nejnovějších článků podle vybraného Habu

library(telegram.bot)
library(habR)

# vytváříme instanci třídy Updater
updater <- Updater('TOKEN VAŠEHO BOTA')

# vytváříme metody
## metoda pro spuštění hlavní klávesnice
start <- function(bot, update) {

  # vytváříme klávesnici
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Seznam článků")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # posíláme klávesnici
  bot$sendMessage(update$message$chat_id,
                  text = 'Vyberte příkaz', 
                  reply_markup = RKM)

}

## Metoda volání Inline klávesnice
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 = 'Vizualizace dat', callback_data = 'data_visualization')
      )
    )
  )

  # Odeslat Inline klávesnici
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Vyberte Hub", 
                  reply_markup = IKM)
}

# metoda pro zprávu o počasí
answer_cb <- function(bot, update) {

  # získáme z zprávy město
  hub <- update$callback_query$data

  # zpráva o tom, že data byla získána pomocí tlačítka
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id, 
                          text = 'Počkejte několik minut, dotaz se zpracovává') 

  # zpráva o tom, že je třeba počkat, dokud bot získá data
  mid <- bot$sendMessage(chat_id = update$from_chat_id(),
                         text = "Počkejte několik minut, než sesbírám data o vybraném Hubu")

  # parsujeme Habr
  posts <- head(habr_hub_posts(hub, 1), 5)

  # odstraňujeme zprávu o tom, že je třeba počkat
  bot$deleteMessage(update$from_chat_id(), mid$message_id) 

  # vytváříme seznam tlačítek
  keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))

  # vytváříme klávesnici
  IKM <- InlineKeyboardMarkup(
    inline_keyboard =  keys 
    )

  # posíláme informace o počasí
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = paste0("5 nejnovějších článků z Hubu ", hub),
                  reply_markup = IKM)

}

# vytváříme filtry
## zprávy s textem Počasí
MessageFilters$hubs <- BaseFilter(function(message) {

  # kontrolujeme text zprávy
  message$text == "Seznam článků"

}
)

# vytváříme zpracovatele
h_start         <- CommandHandler('start', start)
h_hubs          <- MessageHandler(habs, filters = MessageFilters$hubs)
h_query_handler <- CallbackQueryHandler(answer_cb)

# přidáváme zpracovatele do správy
updater <- updater + 
  h_start +
  h_hubs  +
  h_query_handler

# spouštíme bota
updater$start_polling()

Spusťte výše uvedený příklad kódu, než nahradíte 'VAŠE BOT TOKEN' skutečným tokenem, který jste získali při vytváření bota přes BotFather (o vytváření bota jsem mluvil v v prvním článku).

Nakonec dostaneme následující výsledek:
Programujeme telegram bota v jazyce R (část 3): Jak přidat botovi podporu klávesnice

Seznam dostupných Hubů jsme zapsali v hardcodě v metodě 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)
}

Seznam článků z uvedeného Hubu získáváme příkazem habr_hub_posts(), z balíčku habR. Přičemž uvádíme, že nechceme seznam článků za celé období, ale pouze první stránku, na které se nachází 20 článků. Z získané tabulky pomocí příkazu head() necháváme pouze 5 nejvyšších, které jsou nejnovějšími články.

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

Logika je velmi podobná předchozímu botu, ale v tomto případě generujeme Inline klávesnici se seznamem článků dynamicky pomocí funkce lapply().

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

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

Do textu tlačítka dosazujeme název článku posts$title[x], a do argumentu url odkaz na článek: url = posts$link[x].

Dále vytváříme filtr, zpracovatele a spouštíme našeho bota.

Závěr

Nyní budou boty, které jste napsali, mnohem pohodlnější na použití, protože jejich ovládání se bude provádět z klávesnice, a ne zadáváním příkazů. Minimálně při interakci s botem přes smartphone klávesnice výrazně usnadní proces používání.

V dalším článku se podíváme, jak vybudovat logický dialog s botem a pracovat s databázemi.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster