Писане на бот за телеграма в R (част 3): Как да добавите поддръжка на клавиатура към бот

Това е третата статия от поредицата „Писане на телеграм бот в R“. В предишни публикации научихме как да създадем бот за телеграма, да изпращаме съобщения чрез него, добавяме команди и филтри за съобщения към бота. Ето защо, преди да започнете да четете тази статия, горещо ви препоръчвам да я прочетете предишен, защото Тук вече няма да се спирам на описаните по-рано основи на изграждането на ботове.

В тази статия ще подобрим използваемостта на нашия бот, като добавим клавиатура, която ще направи интерфейса на бота интуитивен и лесен за използване.

Писане на бот за телеграма в R (част 3): Как да добавите поддръжка на клавиатура към бот

Всички статии от поредицата “Писане на телеграм бот в R”

  1. Ние създаваме бот и го използваме за изпращане на съобщения в telegram
  2. Добавете поддръжка на команди и филтри за съобщения към бота
  3. Как да добавите поддръжка на клавиатура към бот

Съдържание

Ако се интересувате от анализ на данни, може да се интересувате от моя телеграма и YouTube канали. По-голямата част от съдържанието на който е посветено на езика R.

  1. Какви типове клавиатури поддържа телеграмният бот?
  2. Клавиатура за отговор
  3. Вградена клавиатура
    3.1. Пример за прост бот с поддръжка на InLine бутони
    3.2. Пример за бот, който отчита текущото време за избран град
    3.3. Пример за бот, който показва списък с най-новите статии с връзки към посочения център от habr.com
  4. Заключение

Какви типове клавиатури поддържа телеграмният бот?

Към момента на писане на тази статия telegram.bot ви позволява да създавате два типа клавиатури:

  • Отговор - Основната, обикновена клавиатура, която се намира под панела за въвеждане на текст на съобщението. Такава клавиатура просто изпраща текстово съобщение до бота и като текст ще изпрати текста, който е написан на самия бутон.
  • Inline - Клавиатура, свързана с конкретно съобщение на бот. Тази клавиатура изпраща данните на бота, свързани с натиснатия бутон; тези данни може да се различават от текста, изписан върху самия бутон. И такива бутони се обработват CallbackQueryHandler.

За да може ботът да отвори клавиатурата, е необходимо при изпращане на съобщение чрез метода sendMessage(), предайте създадената преди това клавиатура като аргумент reply_markup.

По-долу ще разгледаме няколко примера.

Клавиатура за отговор

Както писах по-горе, това е основната клавиатура за управление на бота.

Пример за създаване на клавиатура за отговор от официалната помощ

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)

Горното е пример от официалната помощ на пакета telegram.bot. За да създадете клавиатура, използвайте функцията ReplyKeyboardMarkup(), което на свой ред взема списък със списъци с бутони, които са създадени от функцията KeyboardButton().

Защо в ReplyKeyboardMarkup() Трябва ли да преминете не просто списък, а списък от списъци? Факт е, че преминавате основния списък и в него дефинирате всеки ред бутони в отделни списъци, т.к. Можете да поставите няколко бутона в един ред.

аргумент resize_keyboard ви позволява автоматично да изберете оптималния размер на бутоните на клавиатурата и аргумента one_time_keyboard ви позволява да скриете клавиатурата след всяко натискане на бутон.

Нека напишем прост бот, който ще има 3 бутона:

  • Идентификатор на чат - Поискайте ИД на чат за диалог с бот
  • Моето име - Поискайте вашето име
  • Моето влизане - Поискайте вашето потребителско име в telegram

Код 1: Прост бот с клавиатура за отговор

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

Стартирайте примерния код по-горе, след като замените „YOUR BOT TOKEN“ с истинския токен, който сте получили при създаването на бота чрез Бот баща (Говорих за създаване на бот в първа статия).

След стартиране дайте команда на бота /start, защото Точно това дефинирахме за стартиране на клавиатурата.

Писане на бот за телеграма в R (част 3): Как да добавите поддръжка на клавиатура към бот

Ако в момента ви е трудно да анализирате дадения примерен код със създаването на методи, филтри и манипулатори, тогава трябва да се върнете към предишния Статия, в който описах всичко това подробно.

Създадохме 4 метода:

  • старт — Стартиране на клавиатурата
  • chat_id — Заявка за ID на чат
  • my_name — Поискайте вашето име
  • my_username — Поискайте вашето влизане

Възразявам MessageFilters добави 3 филтъра за съобщения въз основа на техния текст:

  • chat_id — Съобщения с текст "Чат ID"
  • име — Съобщения с текст "Моё имя"
  • потребителско име — Съобщения с текст "Мой логин"

И създадохме 4 манипулатора, които на базата на дадени команди и филтри ще изпълнят посочените методи.

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

Самата клавиатура се създава вътре в метода start() екип ReplyKeyboardMarkup().

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

В нашия случай поставихме всички бутони един под друг, но можем да ги подредим в един ред, като направим промени в списъка със списъци с бутони. защото един ред вътре в клавиатурата се създава чрез вложен списък от бутони, тогава, за да покажем нашите бутони в един ред, трябва да пренапишем част от кода за конструиране на клавиатурата по следния начин:

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

Писане на бот за телеграма в R (част 3): Как да добавите поддръжка на клавиатура към бот

Клавиатурата се изпраща в чата с помощта на метода sendMessage(), в аргумента reply_markup.

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

Вградена клавиатура

Както писах по-горе, Inline клавиатурата е обвързана с конкретно съобщение. С нея се работи малко по-трудно от основната клавиатура.

Първоначално трябва да добавите метод към бота за извикване на вградената клавиатура.

За да отговорите на щракване върху бутон Inline, можете също да използвате метода на бота answerCallbackQuery(), който може да покаже известие в интерфейса на телеграмата на потребителя, който натисне бутона Inline.

Данните, изпратени от бутона Inline, не са текст, така че за да ги обработите, трябва да създадете специален манипулатор с помощта на командата CallbackQueryHandler().

Кодът за изграждане на вградена клавиатура, който е даден в официалната помощ на пакета telegram.bot.

Код за изграждане на Inline клавиатура от официалната помощ

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

Трябва да създадете вградена клавиатура с помощта на командата InlineKeyboardMarkup(), на същия принцип като клавиатурата за отговор. IN InlineKeyboardMarkup() необходимо е да се подаде списък от списъци с вградени бутони, всеки отделен бутон се създава от функцията InlineKeyboardButton().

Вграденият бутон може или да предаде някои данни на бота, като използва аргумент callback_data, или отворете която и да е HTML страница, посочена с помощта на аргумента url.

Резултатът ще бъде списък, в който всеки елемент е и списък с вградени бутони, които трябва да бъдат комбинирани в един ред.

След това ще разгледаме няколко примера за ботове с Inline бутони.

Пример за прост бот с поддръжка на InLine бутони

Първо ще напишем бот за експресно тестване за covid-19. По команда /test, ще ви изпрати клавиатура с два бутона, в зависимост от натиснатия бутон ще ви изпрати съобщение с резултатите от вашето тестване.

Код 2: Най-простият бот с вградена клавиатура

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

Стартирайте примерния код по-горе, след като замените „YOUR BOT TOKEN“ с истинския токен, който сте получили при създаването на бота чрез Бот баща (Говорих за създаване на бот в първа статия).

Резултати:
Писане на бот за телеграма в R (част 3): Как да добавите поддръжка на клавиатура към бот

Създадохме два метода:

  • тест — За изпращане към чат Вградена клавиатура
  • answer_cb — За обработка на данни, изпратени от клавиатурата.

Данните, които ще бъдат изпратени от всеки бутон, са посочени в аргумента callback_data, при създаване на бутон. Можете да получите данните, изпратени от бутона, като използвате конструкцията update$callback_query$data, вътре в метода answer_cb.

За да може ботът да реагира на вградената клавиатура, метод answer_cb обработени от специален манипулатор: CallbackQueryHandler(answer_cb). Което изпълнява указания метод, когато се щракне върху бутона Inline. Манипулатор CallbackQueryHandler приема два аргумента:

  • callback — Методът, който трябва да се изпълни
  • pattern — Филтриране по данни, които са обвързани с бутона с помощта на аргумент callback_data.

Съответно, използвайки аргумента pattern Можем да напишем отделен метод за натискане на всеки бутон:

Код 3: Отделни методи за всеки вграден бутон

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

Стартирайте примерния код по-горе, след като замените „YOUR BOT TOKEN“ с истинския токен, който сте получили при създаването на бота чрез Бот баща (Говорих за създаване на бот в първа статия).

Сега сме написали 2 отделни метода, т.е. един метод за всяко натискане на бутон и използва аргумента pattern, когато създавате техните манипулатори:

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

Кодът на метода завършва answer_cb екип bot$answerCallbackQuery(callback_query_id = update$callback_query$id), което казва на бота, че са получени данни от вградената клавиатура.

Пример за бот, който отчита текущото време за избран град

Нека се опитаме да напишем бот, който изисква данни за времето.

Логиката на неговата работа ще бъде следната. Първоначално от екипа /start извиквате главната клавиатура, която има само един бутон „Времето“. Щраквайки върху този бутон, ще получите съобщение с Inline клавиатурата, за да изберете града, за който искате да разберете текущото време. Изберете един от градовете и вземете текущото време.

В този пример с код ще използваме няколко допълнителни пакета:

  • httr — пакет за работа с HTTP заявки, въз основа на който се изгражда работа с всеки API. В нашия случай ще използваме безплатния API openweathermap.org.
  • stringr — пакет за работа с текст, в нашия случай ще го използваме за генериране на съобщение за времето в избрания град.

Код 4: Бот, който съобщава текущото време за избрания град

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

Стартирайте примерния код по-горе, след като замените „YOUR BOT TOKEN“ с истинския токен, който сте получили при създаването на бота чрез Бот баща (Говорих за създаване на бот в първа статия).

В резултат на това нашият бот ще работи нещо подобно:
Писане на бот за телеграма в R (част 3): Как да добавите поддръжка на клавиатура към бот

Схематично този бот може да бъде изобразен така:
Писане на бот за телеграма в R (част 3): Как да добавите поддръжка на клавиатура към бот

Създадохме 3 налични метода в нашия метеорологичен бот:

  • Начало — Стартирайте основната клавиатура на бота
  • време — Стартирайте Inline клавиатура, за да изберете град
  • answer_cb — Основният метод, който иска времето от API за даден град и го изпраща в чата.

метод Начало стартираме го с командата /start, който се изпълнява от манипулатора CommandHandler('start', start).

За да стартирате метод време създадохме филтър със същото име:

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

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

}
)

И ние извикваме този метод със следния манипулатор на съобщения: MessageHandler(weather, filters = MessageFilters$weather).

И в крайна сметка основният ни метод answer_cb реагира на натискане на бутони Inline, което се изпълнява от специален манипулатор: CallbackQueryHandler(answer_cb).

Вътре в метод answer_cb, четем данните, изпратени от клавиатурата, и ги записваме в променлива city: city <- update$callback_query$data. След това изискваме данни за времето от API, генерираме и изпращаме съобщение и накрая използваме метода answerCallbackQuery за да информираме бота, че сме обработили щракването върху бутона Inline.

Пример за бот, който показва списък с най-новите статии с връзки към посочения център от www.habr.com.

Представям този бот, за да ви покажа как да показвате вградени бутони, които водят до уеб страници.

Логиката на този бот е подобна на предишния, първоначално стартираме основната клавиатура с командата /start. След това ботът ни дава списък от 6 центъра, от които да избираме, избираме центъра, който ни интересува, и получаваме 5-те най-нови публикации от избрания център.

Както разбирате, в този случай трябва да получим списък със статии и за това ще използваме специален пакет habR, което ви позволява да поискате статии от Habra и някои статистики за тях в R.

Инсталирайте пакет habR възможно само от github, за което ще ви трябва допълнителен пакет devtools. За да инсталирате, използвайте кода по-долу.

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

Сега нека да разгледаме кода за изграждане на бота, описан по-горе:

Код 5: Бот, който показва списък с най-новите статии в избрания център

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

Стартирайте примерния код по-горе, след като замените „YOUR BOT TOKEN“ с истинския токен, който сте получили при създаването на бота чрез Бот баща (Говорих за създаване на бот в първа статия).

В резултат на това ще получим този резултат:
Писане на бот за телеграма в R (част 3): Как да добавите поддръжка на клавиатура към бот

Ние твърдо кодирахме списъка с хъбове, налични за избор в метода 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)
}

Получаваме списък със статии от посочения Хъб с командата habr_hub_posts(), от опаковката habR. В същото време отбелязваме, че не се нуждаем от списък със статии за цялото време, а само от първата страница, на която са разположени 20 статии. От получената таблица с помощта на командата head() Оставяме само топ 5, които са най-новите статии.

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

Логиката е много подобна на предишния бот, но в този случай генерираме вградена клавиатура със списък от статии, динамично използвайки функцията lapply().

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

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

Вмъкваме заглавието на статията в текста на бутона posts$title[x], и в аргумента url линк към статията: url = posts$link[x].

След това създаваме филтър, манипулатори и стартираме нашия бот.

Заключение

Сега ботовете, които пишете, ще бъдат много по-удобни за използване, поради факта, че ще се управляват от клавиатурата, а не чрез въвеждане на команди. Като минимум, когато взаимодействате с бот чрез смартфон, клавиатурата значително ще опрости процеса на използването му.

В следващата статия ще разберем как да изградим логичен диалог с бот и да работим с бази данни.

Източник: www.habr.com

Добавяне на нов коментар