Telegram bot írása R nyelven (3. rész): Hogyan adjunk a botnak billentyűzet támogatást

Ez a harmadik cikk a 'Telegram bot készítése R nyelven' sorozatban. Az előző publikációk során megtanultuk, hogyan kell létrehozni egy Telegram botot, üzeneteket küldeni rajta, parancsokat és üzenetszűrőket hozzáadni. Ezért, mielőtt nekilátnánk e cikk olvasásának, erősen ajánlom, hogy ismerkedjen meg az előzőekkel, mivel itt már nem fogok részletesen foglalkozni a korábban bemutatott botépítési alapokkal.

Ebben a cikkben növelni fogjuk a botunk használhatóságát azzal, hogy billentyűzetet adunk hozzá, amely intuitív módon érthetővé és könnyen használhatóvá teszi a bot interfészét.

Telegram bot írása R nyelven (3. rész): Hogyan adjunk a botnak billentyűzet támogatást

Minden cikk a "Telegram bot írása R nyelven" sorozatból

  1. Bot létrehozása és üzenetek küldése a telegramon keresztül
  2. Bot parancsok támogatásának és üzenetszűrők hozzáadása
  3. Hogyan lehet billentyűzet támogatást adni a bothoz

Tartalom

Ha érdeklik az adatelemzés, talán érdekesek lesznek a telegram és youtube csatornák. A tartalom nagyobb része R nyelvvel foglalkozik.

  1. Milyen típusú billentyűzeteket támogat a Telegram bot
  2. Válasz billentyűzet
  3. Inline billentyűzet
    3.1. Egyszerű példa egy botra, ami inline gombokat támogat
    3.2. Példa egy botra, amely megadja a jelenlegi időjárást a kiválasztott városra
    3.3. Példa egy botra, amely a legfrissebb cikkek listáját adja meg a megadott Habr-ból a habr.com-ról
  4. Zárás

Milyen típusú billentyűzeteket támogat a Telegram bot

A cikk írásának időpontjában telegram.bot kétféle billentyűzet létrehozását teszi lehetővé:

  • Válasz — Az alapvető, hagyományos billentyűzet, amely a szövegbeviteli panel alatt található. Ez a billentyűzet egyszerűen szöveges üzenetet küld a botnak, és a szövegként azt a szöveget küldi, amely a gombon szerepel.
  • Inline — A bot egy adott üzenetéhez kapcsolódó billentyűzet. Ez a billentyűzet olyan adatokat küld a botnak, amelyek a megnyomott gombhoz kapcsolódnak, ezek az adatok eltérhetnek a gombon szereplő szövegtől. Az ilyen gombokat a következő módon kezeljük CallbackQueryHandler.

Ahhoz, hogy a bot megnyissa a billentyűzetet, a következő üzenetküldési módszer használatával sendMessage(), át kell adni a korábban létrehozott billentyűzetet az argumentumban reply_markup.

Az alábbiakban számos példát elemzünk.

Válasz billentyűzet

Ahogy már korábban írtam, ez a bot vezérlő billentyűzete.

A Válasz billentyűzet létrehozásának példája a hivatalos dokumentációból

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

# Egyedi billentyűzet létrehozás
text <- "Nem hűek ezek az egyedi billentyűzetek?"
RKM <- ReplyKeyboardMarkup(
  keyboard = list(
    list(KeyboardButton("Igen, valóban!")),
    list(KeyboardButton("Nem vagyok benne biztos")),
    list(KeyboardButton("Nem..."))
  ),
  resize_keyboard = FALSE,
  one_time_keyboard = TRUE
)

# Egyedi billentyűzet küldése
bot$sendMessage(chat_id, text, reply_markup = RKM)

A fenti példa a csomag hivatalos dokumentációjából származik. telegram.botA billentyűzet létrehozásához a ReplyKeyboardMarkup(), amely egy jegyzéket vár, amelyet gombok listájaként hozunk létre a KeyboardButton().

Miért a ReplyKeyboardMarkup() Csak egy listát kell átadni, vagy listák listáját? Az a helyzet, hogy egy fő listát ad át, és abban külön listák formájában adja meg minden gomb sorát, mivel egy sorba több gombot is elhelyezhet.

Az argumentum resize_keyboard automatikusan optimalizálja a gombok méretét, és az argumentum one_time_keyboard elrejti a billentyűzetet minden gombnyomás után.

Készítsünk egy nagyon egyszerű botot, amelynek három gombja lesz:

  • Chat ID — Kérje el a beszélgetés chat ID-ját a bottal
  • A nevem — Kérje el a nevét
  • A felhasználónevem — Kérje el a felhasználó nevét a Telegramon

Kód 1: Egyszerű bot Reply billentyűzettel

library(telegram.bot)

# példányosítjuk az Updater osztályt
updater <- Updater('A BOT TOKENJE')

# létrehozzuk a módszereket
## módszer a billentyűzet indításához
start <- function(bot, update) {

  # létrehozzuk a billentyűzetet
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Chat ID")),
      list(KeyboardButton("A nevem")),
      list(KeyboardButton("A felhasználónevem"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
  )

  # elküldjük a billentyűzetet
  bot$sendMessage(update$message$chat_id,
                  text = 'Válassza ki a parancsot', 
                  reply_markup = RKM)

}

## módszer, amely visszaadja a chat id-t
chat_id <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("A beszélgetés chat id-ja: ", update$message$chat_id),
                  parse_mode = "Markdown")

}

## módszer, amely visszaadja a nevet
my_name <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("A neve: ", update$message$from$first_name),
                  parse_mode = "Markdown")

}

## módszer, amely visszaadja a felhasználónevet
my_username <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("A felhasználóneve: ", update$message$from$username),
                  parse_mode = "Markdown")

}

# létrehozunk szűrőket
## üzenetek a "Chat ID" szöveggel
MessageFilters$chat_id <- BaseFilter(function(message) {

  # ellenőrizzük az üzenet szövegét
  message$text == "Chat ID"

}
)

## üzenetek a "A nevem" szöveggel
MessageFilters$name <- BaseFilter(function(message) {

  # ellenőrizzük az üzenet szövegét
  message$text == "A nevem"

}
)

## üzenetek a "A felhasználónevem" szöveggel
MessageFilters$username <- BaseFilter(function(message) {

  # ellenőrizzük az üzenet szövegét
  message$text == "A felhasználónevem"
)

# létrehozunk kezelőket
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)

# hozzáadjuk a kezelőket a kezelőhöz
updater <- updater + 
            h_start +
            h_chat_id +
            h_name +
            h_username

# indítjuk a botot 
updater$start_polling()

Futtassa a fenti kód példát úgy, hogy a 'BOTTOKEN' helyére a valós tokent írja, amit a bot létrehozásakor kapott a BotFather (a bot létrehozásáról már beszéltem a első cikkünkben).

A futtatás után adja meg a botnak a parancsot /start, mert ezt a parancsot határoztuk meg a billentyűzet indításához.

Telegram bot írása R nyelven (3. rész): Hogyan adjunk a botnak billentyűzet támogatást

Ha az adott példakódot most nehezen tudja értelmezni, a módszerek, szűrők és kezelők létrehozásával, érdemes visszatérni a korábbi a Spotify döntéshozatali módszertanáról. Egyre több felhasználó preferálja a zenehallgatást mobilon a streaming szolgáltatásban, de a cégnél túlnyomórészt webprogramozók dolgoznak. A Spotify elemezte ezt a helyzetet, és úgy döntött, hogy több mobilfejlesztőt vesz fel, valamint átnevezi a webes szakembereket új irányba:, amelyben részletesen leírtam mindezt.

Négy módszert hoztunk létre:

  • start — A billentyűzet elindítása
  • chat_id — A chat azonosítójának lekérése
  • my_name — A saját nevének lekérése
  • my_username — A saját felhasználónevének lekérése

A MessageFilters objektumba 3 üzenetszűrőt adtunk hozzá, a szövegük alapján:

  • chat_id — Üzenetek szöveggel "Chat ID"
  • name — Üzenetek szöveggel "Saját nevem"
  • username — Üzenetek szöveggel "Saját felhasználónevem"

És négy kezelőt hoztunk létre, amelyek a megadott parancsok és szűrők alapján a megadott módszereket végrehajtják.

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

A billentyűzet maga a start() parancsot ReplyKeyboardMarkup().

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Chat ID")),
      list(KeyboardButton("Saját nevem")),
      list(KeyboardButton("Saját felhasználónevem"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

Ebben az esetben minden gombot egymás alatt helyeztünk el, de elhelyezhetjük őket egy sorba is, a gombok listájának módosításával. Mivel egy sor a billentyűzeten belül beágyazott gomblistán keresztül jön létre, hogy a gombjainkat egy sorba rendezzük, a billentyűzet építésével kapcsolatos kódot így kell átírni:

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
          KeyboardButton("Chat ID"),
          KeyboardButton("Saját nevem"),
          KeyboardButton("Saját felhasználónevem")
     )
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

Telegram bot írása R nyelven (3. rész): Hogyan adjunk a botnak billentyűzet támogatást

A billentyűzetet a chatbe küldjük a sendMessage(), az argumentumban reply_markup.

  bot$sendMessage(update$message$chat_id,
                  text = 'Válassza ki a parancsot', 
                  reply_markup = RKM)

Inline billentyűzet

Ahogy már írtam, az Inline billentyűzet egy adott üzenethez van kötve. Az Inline billentyűzet kezelése némileg bonyolultabb, mint a fő billentyűzeté.

Először hozzá kell adnia a bothoz egy metódust, az Inline billentyűzet meghívására.

Az Inline gomb megnyomására adott válaszhoz a bot metódusát is használhatja answerCallbackQuery(), amely értesítést küld a felhasználói felületre, aki rákattintott az Inline gombra.

Az Inline gombbal elküldött adatok nem szövegek, ezért ezek feldolgozásához speciális kezelőt kell létrehozni a parancs segítségével CallbackQueryHandler().

Az Inline billentyűzet felépítésének kódja, amely a csomag hivatalos útmutatójában található telegram.bot.

Az Inline billentyűzet felépítésének kódja a hivatalos útmutatóból

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

Az Inline billentyűzetet a következő parancs segítségével kell létrehozni InlineKeyboardMarkup(), hasonló elv alapján, mint a Reply billentyűzet. Az InlineKeyboardMarkup() tartalmaznia kell egy listát, a lista Inline gombjaiból, minden egyes gombot az InlineKeyboardButton().

Inline gomb adhat át a bot számára bizonyos adatokat a callback_dataargumentum segítségével, vagy megnyithat egy HTML oldalt, amelyet az url.

argumentum határoz meg. Ennek eredményeként egy lista jön létre, melynek minden eleme szintén egy lista Inline gombokból, amelyeket egy sorba kell egyesíteni.

Ezután megnézünk néhány példát botokra Inline gombokkal.

Egyszerű példa egy botra, ami inline gombokat támogat

Először írjunk egy botot, amely expressz tesztet végez a covid-19-re. A parancsra /test, küldeni fog egy billentyűzetet két gombbal, attól függően, hogy melyik gombra kattintasz, üzenetet fog küldeni a tesztelésed eredményével.

Kód 2: Egyszerű bot Inline billentyűzettel

library(telegram.bot)

# létrehozzuk az Updater osztály példányát
updater <- Updater('A BOTOD JELENTKEZÉSI KÓDJA')

# metódus az InLine billentyűzet küldésére
test <- function(bot, update) {

  # létrehozzuk az InLine billentyűzetet
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Igen", callback_data = 'yes'),
        InlineKeyboardButton("Nem", callback_data = 'no')
      )
    )
  )

  # Elküldjük a billentyűzetet a csevegésbe
  bot$sendMessage(update$message$chat_id, 
                  text = "Megfertőződött koronavírussal?", 
                  reply_markup = IKM)
}

# metódus a gombnyomás feldolgozására
answer_cb <- function(bot, update) {

  # a gomb által kapott adatok
  data <- update$callback_query$data

  # megszerezzük a gombot megnyomó felhasználó nevét
  uname <- update$effective_user()$first_name

  # az eredmény feldolgozása
  if ( data == 'no' ) {

    msg <- paste0(uname, ", gratulálok, a covid-19 teszted negatív.")

  } else {

    msg <- paste0(uname, ", sajnos a covid-19 teszted pozitív.")

  }

  # Üzenet küldése
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # értesítjük a botot, hogy a gomb kérését elfogadtuk
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# létrehozzuk a kezelőket
inline_h      <- CommandHandler('test', test)
query_handler <- CallbackQueryHandler(answer_cb)

# hozzáadjuk a kezelőket a diszpécserhez
updater <- updater + inline_h + query_handler

# elindítjuk a botot
updater$start_polling()

Futtassa a fenti kód példát úgy, hogy a 'BOTTOKEN' helyére a valós tokent írja, amit a bot létrehozásakor kapott a BotFather (a bot létrehozásáról már beszéltem a első cikkünkben).

Eredmény:
Telegram bot írása R nyelven (3. rész): Hogyan adjunk a botnak billentyűzet támogatást

Két metódust hoztunk létre:

  • teszt — Az Inline billentyűzet chatbe való küldésére
  • answer_cb — Az elküldött adatok feldolgozására a billentyűzetről.

Az adatok, amelyek minden gombnyomással elküldésre kerülnek, a gomb létrehozásakor megadott argumentumban találhatók. callback_data, a gomb létrehozásakor. A gombbal elküldött adatok elérhetők a következő szerkezet segítségével: update$callback_query$data, a metóduson belül. answer_cb.

Ahhoz, hogy a bot reagáljon az Inline billentyűzetre, a answer_cb egy speciális kezelővel van kezelve: CallbackQueryHandler(answer_cb). Ez indítja el a megadott metódust az Inline gomb megnyomásakor. A kezelő CallbackQueryHandler két argumentumot fogad:

  • callback — A metódus, amelyet futtatni kell.
  • pattern — A szűrő az adatokra, amelyeket a gombhoz a megadott argumentummal társítottunk. callback_data.

Ennek megfelelően az argumentummal pattern minden egyes gombnyomásra külön metódust írhatunk:

Kód 3: Metódusok szétválasztása minden Inline gombhoz

library(telegram.bot)

# Az Updater osztály példányának létrehozása
updater <- Updater('A BOT TOKENJE')

# Metódus az InLine billentyűzet küldésére
test <- function(bot, update) {  

  # InLine billentyűzet létrehozása
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Igen", callback_data = 'yes'),
        InlineKeyboardButton("Nem", callback_data = 'no')
      )
    )
  )

  # Billentyűzet küldése a csevegésbe
  bot$sendMessage(update$message$chat_id, 
                  text = "Koronavírus tesztje pozitív?", 
                  reply_markup = IKM)
}

# Metódus a "Igen" gomb megnyomásának kezelésére
answer_cb_yes <- function(bot, update) {

  # A gombot megnyomó felhasználó neve
  uname <- update$effective_user()$first_name

  # Eredmény kezelése
  msg <- paste0(uname, ", sajnálom, a teszted a covid-19 pozitív.")

  # Üzenet küldése
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # A botnak jelzünk, hogy a gombon lévő kérés elfogadva
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# Metódus a "Nem" gomb megnyomásának kezelésére
answer_cb_no <- function(bot, update) {

  # A gombot megnyomó felhasználó neve
  uname <- update$effective_user()$first_name

  msg <- paste0(uname, ", gratulálok, a teszted a covid-19 negatív.")

  # Üzenet küldése
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # A botnak jelzünk, hogy a gombon lévő kérés elfogadva
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# Kezelők létrehozása
inline_h          <- CommandHandler('test', test)
query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no  <- CallbackQueryHandler(answer_cb_no, pattern = 'no')

# Kezelők hozzáadása a dispatcherhez
updater <- updater + 
            inline_h + 
            query_handler_yes +
            query_handler_no

# A bot elindítása
updater$start_polling()

Futtassa a fenti kód példát úgy, hogy a 'BOTTOKEN' helyére a valós tokent írja, amit a bot létrehozásakor kapott a BotFather (a bot létrehozásáról már beszéltem a első cikkünkben).

Most két külön metódust írtunk, tehát egy metódust minden gombnyomásra, és felhasználtuk az argumentumot pattern, a kezelők létrehozásakor.

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

A módszer kódja véget ér answer_cb parancsot bot$answerCallbackQuery(callback_query_id = update$callback_query$id), amely arról tájékoztatja a botot, hogy az adatok az inline billentyűzetről megérkeztek.

Példa egy botra, amely megadja a jelenlegi időjárást a kiválasztott városra

Próbáljunk meg írni egy botot, amely adatokat kérdez meg az időjárásról.

A működési logikája a következő lesz. Kezdetben a parancs segítségével /start az alap billentyűzetet hívja meg, amelyen csak egy "Időjárás" gomb található. A gombra kattintva üzenetet kap egy inline billentyűzettel, ahol meg kell választania a várost, amelyről meg akarja tudni az aktuális időjárást. Válasszon az egyik város közül, és megkapja az aktuális időjárást.

Ebben a kódban több további csomagot is használni fogunk:

  • httr — egy csomag HTTP kérések kezelésére, amely alapján bármilyen API-val való munka felépíthető. Ebben az esetben ingyenes API-t fogunk használni. openweathermap.org.
  • stringr — egy csomag szövegkezeléshez, amelyet ebben az esetben az időjárás üzenetének kialakításához használunk a kiválasztott városban.

4. kód: Bot, amely tájékoztatja az aktuális időjárásról a kiválasztott városban

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

# létrehozzuk az Updater osztály példányát
updater <- Updater('A BOTTAL KAPCSOLATOS TOKEN')

# létrehozzuk a metódusokat
## metódus a fő billentyűzet elindításához
start <- function(bot, update) {

  # létrehozzuk a billentyűzetet
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Időjárás")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # elküldjük a billentyűzetet
  bot$sendMessage(update$message$chat_id,
                  text = 'Válasszon parancsot', 
                  reply_markup = RKM)

}

## Inline billentyűzet metódusa
weather <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'Moszkva', callback_data = 'New York,us'),
        InlineKeyboardButton(text = 'Szentpétervár', callback_data = 'Saint Petersburg'),
        InlineKeyboardButton(text = 'New York', callback_data = 'New York')
      ),
      list(
        InlineKeyboardButton(text = 'Jekatyerinburg', callback_data = 'Yekaterinburg,ru'),
        InlineKeyboardButton(text = 'Berlin', callback_data = 'Berlin,de'),
        InlineKeyboardButton(text = 'Párizs', callback_data = 'Paris,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Róma', callback_data = 'Rome,it'),
        InlineKeyboardButton(text = 'Odessa', callback_data = 'Odessa,ua'),
        InlineKeyboardButton(text = 'Kijev', callback_data = 'Kyiv,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Tokió', callback_data = 'Tokyo'),
        InlineKeyboardButton(text = 'Amszterdam', callback_data = 'Amsterdam,nl'),
        InlineKeyboardButton(text = 'Washington', callback_data = 'Washington,us')
      )
    )
  )

  # Elküldjük az Inline billentyűzetet
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Válasszon várost", 
                  reply_markup = IKM)
}

# metódus az időjárás üzenet küldéséhez
answer_cb <- function(bot, update) {

  # megszerezzük a várost az üzenetből
  city <- update$callback_query$data

  # küldünk egy lekérdezést
  ans <- GET('https://api.openweathermap.org/data/2.5/weather', 
             query = list(q     = city,
                          lang  = 'hu',
                          units = 'metric',
                          appid = '4776568ccea136ffe4cda9f1969af340')) 

  # válasz elemzése
  result <- content(ans)

  # üzenet létrehozása
  msg <- str_glue("{result$name} időjárás:n",
                  "Jelenlegi hőmérséklet: {result$main$temp}n",
                  "Szélsebesség: {result$wind$speed}n",
                  "Leírás: {result$weather[[1]]$description}")

  # átadjuk az időjárási információt
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text    = msg)

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

# létrehozzuk a szűrőket
## üzenetek a 'Időjárás' szöveggel
MessageFilters$weather <- BaseFilter(function(message) {

  # ellenőrizzük az üzenet szövegét
  message$text == "Időjárás"

}
)

# létrehozzuk a feldolgozókat
h_start         <- CommandHandler('start', start)
h_weather       <- MessageHandler(weather, filters = MessageFilters$weather)
h_query_handler <- CallbackQueryHandler(answer_cb)

# hozzáadjuk a kezelőket a kezelőhöz
updater <- updater + 
              h_start +
              h_weather +
              h_query_handler

# elindítjuk a botot
updater$start_polling()

Futtassa a fenti kód példát úgy, hogy a 'BOTTOKEN' helyére a valós tokent írja, amit a bot létrehozásakor kapott a BotFather (a bot létrehozásáról már beszéltem a első cikkünkben).

Ennek eredményeként a botunk körülbelül így fog működni:
Telegram bot írása R nyelven (3. rész): Hogyan adjunk a botnak billentyűzet támogatást

Grafikusan a botot így lehet megalkotni:
Telegram bot írása R nyelven (3. rész): Hogyan adjunk a botnak billentyűzet támogatást

Három módszert hoztunk létre, amelyek a meteorológiai botunkon belül elérhetők:

  • start — A bot fő billentyűzetének elindítása
  • időjárás — Az Inline billentyűzet elindítása a város kiválasztásához
  • answer_cb — A fő módszer, amely a megadott város alapján lekéri az időjárást az API-ból, és elküldi azt a csevegésbe.

Módszer start a parancsunk a következő kombinációval indul /start, amelyet a feldolgozó megvalósít: CommandHandler('start', start).

A módszer elindításához időjárás létrehoztunk egy azonos nevű szűrőt:

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

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

}
)

És ezután meghívjuk ezt a módszert a következő üzenetfeldolgozó módszerrel: MessageHandler(időjárás, filters = MessageFilters$időjárás).

Végül a fő módszerünk answer_cb reagál az Inline gombok megnyomására, amit egy külön feldolgozó valósít meg: CallbackQueryHandler(answer_cb).

A módszer belsejében answer_cb, beolvassuk a billentyűzetről érkező adatokat, és eltároljuk azokat a következő változóban: város: város <- update$callback_query$data. Ezt követően lekérdezzük az API-ból az időjárási adatokat, összegyűjtjük és elküldjük az üzenetet, végül használjuk a módszert answerCallbackQuery hogy tájékoztassuk a botot arról, hogy feldolgoztuk az Inline gomb megnyomását.

Egy példa a botra, ami a kiválasztott híból a legfrissebb cikkek listáját és hivatkozásait mutatja meg. habr.com.

Ezt a botot azért hoztam bemutatni, hogy megmutassam, hogyan lehet Inline gombokat létrehozni, amelyek weboldalakra vezetnek.

A bot logikája hasonló az előzőhöz, kezdetben a fő billentyűzetet a következő paranccsal indítjuk. /start. Ezután a botunk 6 hívási lehetőséget kínál, választunk egy érdekes hívót, és megkapjuk az 5 legfrissebb publikációt a kiválasztott hívóból.

Ahogy érthető, ebben az esetben szükségünk van a cikkek listájának lekérésére, ehhez egy különös csomagot fogunk használni. habR, amely lehetővé teszi az időzített cikkek és azok egyes statisztikáinak lekérését R-ben.

A csomag telepítése habR csak a github-ról lehetséges, ehhez egy további csomagra lesz szükséged: devtools. A telepítéshez használja az alábbi kódot.

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

Most nézzük meg a fent említett bot felépítésének kódját:

Kód 5: Bot, amely a választott hívó legfrissebb cikkeinek listáját jeleníti meg

library(telegram.bot)
library(habR)

# Létrehozunk egy Updater osztály példányt
updater <- Updater('A BOT TOKENED')

# Metódusok létrehozása
## Metódus a fő billentyűzet indításához
start <- function(bot, update) {

  # Billentyűzet létrehozása
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Cikkek listája")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # Billentyűzet küldése
  bot$sendMessage(update$message$chat_id,
                  text = 'Válasszon parancsot', 
                  reply_markup = RKM)

}

## Inline billentyűzet metódusa
habs <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'R', callback_data = 'R'),
        InlineKeyboardButton(text = 'Adatbányászat', callback_data = 'data_mining'),
        InlineKeyboardButton(text = 'Adatmérnökség', callback_data = 'data_engineering')
      ),
      list(
        InlineKeyboardButton(text = 'Nagy Adat', callback_data = 'bigdata'),
        InlineKeyboardButton(text = 'Python', callback_data = 'python'),
        InlineKeyboardButton(text = 'Adatok vizualizálása', callback_data = 'data_visualization')
      )
    )
  )

  # Inline billentyűzet küldése
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Válasszon egy Hubot", 
                  reply_markup = IKM)
}

# Metódus az időjárás üzenethez
answer_cb <- function(bot, update) {

  # Város szerzése az üzenetből
  hub <- update$callback_query$data

  # Üzenet arról, hogy az adatok a gombnyomás után megérkeztek
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id, 
                          text = 'Kérem, várjon néhány percet, a kérés feldolgozása folyamatban van') 

  # Üzenet arról, hogy várni kell, amíg a bot megszerzi az adatokat
  mid <- bot$sendMessage(chat_id = update$from_chat_id(),
                         text    = "Kérem, várjon néhány percet, amíg összegyűjtöm az adatokat a választott Hubról")

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

  # Üzenet törlése, hogy várakozás szükséges
  bot$deleteMessage(update$from_chat_id(), mid$message_id) 

  # Gombok listájának létrehozása
  keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))

  # Billentyűzet létrehozása
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = keys 
    )

  # Időjárás információk küldése
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text    = paste0("5 legfrissebb cikk a Hubról: ", hub),
                  reply_markup = IKM)

}

# Szűrők létrehozása
## Üzenetek a "Időjárás" szöveggel
MessageFilters$hubs <- BaseFilter(function(message) {

  # Üzenet szövegének ellenőrzése
  message$text == "Cikkek listája"

}
)

# Kezelők létrehozása
h_start         <- CommandHandler('start', start)
h_hubs          <- MessageHandler(habs, filters = MessageFilters$hubs)
h_query_handler <- CallbackQueryHandler(answer_cb)

# Kezelők hozzáadása a kezelőhöz
updater <- updater + 
  h_start +
  h_hubs  +
  h_query_handler

# Bot indítása
updater$start_polling()

Futtassa a fenti kód példát úgy, hogy a 'BOTTOKEN' helyére a valós tokent írja, amit a bot létrehozásakor kapott a BotFather (a bot létrehozásáról már beszéltem a első cikkünkben).

Az eredmény, amit kapunk, a következő lesz:
Telegram bot írása R nyelven (3. rész): Hogyan adjunk a botnak billentyűzet támogatást

A kiválasztható Hubok listáját hardkódban rögzítettük a módszerben 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)
}

A megadott Hubból származó cikkek listáját a következő parancs segítségével kapjuk meg habr_hub_posts(), a csomagból habR. Itt megadjuk, hogy nem szükséges az összes cikk listája, csak az első oldal, amelyen 20 cikk található. A kapott táblázatból a következő paranccsal head() csak az 5 legfelső cikket hagyjuk meg, amelyek a legfrissebbek.

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

A logika nagyon hasonló az előző botéhoz, de ebben az esetben az Inline billentyűzetet a cikkek listájával dinamikusan generáljuk a lapply().

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

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

segítségével a gomb szövegében a cikk címét helyettesítjük posts$title[x], az argumentumban pedig a cikk linkjét: url url = posts$link[x] Ezután létrehozzuk a szűrőt, az eseménykezelőket és elindítjuk a botunkat..

Mostantól a saját maga által írt botok sokkal kényelmesebbek lesznek a használat során, mivel a vezérlésüket billentyűzettel végezhetjük, nem parancsok beírásával. Legalábbis a bot használata során okostelefonon a billentyűzet jelentősen megkönnyíti a folyamatot.

Zárás

A következő cikkben megvizsgáljuk, hogyan lehet logikai párbeszédet folytatni a bottal és dolgozni az adatbázisokkal.

Ez a harmadik cikk a "Telegram bot készítése R nyelven" sorozatban. Az előző publikációkban megtanultuk, hogyan hozzunk létre Telegram botot, hogyan küldjünk üzeneteket rajta, és hogyan adjunk parancsokat és üzenetszűrőket a bothoz.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster