Att skriva en telegrambot i R (del 3): Hur man lägger till tangentbordsstöd till en bot

Detta är den tredje artikeln i serien "Att skriva en telegrambot i R". I tidigare publikationer har vi lärt oss att skapa en telegrambot, skicka meddelanden genom den, lägga till kommandon och meddelandefilter till boten. Därför, innan du börjar läsa den här artikeln, rekommenderar jag starkt att du läser tidigare, därför att Här kommer jag inte längre att uppehålla mig vid de tidigare beskrivna grunderna för botbyggande.

I den här artikeln kommer vi att förbättra användbarheten av vår bot genom att lägga till ett tangentbord, vilket kommer att göra botgränssnittet intuitivt och enkelt att använda.

Att skriva en telegrambot i R (del 3): Hur man lägger till tangentbordsstöd till en bot

Alla artiklar från serien "Att skriva en telegrambot i R"

  1. Vi skapar en bot och använder den för att skicka meddelanden i telegram
  2. Lägg till kommandostöd och meddelandefilter till boten
  3. Hur man lägger till tangentbordsstöd till en bot

Innehåll

Om du är intresserad av dataanalys kan du vara intresserad av min telegram и Youtube kanaler. Det mesta av innehållet är tillägnat R-språket.

  1. Vilka typer av tangentbord stöder telegramboten?
  2. Svara tangentbordet
  3. Inline-tangentbord
    3.1. Ett exempel på en enkel bot med stöd för InLine-knappar
    3.2. Ett exempel på en bot som rapporterar aktuellt väder för en vald stad
    3.3. Ett exempel på en bot som visar en lista över de senaste artiklarna med länkar till det angivna navet från habr.com
  4. Slutsats

Vilka typer av tangentbord stöder telegramboten?

När detta skrivs telegram.bot låter dig skapa två typer av tangentbord:

  • Svara - Det vanliga, vanliga tangentbordet, som finns under inmatningspanelen för meddelandetext. Ett sådant tangentbord skickar helt enkelt ett textmeddelande till boten, och som texten kommer det att skicka texten som är skriven på själva knappen.
  • Inline - Tangentbord kopplat till ett specifikt botmeddelande. Det här tangentbordet skickar botdata som är associerade med knappen som trycks ned; dessa data kan skilja sig från texten som skrivits på själva knappen. Och sådana knappar bearbetas igenom CallbackQueryHandler.

För att boten ska öppna tangentbordet är det nödvändigt när du skickar ett meddelande via metoden sendMessage(), skicka det tidigare skapade tangentbordet som ett argument reply_markup.

Nedan ska vi titta på flera exempel.

Svara tangentbordet

Som jag skrev ovan är detta det viktigaste botkontrolltangentbordet.

Ett exempel på att skapa ett Svartangentbord från den officiella hjälpen

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)

Ovanstående är ett exempel från paketets officiella hjälp telegram.bot. För att skapa ett tangentbord, använd funktionen ReplyKeyboardMarkup(), som i sin tur tar en lista med listor med knappar som skapas av funktionen KeyboardButton().

Varför i ReplyKeyboardMarkup() Behöver du klara inte bara en lista utan en lista med listor? Faktum är att du passerar huvudlistan, och i den definierar du varje rad med knappar i separata listor, eftersom Du kan placera flera knappar på en rad.

argument resize_keyboard låter dig automatiskt välja den optimala storleken på tangentbordsknapparna och argumentet one_time_keyboard låter dig dölja tangentbordet efter varje knapptryckning.

Låt oss skriva en enkel bot som kommer att ha 3 knappar:

  • Chat-ID - Begär chat-ID för dialog med bot
  • Mitt namn - Begär ditt namn
  • Min inloggning - Begär ditt användarnamn i telegram

Kod 1: Enkel bot med Svartangentbord

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

Kör kodexemplet ovan, efter att ha ersatt 'DIN BOTTOKEN' med den riktiga token du fick när du skapade boten via BotFader (Jag pratade om att skapa en bot i första artikeln).

Efter att ha startat, ge boten ett kommando /start, därför att Detta är precis vad vi definierade för att starta tangentbordet.

Att skriva en telegrambot i R (del 3): Hur man lägger till tangentbordsstöd till en bot

Om det för tillfället är svårt för dig att analysera det givna kodexemplet, med skapandet av metoder, filter och hanterare, bör du återgå till det föregående artikeln, där jag beskrev allt detta i detalj.

Vi skapade 4 metoder:

  • start — Starta tangentbordet
  • chat_id — Begär chatt-ID
  • mitt_namn — Begär ditt namn
  • my_username — Begär din inloggning

Att protestera Meddelandefilter lagt till 3 meddelandefilter baserat på deras text:

  • chat_id — Meddelanden med text "Чат ID"
  • namn — Meddelanden med text "Моё имя"
  • användarnamn — Meddelanden med text "Мой логин"

Och vi skapade 4 hanterare som, baserat på givna kommandon och filter, kommer att exekvera de angivna metoderna.

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

Själva tangentbordet skapas inuti metoden start() team ReplyKeyboardMarkup().

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

I vårt fall placerade vi alla knappar under varandra, men vi kan ordna dem på en rad genom att göra ändringar i listan med knapplistor. Därför att en rad inuti tangentbordet skapas genom en kapslad lista med knappar, sedan för att visa våra knappar på en rad måste vi skriva om en del av koden för att konstruera tangentbordet så här:

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

Att skriva en telegrambot i R (del 3): Hur man lägger till tangentbordsstöd till en bot

Tangentbordet skickas till chatten med metoden sendMessage(), i argumentationen reply_markup.

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

Inline-tangentbord

Som jag skrev ovan är Inline-tangentbordet knutet till ett specifikt meddelande. Det är något svårare att arbeta med än huvudtangentbordet.

Inledningsvis måste du lägga till en metod till boten för att anropa det inbyggda tangentbordet.

För att svara på ett Inline-knappklick kan du också använda botmetoden answerCallbackQuery(), som kan visa ett meddelande i telegramgränssnittet till användaren som trycker på Inline-knappen.

Data som skickas från Inline-knappen är inte text, så för att bearbeta den måste du skapa en speciell hanterare med kommandot CallbackQueryHandler().

Koden för att bygga ett Inline-tangentbord som ges i paketets officiella hjälp telegram.bot.

Kod för att bygga ett inline-tangentbord från den officiella hjälpen

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

Du måste bygga ett inline-tangentbord med kommandot InlineKeyboardMarkup(), på samma princip som Svartangentbordet. I InlineKeyboardMarkup() det är nödvändigt att skicka en lista med listor med Inline-knappar, varje enskild knapp skapas av funktionen InlineKeyboardButton().

En inline-knapp kan antingen skicka vissa data till boten med hjälp av ett argument callback_data, eller öppna en HTML-sida som anges med argumentet url.

Resultatet blir en lista där varje element också är en lista med Inline-knappar som måste kombineras till en rad.

Därefter kommer vi att titta på flera exempel på bots med Inline-knappar.

Ett exempel på en enkel bot med stöd för InLine-knappar

Först kommer vi att skriva en bot för expresstestning för covid-19. På kommando /test, kommer det att skicka ett tangentbord med två knappar, beroende på vilken knapp som trycks in kommer det att skicka ett meddelande till dig med resultatet av din testning.

Kod 2: Den enklaste boten med ett Inline-tangentbord

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

Kör kodexemplet ovan, efter att ha ersatt 'DIN BOTTOKEN' med den riktiga token du fick när du skapade boten via BotFader (Jag pratade om att skapa en bot i första artikeln).

Resultat:
Att skriva en telegrambot i R (del 3): Hur man lägger till tangentbordsstöd till en bot

Vi skapade två metoder:

  • testa — För att skicka till chatt Inline-tangentbord
  • answer_cb — För att behandla data som skickas från tangentbordet.

Data som kommer att skickas från varje knapp anges i argumentet callback_data, när du skapar en knapp. Du kan ta emot data som skickas från knappen med hjälp av konstruktionen update$callback_query$data, inuti metoden answer_cb.

För att boten ska reagera på det inbyggda tangentbordet, metod answer_cb behandlas av en speciell hanterare: CallbackQueryHandler(answer_cb). Som kör den angivna metoden när Inline-knappen klickas. Hanterare CallbackQueryHandler tar två argument:

  • callback — Metoden som behöver köras
  • pattern — Filtrera efter data som är bunden till knappen med ett argument callback_data.

Följaktligen använder argumentet pattern Vi kan skriva en separat metod för att trycka på varje knapp:

Kod 3: Separata metoder för varje Inline-knapp

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

Kör kodexemplet ovan, efter att ha ersatt 'DIN BOTTOKEN' med den riktiga token du fick när du skapade boten via BotFader (Jag pratade om att skapa en bot i första artikeln).

Nu har vi skrivit 2 separata metoder d.v.s. en metod, för varje knapptryckning, och använde argumentet pattern, när de skapar sina hanterare:

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

Metodkoden slutar answer_cb team bot$answerCallbackQuery(callback_query_id = update$callback_query$id), som talar om för boten att data från inlinetangentbordet har tagits emot.

Ett exempel på en bot som rapporterar aktuellt väder för en vald stad

Låt oss försöka skriva en bot som begär väderdata.

Logiken i dess arbete kommer att vara följande. Till en början av teamet /start du anropar huvudtangentbordet, som bara har en "Väder"-knapp. Genom att klicka på den här knappen får du ett meddelande med det inbyggda tangentbordet för att välja den stad för vilken du vill ta reda på det aktuella vädret. Välj en av städerna och få aktuellt väder.

I detta kodexempel kommer vi att använda flera ytterligare paket:

  • httr — ett paket för att arbeta med HTTP-förfrågningar, på grundval av vilket arbete med valfritt API byggs. I vårt fall kommer vi att använda gratis API openweathermap.org.
  • stringr — ett paket för att arbeta med text, i vårt fall kommer vi att använda det för att generera ett meddelande om vädret i den valda staden.

Kod 4: En bot som rapporterar aktuellt väder för den valda staden

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

Kör kodexemplet ovan, efter att ha ersatt 'DIN BOTTOKEN' med den riktiga token du fick när du skapade boten via BotFader (Jag pratade om att skapa en bot i första artikeln).

Som ett resultat kommer vår bot att fungera ungefär så här:
Att skriva en telegrambot i R (del 3): Hur man lägger till tangentbordsstöd till en bot

Schematiskt kan denna bot avbildas så här:
Att skriva en telegrambot i R (del 3): Hur man lägger till tangentbordsstöd till en bot

Vi har skapat 3 metoder tillgängliga i vår väderbot:

  • starta — Starta huvudbottangentbordet
  • väder — Starta det inbyggda tangentbordet för att välja en stad
  • answer_cb — Den huvudsakliga metoden som begär vädret från API:et för en viss stad och skickar det till chatten.

metod starta vi startar den med kommandot /start, som implementeras av hanteraren CommandHandler('start', start).

Att köra en metod väder vi skapade ett filter med samma namn:

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

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

}
)

Och vi kallar den här metoden med följande meddelandehanterare: MessageHandler(weather, filters = MessageFilters$weather).

Och i slutändan vår huvudsakliga metod answer_cb reagerar på att trycka på Inline-knappar, vilket implementeras av en speciell hanterare: CallbackQueryHandler(answer_cb).

Inuti en metod answer_cb, läser vi data som skickas från tangentbordet och skriver det till en variabel city: city <- update$callback_query$data. Sedan begär vi väderdata från API:t, genererar och skickar ett meddelande och använder slutligen metoden answerCallbackQuery för att informera boten om att vi bearbetade klicket på Inline-knappen.

Ett exempel på en bot som visar en lista över de senaste artiklarna med länkar till det angivna navet från will.com.

Jag presenterar den här boten för att visa dig hur du visar Inline-knappar som leder till webbsidor.

Logiken för den här boten liknar den föregående; initialt startar vi huvudtangentbordet med kommandot /start. Därefter ger boten oss en lista med 6 hubbar att välja mellan, vi väljer den hub vi är intresserade av och tar emot de 5 senaste publikationerna från den valda hubben.

Som du förstår måste vi i det här fallet få en lista med artiklar, och för detta kommer vi att använda ett speciellt paket habR, som låter dig begära artiklar från Habra och lite statistik om dem i R.

Installera paketet habR endast möjligt från github, för vilket du behöver ett extra paket devtools. Använd koden nedan för att installera.

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

Låt oss nu titta på koden för att bygga boten som beskrivs ovan:

Kod 5: En bot som visar en lista över de senaste artiklarna på det valda navet

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

Kör kodexemplet ovan, efter att ha ersatt 'DIN BOTTOKEN' med den riktiga token du fick när du skapade boten via BotFader (Jag pratade om att skapa en bot i första artikeln).

Som ett resultat kommer vi att få detta resultat:
Att skriva en telegrambot i R (del 3): Hur man lägger till tangentbordsstöd till en bot

Vi hårdkodade listan över Hubs tillgängliga för val i metoden 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)
}

Vi får en lista över artiklar från den angivna Hub med kommandot habr_hub_posts(), från paketet habR. Samtidigt påpekar vi att vi inte behöver en lista över artiklar för hela tiden, utan endast den första sidan som 20 artiklar finns på. Från den resulterande tabellen med kommandot head() Vi lämnar bara topp 5, som är de senaste artiklarna.

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

Logiken är väldigt lik den tidigare boten, men i det här fallet genererar vi ett Inline-tangentbord med en lista över artiklar dynamiskt med funktionen lapply().

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

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

Vi infogar artikelns titel i knapptexten posts$title[x], och i argumentationen url länk till artikel: url = posts$link[x].

Därefter skapar vi ett filter, hanterare och startar vår bot.

Slutsats

Nu kommer botarna du skriver att vara mycket bekvämare att använda, på grund av att de kommer att styras från tangentbordet, snarare än genom att ange kommandon. Åtminstone, när du interagerar med en bot via en smartphone, kommer tangentbordet att avsevärt förenkla processen att använda den.

I nästa artikel kommer vi att ta reda på hur man bygger en logisk dialog med en bot och arbetar med databaser.

Källa: will.com

Lägg en kommentar