Escrevendo um bot no telegram usando a linguagem R (parte 3): Como adicionar suporte a teclado ao bot

Este é o terceiro artigo da série "Escrevendo um bot do Telegram na linguagem R". Nas publicações anteriores, aprendemos a criar um bot do Telegram, enviar mensagens através dele, adicionar comandos e filtros de mensagens. Portanto, antes de começar a ler este artigo, recomendo fortemente que você familiarize-se com as anteriores, pois aqui não vou me deter nas bases de construção de bots já descritas anteriormente.

Neste artigo, vamos aumentar a usabilidade do nosso bot ao acrescentar um teclado, que tornará a interface do bot intuitiva e fácil de usar.

Escrevendo um bot no telegram usando a linguagem R (parte 3): Como adicionar suporte a teclado ao bot

Criando um bot e enviando mensagens através dele no telegram

  1. Adicionando suporte a comandos e filtros de mensagens ao bot
  2. Como adicionar suporte a teclado ao bot
  3. Construindo um diálogo sequencial e lógico com o bot

Conteúdo

youtube telegram e canais. A maior parte do conteúdo é dedicada à linguagem R. O processo de construção do bot

  1. Quais tipos de teclados o bot do Telegram suporta
  2. Teclado de Resposta
  3. Teclado Inline
    3.1. Exemplo do bot mais simples com suporte a botões Inline
    3.2. Exemplo de um bot que informa o clima atual na cidade escolhida
    3.3. Exemplo de um bot que exibe uma lista dos artigos mais recentes com links sobre o Hub especificado no habr.com
  4. Conclusão

Quais tipos de teclados o bot do Telegram suporta

No momento da escrita deste artigo telegram.bot permite que você crie teclados de dois tipos:

  • Resposta — Teclado padrão, que fica abaixo do painel de entrada de texto da mensagem. Esse teclado simplesmente envia uma mensagem de texto ao bot, e como texto enviará o texto que está escrito no próprio botão.
  • Inline — Teclado ligado a uma mensagem específica do bot. Este teclado envia ao bot dados associados ao botão pressionado, esses dados podem ser diferentes do texto escrito no próprio botão. E esses botões são processados através do CallbackQueryHandler.

Para que o bot abra o teclado, é necessário, ao enviar a mensagem pelo método sendMessage(), passar o teclado criado anteriormente como argumento reply_markup.

Abaixo, discutiremos alguns exemplos.

Teclado de Resposta

Como já mencionei acima, este é o teclado principal de controle do bot.

Exemplo de criação de um teclado de resposta da documentação oficial

bot <- Bot(token = "TOKEN")
chat_id <- "CHAT_ID"

# Criar Teclado Personalizado
text <- "Afinal, esses teclados personalizados são legais?"
RKM <- ReplyKeyboardMarkup(
  keyboard = list(
    list(KeyboardButton("Sim, com certeza são!")),
    list(KeyboardButton("Não tenho certeza")),
    list(KeyboardButton("Não..."))
  ),
  resize_keyboard = FALSE,
  one_time_keyboard = TRUE
)

# Enviar Teclado Personalizado
bot$sendMessage(chat_id, text, reply_markup = RKM)

Acima está um exemplo da documentação oficial do pacote telegram.bot. Para criar um teclado é utilizada a função ReplyKeyboardMarkup(), que por sua vez aceita uma lista de listas de botões, que são criados pela função KeyboardButton().

Por que no ReplyKeyboardMarkup() é necessário transmitir não apenas uma lista, mas uma lista de listas? O fato é que você está enviando a lista principal, e nela você define, em listas separadas, cada linha de botões, pois em uma linha é possível dispor vários botões.

Argumento resize_keyboard permite ajustar automaticamente o tamanho ideal dos botões do teclado, e o argumento one_time_keyboard permite ocultar o teclado após cada clique no botão.

Vamos criar um bot simples, que terá 3 botões:

  • Chat ID — Solicitar o chat ID do diálogo com o bot
  • Meu nome — Solicitar meu nome
  • Meu login — Solicitar meu nome de usuário no telegram

Código 1: Bot simples com teclado de resposta

library(telegram.bot)

# criamos uma instância da classe Updater
updater <- Updater('SEU TOKEN AQUI')

# criamos métodos
## método para iniciar o teclado
start <- function(bot, update) {

  # criamos o teclado
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Chat ID")),
      list(KeyboardButton("Meu nome")),
      list(KeyboardButton("Meu login"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
  )

  # enviamos o teclado
  bot$sendMessage(update$message$chat_id,
                  text = 'Escolha um comando', 
                  reply_markup = RKM)

}

## método que retorna o id do chat
chat_id <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("O chat id deste diálogo: ", update$message$chat_id),
                  parse_mode = "Markdown")

}

## método que retorna o nome
my_name <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Você se chama ", update$message$from$first_name),
                  parse_mode = "Markdown")

}

## método que retorna o login
my_username <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Seu login é ", update$message$from$username),
                  parse_mode = "Markdown")

}

# criamos filtros
## mensagens com o texto Chat ID
MessageFilters$chat_id <- BaseFilter(function(message) {

  # verificamos o texto da mensagem
  message$text == "Chat ID"

}
)

## mensagens com o texto Meu nome
MessageFilters$name <- BaseFilter(function(message) {

  # verificamos o texto da mensagem
  message$text == "Meu nome"

}
)

## mensagens com o texto Meu login
MessageFilters$username <- BaseFilter(function(message) {

  # verificamos o texto da mensagem
  message$text == "Meu login"
)

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

# adicionamos manipuladores ao dispatcher
updater <- updater + 
            h_start +
            h_chat_id +
            h_name +
            h_username

# iniciamos o bot 
updater$start_polling()

Execute the example code above, replacing 'SEU TOKEN DE BOT' with the real token you received when creating your bot via BotFather (I explained how to create a bot in primeiro artigo).

After launching, give the bot the command /start, as that is the one we defined to launch the keyboard.

Escrevendo um bot no telegram usando a linguagem R (parte 3): Como adicionar suporte a teclado ao bot

If you find the example code difficult to parse regarding the creation of methods, filters, and handlers, you should refer back to the previous artigo, where I detailed all of this.

We created 4 methods:

  • start — Launch the keyboard
  • chat_id — Request chat ID
  • my_name — Request your name
  • my_username — Request your username

In the object MessageFilters we added 3 message filters based on their text:

  • chat_id — Messages with the text "Chat ID"
  • name — Messages with the text "My name"
  • username — Messages with the text "My username"

And we created 4 handlers that will execute specified methods based on defined commands and filters.

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

The keyboard itself is created within the method start() com o comando ReplyKeyboardMarkup().

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Chat ID")),
      list(KeyboardButton("My name")),
      list(KeyboardButton("My username"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

In our case, we positioned all buttons one below the other, but we can arrange them in a single row by modifying the list of button lists. Since one row within the keyboard is created through a nested list of buttons, to display our buttons in one row, we need to rewrite part of the keyboard construction code like this:

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
          KeyboardButton("Chat ID"),
          KeyboardButton("My name"),
          KeyboardButton("My username")
     )
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

Escrevendo um bot no telegram usando a linguagem R (parte 3): Como adicionar suporte a teclado ao bot

The keyboard is sent to the chat via the method sendMessage(), in the argument reply_markup.

  bot$sendMessage(update$message$chat_id,
                  text = 'Choose a command', 
                  reply_markup = RKM)

Teclado Inline

As I mentioned earlier, the Inline keyboard is tied to a specific message. Working with it is a bit more complex than with the main keyboard.

Initially, you need to add a method to the bot to call the Inline keyboard.

To respond to Inline button presses, you can also use the bot's method answerCallbackQuery(), which can display a notification in the Telegram interface for the user who pressed the Inline button.

Data sent from the Inline button is not treated as text, so to process it, you need to create a special handler using the command CallbackQueryHandler().

Código para construir um teclado Inline, que é fornecido na documentação oficial do pacote telegram.bot.

Código para construir um teclado Inline da documentação oficial

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

Para construir o teclado Inline, é necessário usar o comando InlineKeyboardMarkup(), seguindo o mesmo princípio que o teclado Reply. Na InlineKeyboardMarkup() é necessário passar uma lista de listas de botões Inline, onde cada botão individual é criado pela função InlineKeyboardButton().

Um botão Inline pode ou transmitir dados ao bot através do argumento callback_data, ou abrir uma página HTML especificada através do argumento url.

O resultado será uma lista em que cada elemento também é uma lista de botões Inline, que devem ser combinados em uma única linha.

Em seguida, veremos alguns exemplos de bots com botões Inline.

Exemplo do bot mais simples com suporte a botões Inline

Para começar, escreveremos um bot para teste rápido de covid-19. Ao receber o comando /test, ele enviará a você um teclado com dois botões, dependendo do botão pressionado, ele enviará uma mensagem com os resultados do seu teste.

Código 2: Bot simples com teclado Inline

library(telegram.bot)

# criamos uma instância da classe Updater
updater <- Updater('SEU TOKEN AQUI')

# método para enviar o teclado Inline
test <- function(bot, update) {

  # criamos o teclado Inline
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Sim", callback_data = 'yes'),
        InlineKeyboardButton("Não", callback_data = 'no')
      )
    )
  )

  # Enviamos o teclado no chat
  bot$sendMessage(update$message$chat_id, 
                  text = "Você está doente com coronavírus?", 
                  reply_markup = IKM)
}

# método para processar o pressionar do botão
answer_cb <- function(bot, update) {

  # dados recebidos do botão
  data <- update$callback_query$data

  # obtemos o nome do usuário que pressionou o botão
  uname <- update$effective_user()$first_name

  # processamento do resultado
  if (data == 'no') {

    msg <- paste0(uname, ", parabéns, seu teste para covid-19 é negativo.")

  } else {

    msg <- paste0(uname, ", infelizmente, seu teste para covid-19 é positivo.")

  }

  # Enviando mensagem
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # informamos ao bot que a solicitação do botão foi recebida
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# criamos manipuladores
inline_h      <- CommandHandler('test', test)
query_handler <- CallbackQueryHandler(answer_cb)

# adicionamos manipuladores ao despachante
updater <- updater + inline_h + query_handler

# iniciamos o bot
updater$start_polling()

Execute the example code above, replacing 'SEU TOKEN DE BOT' with the real token you received when creating your bot via BotFather (I explained how to create a bot in primeiro artigo).

Resultado:
Escrevendo um bot no telegram usando a linguagem R (parte 3): Como adicionar suporte a teclado ao bot

Criamos dois métodos:

  • test — Para enviar o teclado Inline no chat
  • answer_cb — Para processar os dados enviados do teclado.

Os dados que serão enviados com cada botão são especificados no argumento callback_data, ao criar o botão. Os dados enviados pelo botão podem ser obtidos através da estrutura update$callback_query$data, dentro do método answer_cb.

Para que o bot reaja ao teclado Inline, o método answer_cb é tratado por meio de um manipulador especial: CallbackQueryHandler(answer_cb). Este inicia o método especificado ao pressionar o botão Inline. O manipulador CallbackQueryHandler aceita dois argumentos:

  • callback — O método que deve ser executado
  • pattern — Filtro para os dados vinculados ao botão através do argumento callback_data.

Consequentemente, através do argumento pattern podemos escrever um método separado para cada botão pressionado:

Código 3: Dividindo os métodos para cada botão Inline

library(telegram.bot)

# criando uma instância da classe Updater
updater <- Updater('SEU TOKEN DE BOT')

# método para enviar o teclado InLine
test <- function(bot, update) {  

  # criando o teclado InLine
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Sim", callback_data = 'yes'),
        InlineKeyboardButton("Não", callback_data = 'no')
      )
    )
  )

  # Enviando o teclado para o chat
  bot$sendMessage(update$message$chat_id, 
                  text = "Você tem coronavírus?", 
                  reply_markup = IKM)
}

# método para processar o pressionamento do botão Sim
answer_cb_yes <- function(bot, update) {

  # recebendo o nome do usuário que pressionou o botão
  uname <- update$effective_user()$first_name

  # processamento do resultado
  msg <- paste0(uname, ", infelizmente seu teste para covid-19 foi positivo.")

  # Envio da mensagem
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # informando ao bot que a solicitação do botão foi aceita
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# método para processar o pressionamento do botão Não
answer_cb_no <- function(bot, update) {

  # recebendo o nome do usuário que pressionou o botão
  uname <- update$effective_user()$first_name

  msg <- paste0(uname, ", parabéns, seu teste para covid-19 foi negativo.")

  # Envio da mensagem
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # informando ao bot que a solicitação do botão foi aceita
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# criando manipuladores
inline_h          <- CommandHandler('test', test)
query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no  <- CallbackQueryHandler(answer_cb_no, pattern = 'no')

# adicionando manipuladores ao despachante
updater <- updater + 
            inline_h + 
            query_handler_yes +
            query_handler_no

# iniciando o bot
updater$start_polling()

Execute the example code above, replacing 'SEU TOKEN DE BOT' with the real token you received when creating your bot via BotFather (I explained how to create a bot in primeiro artigo).

Agora escrevemos 2 métodos separados, ou seja, um método para cada botão pressionado, e usamos o argumento pattern, ao criar seus manipuladores:

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

O código do método está terminando answer_cb com o comando bot$answerCallbackQuery(callback_query_id = update$callback_query$id), que informa ao bot que os dados do teclado inline foram recebidos.

Exemplo de um bot que informa o clima atual na cidade escolhida

Vamos tentar escrever um bot que solicita dados sobre o clima.

A lógica de funcionamento será a seguinte. Inicialmente, utilizando o comando /start você chama o teclado principal, que contém apenas um botão "Clima". Ao pressionar este botão, você recebe uma mensagem com um teclado inline para selecionar a cidade da qual deseja saber o clima atual. Você escolhe uma das cidades e recebe as informações sobre o clima atual.

Neste exemplo de código, usaremos vários pacotes adicionais:

  • httr — um pacote para manipulação de requisições HTTP, que serve de base para trabalhar com qualquer API. No nosso caso, utilizaremos a API gratuita openweathermap.org.
  • stringr — um pacote para manipulação de texto, que, neste caso, utilizaremos para formar a mensagem sobre o clima na cidade escolhida.

Código 4: Bot que informa o clima atual da cidade selecionada

library(telegram.bot)
library(httr)
library(stringr)

# Criando uma instância da classe Updater
updater <- Updater('SEU TOKEN DO BOT')

# Criando métodos
## Método para iniciar o teclado principal
start <- function(bot, update) {

  # Criando o teclado
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Clima")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # Enviando o teclado
  bot$sendMessage(update$message$chat_id,
                  text = 'Escolha um comando', 
                  reply_markup = RKM)

}

## Método para chamar o teclado Inline
weather <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'Moscovo', callback_data = 'New York,us'),
        InlineKeyboardButton(text = 'São Petersburgo', callback_data = 'Saint Petersburg'),
        InlineKeyboardButton(text = 'Nova York', callback_data = 'New York')
      ),
      list(
        InlineKeyboardButton(text = 'Ekaterinburgo', callback_data = 'Yekaterinburg,ru'),
        InlineKeyboardButton(text = 'Berlim', callback_data = 'Berlin,de'),
        InlineKeyboardButton(text = 'Paris', callback_data = 'Paris,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Roma', callback_data = 'Rome,it'),
        InlineKeyboardButton(text = 'Odessa', callback_data = 'Odessa,ua'),
        InlineKeyboardButton(text = 'Kiev', callback_data = 'Kyiv,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Tóquio', callback_data = 'Tokyo'),
        InlineKeyboardButton(text = 'Amsterdã', callback_data = 'Amsterdam,nl'),
        InlineKeyboardButton(text = 'Washington', callback_data = 'Washington,us')
      )
    )
  )

  # Enviar o teclado Inline
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Escolha uma cidade", 
                  reply_markup = IKM)
}

# Método para enviar a mensagem do clima
answer_cb <- function(bot, update) {

  # Obtendo a cidade da mensagem
  city <- update$callback_query$data

  # Enviando a solicitação
  ans <- GET('https://api.openweathermap.org/data/2.5/weather', 
             query = list(q     = city,
                          lang  = 'pt',
                          units = 'metric',
                          appid = '4776568ccea136ffe4cda9f1969af340')) 

  # Analisando a resposta
  result <- content(ans)

  # Formando a mensagem
  msg <- str_glue("{result$name} clima:\n",
                  "Temperatura atual: {result$main$temp}°C\n",
                  "Velocidade do vento: {result$wind$speed} m/s\n",
                  "Descrição: {result$weather[[1]]$description}")

  # Enviando informações sobre o clima
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text    = msg)

  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# Criando filtros
## Mensagens com o texto Clima
MessageFilters$weather <- BaseFilter(function(message) {

  # Verificando o texto da mensagem
  message$text == "Clima"

}
)

# Criando manipuladores
h_start         <- CommandHandler('start', start)
h_weather       <- MessageHandler(weather, filters = MessageFilters$weather)
h_query_handler <- CallbackQueryHandler(answer_cb)

# Adicionando manipuladores ao despachante
updater <- updater + 
              h_start +
              h_weather +
              h_query_handler

# Iniciando o bot
updater$start_polling()

Execute the example code above, replacing 'SEU TOKEN DE BOT' with the real token you received when creating your bot via BotFather (I explained how to create a bot in primeiro artigo).

Como resultado, nosso bot funcionará mais ou menos assim:
Escrevendo um bot no telegram usando a linguagem R (parte 3): Como adicionar suporte a teclado ao bot

Esquematicamente, este bot pode ser representado assim:
Escrevendo um bot no telegram usando a linguagem R (parte 3): Como adicionar suporte a teclado ao bot

Criamos 3 métodos disponíveis dentro do nosso bot do tempo:

  • start — Iniciar o teclado principal do bot
  • weather — Iniciar o teclado Inline para seleção de cidade
  • answer_cb — Método principal que, dado uma cidade, consulta a API do tempo e envia a resposta no chat.

Método start é iniciado pelo comando /start, que é implementado pelo manipulador CommandHandler('start', start).

Para iniciar o método weather criou-se um filtro homônimo:

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

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

}
)

E chamamos este método com o seguinte manipulador de mensagens: MessageHandler(weather, filters = MessageFilters$weather).

E, por fim, nosso método principal answer_cb reage ao pressionar os botões Inline, o que é implementado por um manipulador especial: CallbackQueryHandler(answer_cb).

Dentro do método answer_cb, lemos os dados enviados pelo teclado e os registramos na variável city: city <- update$callback_query$data. Depois, consultamos os dados do tempo na API, formamos e enviamos a mensagem, e, por fim, utilizamos o método answerCallbackQuery para informar ao bot que processamos o pressionamento do botão Inline.

Um exemplo de bot que exibe uma lista dos artigos mais recentes com links do Hub indicado em habr.com.

Este bot é apresentado para mostrar como exibir botões Inline que levam a páginas da web.

A lógica deste bot é semelhante à anterior; inicialmente, iniciamos o teclado principal com o comando /start. Em seguida, o bot nos oferece uma lista de 6 hubs, escolhemos o hub que nos interessa e obtemos as 5 publicações mais recentes do hub selecionado.

Como vocês podem entender, neste caso, precisamos obter uma lista de artigos, e para isso usaremos um pacote especial habR, que permite consultar artigos do Habr e algumas estatísticas sobre eles em R.

O pacote habR pode ser instalado apenas a partir do GitHub, para isso você precisará de um pacote adicional devtools. Para instalar, use o código abaixo.

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

Agora vamos observar o código para construir o bot descrito acima:

Código 5: Bot que exibe a lista dos artigos mais frescos do hub selecionado

library(telegram.bot)
library(habR)

# Criar uma instância da classe Updater
updater <- Updater('TOKEN DO SEU BOT')

# Criar métodos
## Método para iniciar o teclado principal
start <- function(bot, update) {

  # Criar o teclado
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Lista de artigos")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # Enviar o teclado
  bot$sendMessage(update$message$chat_id,
                  text = 'Escolha um comando', 
                  reply_markup = RKM)

}

## Método para chamar o teclado Inline
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 = 'Visualização de Dados', callback_data = 'data_visualization')
      )
    )
  )

  # Enviar teclado Inline
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Escolha um Hub", 
                  reply_markup = IKM)
}

# Método para mensagem do clima
answer_cb <- function(bot, update) {

  # Obter da mensagem a cidade
  hub <- update$callback_query$data

  # Mensagem informando que os dados do botão foram recebidos
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id, 
                          text = 'Aguarde alguns minutos, a solicitação está sendo processada') 

  # Mensagem informando que deve esperar enquanto o bot obtém os dados
  mid <- bot$sendMessage(chat_id = update$from_chat_id(),
                         text    = "Aguarde alguns minutos enquanto eu reúno dados do Hub escolhido")

  # Parsing do Habr
  posts <- head(habr_hub_posts(hub, 1), 5)

  # Deletar mensagem de espera
  bot$deleteMessage(update$from_chat_id(), mid$message_id) 

  # Formar lista de botões
  keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))

  # Formar teclado
  IKM <- InlineKeyboardMarkup(
    inline_keyboard =  keys 
    )

  # Enviar informações sobre o clima
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text    = paste0("5 artigos mais recentes do Hub ", hub),
                  reply_markup = IKM)

}

# Criar filtros
## Mensagens com texto Clima
MessageFilters$hubs <- BaseFilter(function(message) {

  # Verificar texto da mensagem
  message$text == "Lista de artigos"

}
)

# Criar manipuladores
h_start         <- CommandHandler('start', start)
h_hubs          <- MessageHandler(habs, filters = MessageFilters$hubs)
h_query_handler <- CallbackQueryHandler(answer_cb)

# Adicionar manipuladores ao dispatcher
updater <- updater + 
  h_start +
  h_hubs  +
  h_query_handler

# Iniciar o bot
updater$start_polling()

Execute the example code above, replacing 'SEU TOKEN DE BOT' with the real token you received when creating your bot via BotFather (I explained how to create a bot in primeiro artigo).

No final, obtivemos o seguinte resultado:
Escrevendo um bot no telegram usando a linguagem R (parte 3): Como adicionar suporte a teclado ao bot

A lista de hubs disponíveis para seleção foi codificada diretamente no método hubs:

## Метод вызова 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)
}

A lista de artigos do hub especificado é obtida pelo comando habr_hub_posts(), do pacote habR. Nesse caso, especificamos que não precisamos da lista de artigos de todo o tempo, mas apenas da primeira página, que contém 20 artigos. A partir da tabela obtida, com o comando head() , mantemos apenas os 5 superiores, que são os artigos mais recentes.

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

A lógica é muito semelhante à do bot anterior, mas neste caso, a interface de teclado inline com a lista de artigos é gerada dinamicamente usando a função lapply().

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

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

No texto do botão, inserimos o título do artigo posts$title[x], e no argumento url o link para o artigo: url = posts$link[x].

Em seguida, criamos um filtro, tratadores e iniciamos nosso bot.

Conclusão

Agora, os bots que você criou serão significativamente mais convenientes de usar, uma vez que seu controle será feito pelo teclado e não pela inserção de comandos. Pelo menos na interação com o bot por meio de um smartphone, o teclado tornará o processo de uso muito mais fácil.

No próximo artigo, vamos entender como construir um diálogo lógico com o bot e trabalhar com bancos de dados.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster