用R编写电报机器人(第3部分):如何向机器人添加键盘支持

这是“用R语言编写电报机器人”系列的第三篇文章。在以前的出版物中,我们学习了如何创建电报机器人,如何通过其发送消息,向该机器人添加命令和消息过滤器。因此,强烈建议您在开始阅读本文之前,先熟悉一下以前的文章,因为 在这里,我不会以前面描述的机器人构建为基础。



在本文中,我们将通过添加键盘来使机器人界面直观易用,从而提高机器人的可用性。





该系列的所有文章“用R语言编写电报机器人”



  1. 我们创建一个机器人并使用它发送消息到电报
  2. 向机器人添加命令支持和消息过滤器
  3. 如何为您的机器人增加键盘支持
  4. 与机器人建立一致的逻辑对话
  5. Bot用户权限管理


内容



如果您对数据分析感兴趣,则可能对我的电报YouTube频道感兴趣其中大部分内容专门用于R语​​言。



  1. 电报漫游器支持哪些类型的键盘?
  2. 回复键盘
  3. Inline

    3.1. InLine

    3.2. ,

    3.3. , - habr.com




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


, ' ' , BotFather ( ).

/start, .. .





, , , , .



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
)




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


, ' ' , BotFather ( ).

:



:



  • test — 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()


, ' ' , BotFather ( ).

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 , , . , .



:





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


, ' ' , BotFather ( ).

:



:



3 , :



  • start
  • weather — Inline
  • answer_cb — , API , .


start /start, CommandHandler('start', start).



weather :



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


, ' ' , BotFather ( ).

:



, 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].



, , .





, , , . .



, .




All Articles