Een telegrambot schrijven in R (deel 3): Toetsenbordondersteuning toevoegen aan een bot

Dit is het derde artikel in de serie “Een telegrambot schrijven in R”. In eerdere publicaties hebben we geleerd hoe we een telegrambot kunnen maken, er berichten doorheen kunnen sturen, commando's en berichtfilters aan de bot kunnen toevoegen. Daarom raad ik u ten zeerste aan dit artikel te lezen voordat u dit artikel gaat lezen vorig, omdat Hier zal ik niet langer stilstaan ​​bij de eerder beschreven basisprincipes van het bouwen van bots.

In dit artikel zullen we de bruikbaarheid van onze bot verbeteren door een toetsenbord toe te voegen, waardoor de botinterface intuïtief en gebruiksvriendelijk wordt.

Een telegrambot schrijven in R (deel 3): Toetsenbordondersteuning toevoegen aan een bot

Alle artikelen uit de serie “Een telegrambot schrijven in R”

  1. We maken een bot en gebruiken deze om berichten in telegram te verzenden
  2. Voeg opdrachtondersteuning en berichtfilters toe aan de bot
  3. Hoe toetsenbordondersteuning aan een bot toe te voegen

Inhoud

Als u geïnteresseerd bent in data-analyse, bent u wellicht geïnteresseerd in mijn telegram и youtube kanalen. Het grootste deel van de inhoud is gewijd aan de R-taal.

  1. Welke soorten toetsenborden ondersteunt de Telegram-bot?
  2. Antwoordtoetsenbord
  3. Inline-toetsenbord
    3.1. Een voorbeeld van een eenvoudige bot met ondersteuning voor InLine-knoppen
    3.2. Een voorbeeld van een bot die het huidige weer voor een geselecteerde stad rapporteert
    3.3. Een voorbeeld van een bot die een lijst met de nieuwste artikelen weergeeft met links naar de opgegeven Hub van habr.com
  4. Conclusie

Welke soorten toetsenborden ondersteunt de Telegram-bot?

РќР ° РјРѕРјРµРЅС ‚РЅР ° РїРёСЃР ° РЅРёСЏ стР° тьи telegram.bot Hiermee kunt u twee soorten toetsenborden maken:

  • Antwoord - Het gewone hoofdtoetsenbord, dat zich onder het tekstinvoerpaneel voor berichten bevindt. Zo'n toetsenbord stuurt eenvoudigweg een sms-bericht naar de bot, en als tekst stuurt hij de tekst die op de knop zelf staat.
  • Inline - Toetsenbord gekoppeld aan een specifiek botbericht. Dit toetsenbord verzendt de botgegevens die horen bij de ingedrukte knop; deze gegevens kunnen afwijken van de tekst die op de knop zelf staat. En dergelijke knoppen worden verwerkt CallbackQueryHandler.

Om ervoor te zorgen dat de bot het toetsenbord opent, is dit noodzakelijk bij het verzenden van een bericht via de methode sendMessage(), geef het eerder gemaakte toetsenbord door als argument reply_markup.

Hieronder zullen we verschillende voorbeelden bekijken.

Antwoordtoetsenbord

Zoals ik hierboven schreef, is dit het belangrijkste botbesturingstoetsenbord.

Een voorbeeld van het maken van een antwoordtoetsenbord uit de officiële help

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)

Het bovenstaande is een voorbeeld uit de officiële hulp van het pakket telegram.bot. Gebruik de functie om een ​​toetsenbord te maken ReplyKeyboardMarkup(), dat op zijn beurt een lijst bevat met lijsten met knoppen die door de functie zijn gemaakt KeyboardButton().

Waarom in ReplyKeyboardMarkup() Moet u niet alleen een lijst, maar een lijst met lijsten doorgeven? Het feit is dat je de hoofdlijst passeert en daarin elke rij knoppen in afzonderlijke lijsten definieert, omdat Je kunt meerdere knoppen op één rij plaatsen.

argument resize_keyboard Hiermee kunt u automatisch de optimale grootte van de toetsenbordknoppen en het argument selecteren one_time_keyboard Hiermee kunt u het toetsenbord verbergen na elke druk op een knop.

Laten we een eenvoudige bot schrijven die 3 knoppen heeft:

  • Chat-ID - Vraag chat-ID aan van dialoog met bot
  • Mijn naam - Vraag uw naam aan
  • Mijn login - Vraag uw gebruikersnaam op in telegram

Code 1: Eenvoudige bot met antwoordtoetsenbord

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

Voer het bovenstaande codevoorbeeld uit, nadat u 'UW BOT TOKEN' hebt vervangen door het echte token dat u heeft ontvangen bij het maken van de bot via BotVader (Ik had het over het maken van een bot in eerste artikel).

Geef de bot na het starten een commando /start, omdat Dit is precies wat we hebben gedefinieerd om het toetsenbord te starten.

Een telegrambot schrijven in R (deel 3): Toetsenbordondersteuning toevoegen aan een bot

Als het op dit moment moeilijk voor u is om het gegeven codevoorbeeld te ontleden, met het maken van methoden, filters en handlers, dan moet u terugkeren naar het vorige статье, waarin ik dit allemaal in detail heb beschreven.

We hebben 4 methoden gemaakt:

  • start — Start het toetsenbord
  • chat_id — Chat-ID aanvragen
  • mijn_naam — Vraag uw naam aan
  • mijn_gebruikersnaam — Vraag uw login aan

Bezwaar maken BerichtFilters 3 berichtfilters toegevoegd op basis van hun tekst:

  • chat_id — Berichten met tekst "Чат ID"
  • naam — Berichten met tekst "Моё имя"
  • gebruikersnaam — Berichten met tekst "Мой логин"

En we hebben 4 handlers gemaakt die, op basis van gegeven commando's en filters, de gespecificeerde methoden zullen uitvoeren.

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

Het toetsenbord zelf wordt binnen de methode gemaakt start() team ReplyKeyboardMarkup().

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

In ons geval hebben we alle knoppen onder elkaar geplaatst, maar we kunnen ze in één rij rangschikken door wijzigingen aan te brengen in de lijst met knoppenlijsten. Omdat één rij binnen het toetsenbord wordt gemaakt via een geneste lijst met knoppen. Om onze knoppen in één rij weer te geven, moeten we een deel van de code voor het construeren van het toetsenbord als volgt herschrijven:

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

Een telegrambot schrijven in R (deel 3): Toetsenbordondersteuning toevoegen aan een bot

Het toetsenbord wordt met behulp van de methode naar de chat verzonden sendMessage(), in de argumentatie reply_markup.

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

Inline-toetsenbord

Zoals ik hierboven schreef, is het Inline-toetsenbord gekoppeld aan een specifiek bericht. Het is iets moeilijker om mee te werken dan het hoofdtoetsenbord.

In eerste instantie moet u een methode aan de bot toevoegen om het inline-toetsenbord aan te roepen.

Om te reageren op een klik op een Inline-knop, kunt u ook de botmethode gebruiken answerCallbackQuery(), waarmee een melding in de telegraminterface kan worden weergegeven aan de gebruiker die op de Inline-knop drukt.

De gegevens die via de Inline-knop worden verzonden, zijn geen tekst, dus om deze te verwerken moet u een speciale handler maken met behulp van de opdracht CallbackQueryHandler().

De code voor het bouwen van een Inline-toetsenbord die wordt gegeven in de officiële help van het pakket telegram.bot.

Code voor het bouwen van een inline-toetsenbord uit de officiële hulp

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

U moet een Inline-toetsenbord bouwen met behulp van de opdracht InlineKeyboardMarkup(), volgens hetzelfde principe als het antwoordtoetsenbord. IN InlineKeyboardMarkup() het is noodzakelijk om een ​​lijst met lijsten met inline-knoppen door te geven, elke individuele knop wordt door de functie gemaakt InlineKeyboardButton().

Een inline-knop kan met behulp van een argument bepaalde gegevens aan de bot doorgeven callback_dataof open een HTML-pagina die met het argument is opgegeven url.

Het resultaat is een lijst waarin elk element ook een lijst met inline-knoppen is die in één rij moeten worden gecombineerd.

Vervolgens bekijken we verschillende voorbeelden van bots met inline-knoppen.

Een voorbeeld van een eenvoudige bot met ondersteuning voor InLine-knoppen

Eerst zullen we een bot schrijven voor snelle tests op covid-19. Op bevel /test, het stuurt u een toetsenbord met twee knoppen, afhankelijk van de ingedrukte knop stuurt het u een bericht met de resultaten van uw test.

Code 2: De eenvoudigste bot met een inline toetsenbord

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

Voer het bovenstaande codevoorbeeld uit, nadat u 'UW BOT TOKEN' hebt vervangen door het echte token dat u heeft ontvangen bij het maken van de bot via BotVader (Ik had het over het maken van een bot in eerste artikel).

Resultaat:
Een telegrambot schrijven in R (deel 3): Toetsenbordondersteuning toevoegen aan een bot

We hebben twee methoden gemaakt:

  • proef — Om naar chat te verzenden Inline toetsenbord
  • antwoord_cb — Om gegevens te verwerken die vanaf het toetsenbord zijn verzonden.

De gegevens die vanaf elke knop worden verzonden, worden gespecificeerd in het argument callback_data, bij het maken van een knop. U kunt de gegevens die via de knop worden verzonden, ontvangen met behulp van de constructie update$callback_query$data, binnen de methode antwoord_cb.

Om de bot te laten reageren op het Inline-toetsenbord, method antwoord_cb verwerkt door een speciale verwerker: CallbackQueryHandler(answer_cb). Die de opgegeven methode uitvoert wanneer op de Inline-knop wordt geklikt. Behandelaar CallbackQueryHandler heeft twee argumenten:

  • callback — De methode die moet worden uitgevoerd
  • pattern — Filter op gegevens die aan de knop zijn gekoppeld met behulp van een argument callback_data.

Dienovereenkomstig, met behulp van het argument pattern We kunnen een aparte methode schrijven voor het indrukken van elke knop:

Code 3: Afzonderlijke methoden voor elke Inline-knop

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

Voer het bovenstaande codevoorbeeld uit, nadat u 'UW BOT TOKEN' hebt vervangen door het echte token dat u heeft ontvangen bij het maken van de bot via BotVader (Ik had het over het maken van een bot in eerste artikel).

Nu hebben we 2 afzonderlijke methoden geschreven, d.w.z. één methode, voor elke druk op de knop, en gebruikte het argument pattern, bij het maken van hun handlers:

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

Methodecode eindigt antwoord_cb team bot$answerCallbackQuery(callback_query_id = update$callback_query$id), wat de bot vertelt dat er gegevens van het inline toetsenbord zijn ontvangen.

Een voorbeeld van een bot die het huidige weer voor een geselecteerde stad rapporteert

Laten we proberen een bot te schrijven die weergegevens opvraagt.

De logica van zijn werk zal als volgt zijn. In eerste instantie door het team /start je noemt het hoofdtoetsenbord, dat slechts één ‘Weer’-knop heeft. Door op deze knop te klikken, ontvangt u een bericht met het Inline-toetsenbord waarmee u de stad kunt selecteren waarvoor u het actuele weer wilt weten. Selecteer een van de steden en bekijk het huidige weer.

In dit codevoorbeeld zullen we verschillende aanvullende pakketten gebruiken:

  • httr — een pakket voor het werken met HTTP-verzoeken, op basis waarvan het werken met elke API wordt gebouwd. In ons geval gebruiken we de gratis API openweerkaart.org.
  • stringr — een pakket om met tekst te werken, in ons geval zullen we het gebruiken om een ​​bericht te genereren over het weer in de geselecteerde stad.

Code 4: Een bot die het huidige weer voor de geselecteerde stad rapporteert

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

Voer het bovenstaande codevoorbeeld uit, nadat u 'UW BOT TOKEN' hebt vervangen door het echte token dat u heeft ontvangen bij het maken van de bot via BotVader (Ik had het over het maken van een bot in eerste artikel).

Als gevolg hiervan zal onze bot ongeveer als volgt werken:
Een telegrambot schrijven in R (deel 3): Toetsenbordondersteuning toevoegen aan een bot

Schematisch kan deze bot als volgt worden weergegeven:
Een telegrambot schrijven in R (deel 3): Toetsenbordondersteuning toevoegen aan een bot

We hebben 3 methoden beschikbaar gemaakt in onze weerbot:

  • begin - Start het hoofdbottoetsenbord
  • weer — Start het Inline-toetsenbord om een ​​stad te selecteren
  • antwoord_cb — De belangrijkste methode die het weer van de API voor een bepaalde stad opvraagt ​​en naar de chat stuurt.

werkwijze begin we starten het met het commando /start, dat wordt geïmplementeerd door de handler CommandHandler('start', start).

Een methode uitvoeren weer we hebben een filter met dezelfde naam gemaakt:

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

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

}
)

En we noemen deze methode met de volgende berichthandler: MessageHandler(weather, filters = MessageFilters$weather).

En uiteindelijk onze belangrijkste methode antwoord_cb reageert op het indrukken van Inline-knoppen, wat wordt geïmplementeerd door een speciale handler: CallbackQueryHandler(answer_cb).

Binnen een methode antwoord_cb, lezen we de gegevens die vanaf het toetsenbord zijn verzonden en schrijven deze naar een variabele city: city <- update$callback_query$data. Vervolgens vragen we weergegevens op uit de API, genereren en verzenden een bericht en gebruiken uiteindelijk de methode answerCallbackQuery om de bot te informeren dat we de klik op de Inline-knop hebben verwerkt.

Een voorbeeld van een bot die een lijst met de nieuwste artikelen weergeeft met links naar de opgegeven Hub www.habr.com.

Ik presenteer deze bot om u te laten zien hoe u inline-knoppen kunt weergeven die naar webpagina's leiden.

De logica van deze bot is vergelijkbaar met de vorige; in eerste instantie starten we het hoofdtoetsenbord met de opdracht /start. Vervolgens geeft de bot ons een lijst met 6 hubs waaruit we kunnen kiezen, selecteren we de hub waarin we geïnteresseerd zijn en ontvangen we de 5 meest recente publicaties van de geselecteerde Hub.

Zoals u begrijpt, hebben we in dit geval een lijst met artikelen nodig, en hiervoor zullen we een speciaal pakket gebruiken habR, waarmee u artikelen van Habra en enkele statistieken daarover in R kunt opvragen.

Installeer pakket habR alleen mogelijk vanuit github, waarvoor je een extra pakket nodig hebt devtools. Gebruik de onderstaande code om te installeren.

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

Laten we nu eens kijken naar de code voor het bouwen van de hierboven beschreven bot:

Code 5: Een bot die een lijst met de meest recente artikelen op de geselecteerde Hub weergeeft

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

Voer het bovenstaande codevoorbeeld uit, nadat u 'UW BOT TOKEN' hebt vervangen door het echte token dat u heeft ontvangen bij het maken van de bot via BotVader (Ik had het over het maken van een bot in eerste artikel).

Als resultaat krijgen we dit resultaat:
Een telegrambot schrijven in R (deel 3): Toetsenbordondersteuning toevoegen aan een bot

We hebben de lijst met hubs die beschikbaar zijn voor selectie in de methode hardgecodeerd 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)
}

Met de opdracht krijgen we een lijst met artikelen van de opgegeven Hub habr_hub_posts(), uit het pakket habR. Tegelijkertijd wijzen we erop dat we niet de hele tijd een lijst met artikelen nodig hebben, maar alleen de eerste pagina waarop 20 artikelen staan. Uit de resulterende tabel met behulp van de opdracht head() We laten alleen de top 5 over, dit zijn de meest recente artikelen.

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

De logica lijkt sterk op de vorige bot, maar in dit geval genereren we dynamisch een Inline-toetsenbord met een lijst met artikelen met behulp van de functie lapply().

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

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

We voegen de titel van het artikel in de knoptekst posts$title[x], en in de argumentatie url link naar artikel: url = posts$link[x].

Vervolgens maken we een filter, handlers en lanceren we onze bot.

Conclusie

Nu zullen de bots die u schrijft veel handiger in gebruik zijn, omdat ze worden bestuurd vanaf het toetsenbord, in plaats van door het invoeren van opdrachten. Bij interactie met een bot via een smartphone zal het toetsenbord het gebruik ervan op zijn minst aanzienlijk vereenvoudigen.

In het volgende artikel zullen we uitzoeken hoe we een logische dialoog met een bot kunnen opbouwen en met databases kunnen werken.

Bron: www.habr.com

Voeg een reactie