Escribir un bot de telegrama en R (parte 3): cĂłmo agregar soporte de teclado a un bot

Este es el tercer artículo de la serie "Escribir un bot de telegrama en lenguaje R". En publicaciones anteriores, aprendimos cómo crear un bot de telegramas, enviar mensajes a través de él, agregar comandos y filtros de mensajes al bot. Por eso, antes de comenzar a leer este artículo, te recomiendo que te familiarices con los anteriores , porque aquí no me detendré en las bases de la construcción de bots descritas anteriormente.



En este artículo, mejoraremos la usabilidad de nuestro bot al agregar un teclado que hará que la interfaz del bot sea intuitiva y fácil de usar.





Todos los artĂ­culos de la serie "Escribir un bot de telegrama en lenguaje R"



  1. Creamos un bot y enviamos mensajes a telegram usándolo
  2. Agregue soporte de comando y filtros de mensajes al bot
  3. CĂłmo agregar soporte de teclado a su bot
  4. Construyendo un diálogo lógico y consistente con el bot
  5. GestiĂłn de derechos de usuario de bot


Contenido



Si está interesado en el análisis de datos, puede que le interesen mis canales de telegram y youtube . La mayor parte del contenido está dedicado al lenguaje R.



  1. ¿Qué tipos de teclados admite el bot de telegram?
  2. Responder teclado
  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