Пішам telegram бота на мове R (частка 3): Як дадаць боту падтрымку клавіятуры

Гэта трэці артыкул з серыі "Пішам telegram бота на мове R". У папярэдніх публікацыях мы навучыліся ствараць тэлеграм робата, адпраўляць праз яго паведамленні, дадалі робату каманды і фільтры паведамленняў. Таму перад тым як прыступіць да чытання дадзенага артыкула я вельмі рэкамендую азнаёміцца ​​з папярэднімі, т.я. тут я ўжо не буду спыняць на апісаных раней асновах ботабудавання.

У гэтым артыкуле мы павысім юзабіліці нашага робата за кошт дадання клавіятуры, якая зробіць інтэрфейс робата інтуітыўна зразумелым, і простым ў выкарыстанні.

Пішам telegram бота на мове R (частка 3): Як дадаць боту падтрымку клавіятуры

Усе артыкулы з серыі "Пішам telegram бота на мове R"

  1. Ствараем бота, і адпраўляем з яго дапамогай паведамлення ў telegram
  2. Дадаем боту падтрымку каманд і фільтры паведамленняў
  3. Як дадаць боту падтрымку клавіятуры

Змест

Калі вы цікавіцеся аналізам дадзеных магчыма вам будуць цікавыя мае тэлеграма и YouTube каналы. Большая частка кантэнту якіх прысвечаны мове R.

  1. Якія тыпы клавіятур падтрымлівае тэлеграм бот
  2. Reply клавіятура
  3. Inline клавіятура
    3.1. Прыклад найпростага робата з падтрымкай InLine кнопак
    3.2. Прыклад бота, які паведамляе бягучае надвор'е па выбраным горадзе
    3.3. Прыклад робата, які выводзіць спіс самых свежых артыкулаў са спасылкамі па-паказаным Хабу з habr.com
  4. Заключэнне

Якія тыпы клавіятур падтрымлівае тэлеграм бот

На момант напісання артыкула telegram.bot дазваляе вам стварыць клавіятуры двух тыпаў:

  • Reply - Асноўная, звычайная клавіятура, якая знаходзіцца пад панэллю ўводу тэксту паведамлення. Такая клавіятура проста адпраўляе робату тэкставае паведамленне, і ў якасці тэксту адправіць той тэкст, які напісаны на самой кнопцы.
  • Inline – Клавіятура прывязаная да канкрэтнага паведамлення робата. Дадзеная клавіятура адпраўляе робату дадзеныя, прывязаныя да націснутай кнопкі, гэтыя дадзеныя могуць адрознівацца ад тэксту, напісанага на самой кнопцы. І апрацоўваюцца такія кнопкі праз CallbackQueryHandler.

Для таго, каб бот адкрыў клавіятуру неабходна пры адпраўцы паведамлення праз метад sendMessage(), перадаць створаную раней клавіятуру ў аргумент reply_markup.

Ніжэй мы разбяром некалькі прыкладаў.

Reply клавіятура

Як я ўжо пісаў вышэй, гэта асноўная клавіятура кіравання робатам.

Прыклад стварэння Reply клавіятуры з афіцыйнай даведкі

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 кнопкі:

  • Чат ID - Запытаць чат ID дыялогу з ботам
  • Маё імя - Запытаць сваё імя
  • Мой лагін - Запытаць сваё імя карыстальніка ў тэлеграм

Код 1: Просты бот з Reply клавіятурай

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

Запусціце прыведзены вышэй прыклад кода, папярэдне замяніўшы 'ТОКЕН ВАШАГА БОТА' на рэальны токен, які вы атрымалі пры стварэнні бота праз БотБацька (аб стварэнні бота я распавядаў у першым артыкуле).

Пасля запуску задайце боту каманду /start, т.я. менавіта яе мы вызначылі для запуску клавіятуры.

Пішам telegram бота на мове R (частка 3): Як дадаць боту падтрымку клавіятуры

Калі на дадзены момант вам складана разабраць прыведзены прыклад кода, са стварэннем метадаў, фільтраў і апрацоўшчыкаў, тое варта вярнуцца да папярэдняй артыкуле, у якой я падрабязна ўсё гэта апісаў.

Мы стварылі 4 метады:

  • start - Запуск клавіятуры
  • chat_id - Запыт ідэнтыфікатара чата
  • my_name - Запыт свайго імя
  • my_username - Запыт свайго лагіна

У аб'ект MessageFilters дадалі 3 фільтры паведамленняў, па іх тэксце:

  • chat_id — Допісы з тэкстам "Чат ID"
  • name — Допісы з тэкстам "Моё имя"
  • username — Паведамленні з тэкстам "Мой логин"

І стварылі 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
)

Пішам telegram бота на мове R (частка 3): Як дадаць боту падтрымку клавіятуры

Адпраўляецца клавіятура ў чат метадам sendMessage(), у аргуменце reply_markup.

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

Inline клавіятура

Як я ўжо пісаў вышэй, Inline клавіятура прывязана да канкрэтнага паведамлення. З ёй працаваць некалькі складаней, чым з асноўнай клавіятурай.

Першапачаткова вам неабходна дадаць робату метад, для выкліку Inline клавіятуры.

Для адказу на націск Inline кнопкі таксама можна выкарыстоўваць метад бота answerCallbackQuery(), які можа вывесці апавяшчэнне ў інтэрфейсе telegram, карыстачу націснуў Inline кнопку.

Дадзеныя адпраўленыя з Inline кнопкі не з'яўляюцца тэкстам, таму для іх апрацоўкі неабходна стварыць спецыяльны апрацоўшчык з дапамогай каманды CallbackQueryHandler().

Код пабудовы Inline клавіятуры які прыводзіцца ў афіцыйнай даведцы пакета 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)

Будаваць Inline клавіятуру неабходна з дапамогай каманды InlineKeyboardMarkup(), па такім жа прынцыпе, як і Reply клавіятуру. У InlineKeyboardMarkup() неабходна перадаць спіс, спісаў Inline кнопак, кожная асобная кнопка ствараецца функцыяй InlineKeyboardButton().

Inline кнопка можа альбо перадаваць робату нейкія дадзеныя з дапамогай аргументу callback_data, альбо адкрываць якую-небудзь HTML старонку, зададзеную з дапамогай аргументу url.

У выніку будзе спіс, у якім кожны элемент таксама з'яўляецца спісам Inline кнопак, якія неабходна аб'яднаць у адзін шэраг.

Далей мы разгледзім некалькі прыкладаў робатаў з Inline кнопкамі.

Прыклад найпростага робата з падтрымкай InLine кнопак

Для пачатку мы напішам робата для экспрэс тэсціравання на covid-19. Па камандзе /test, ён будзе адпраўляць вам клавіятуру з двума кнопкамі, у залежнасці ад націснутай кнопкі ён будзе дасылаць вам паведамленне з вынікамі вашага тэсціравання.

Код 2: Найпросты бот з Inline клавіятурай

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

Запусціце прыведзены вышэй прыклад кода, папярэдне замяніўшы 'ТОКЕН ВАШАГА БОТА' на рэальны токен, які вы атрымалі пры стварэнні бота праз БотБацька (аб стварэнні бота я распавядаў у першым артыкуле).

Вынік:
Пішам telegram бота на мове R (частка 3): Як дадаць боту падтрымку клавіятуры

Мы стварылі два метады:

  • тэст - Для адпраўкі ў чат Inline клавіятуры
  • answer_cb - Для апрацоўкі адпраўленых з клавіятуры дадзеных.

Дадзеныя, якія будуць адпраўлены з кожнай кнопкі задаюцца ў аргуменце callback_data, пры стварэнні кнопкі. Атрымаць адпраўленыя з кнопкі даныя можна з дапамогай канструкцыі update$callback_query$data, ўнутры метаду answer_cb.

Што б бот рэагаваў на Inline клавіятуру, метад answer_cb апрацоўваецца спецыяльным апрацоўшчыкам: CallbackQueryHandler(answer_cb). Які запускае ўказаны метад па націску Inline кнопкі. Апрацоўшчык CallbackQueryHandler прымае два аргументы:

  • callback - Метад які неабходна запусціць
  • pattern - Фільтр па дадзеных, якія прывязаныя да кнопкі з дапамогай аргументу callback_data.

Адпаведна з дапамогай аргумента pattern мы можам пад націск кожнай кнопкі напісаць асобны метад:

Код 3: Падзяляем метады пад кожную Inline кнопку

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

Запусціце прыведзены вышэй прыклад кода, папярэдне замяніўшы 'ТОКЕН ВАШАГА БОТА' на рэальны токен, які вы атрымалі пры стварэнні бота праз БотБацька (аб стварэнні бота я распавядаў у першым артыкуле).

Цяпер мы напісалі 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), Якая паведамляе робату, што дадзеныя з inline клавіятуры атрыманы.

Прыклад бота, які паведамляе бягучае надвор'е па выбраным горадзе

Давайце паспрабуем напісаць робата, які запытвае дадзеныя аб надвор'і.

Логіка яго працы будзе наступная. Першапачаткова камандай /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()

Запусціце прыведзены вышэй прыклад кода, папярэдне замяніўшы 'ТОКЕН ВАШАГА БОТА' на рэальны токен, які вы атрымалі пры стварэнні бота праз БотБацька (аб стварэнні бота я распавядаў у першым артыкуле).

У выніку наш бот будзе працаваць прыкладна так:
Пішам telegram бота на мове R (частка 3): Як дадаць боту падтрымку клавіятуры

Схематычна дадзенага робата можна выбраць вось так:
Пішам telegram бота на мове 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 кнопкі.

Прыклад робата, які выводзіць спіс самых свежых артыкулаў са спасылкамі па-паказаным Хабу з habr.com.

Дадзенага робата я прыводжу для таго, каб паказаць вам, як вывесці Inline кнопкі якія вядуць на вэб старонкі.

Логіка дадзенага робата падобная з папярэднім, першапачаткова мы запускаем асноўную клавіятуру камандай /start. Далей бот дае нам на выбар спіс з 6 хабаў, мы выбіраем які цікавіць нас хаб, і атрымліваем 5 самых свежых публікацый з абранага Хаба.

Як вы разумееце, у дадзеным выпадку нам неабходна атрымаць спіс артыкулаў, і для гэтага мы будзем выкарыстоўваць спецыяльны пакет habR, які дазваляе запытваць з хабры артыкула і некаторую статыстыку па іх у 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()

Запусціце прыведзены вышэй прыклад кода, папярэдне замяніўшы 'ТОКЕН ВАШАГА БОТА' на рэальны токен, які вы атрымалі пры стварэнні бота праз БотБацька (аб стварэнні бота я распавядаў у першым артыкуле).

У выніку мы атрымаем вось такі вынік:
Пішам telegram бота на мове 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)

Логіка вельмі падобная з папярэднім ботам, але ў дадзеным выпадку Inline клавіятуру са спісам артыкулаў мы генеруемы дынамічна з дапамогай функцыі 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].

Далей, ствараем фільтр, апрацоўшчыкі і запускаем нашага робата.

Заключэнне

Цяпер напісаныя вамі робаты будуць значна зручней у працы, за кошт таго, што кіраванне імі будзе ажыццяўляцца з клавіятуры, а не ўводам каманд. Прынамсі пры ўзаемадзеянні з ботам праз смартфон клавіятура адчувальна спросціць працэс яго выкарыстання.

У наступным артыкуле мы разбярэмся як будаваць лагічны дыялог з ботам, і працаваць з базамі дадзеных.

Крыніца: habr.com

Дадаць каментар