Utilizando Inline Keyboard em um Bot para o Telegram

Aqui no blog eu fiz uma série de três posts mostrando como desenvolver e publicar um bot para o Telegram. O que eu não esperava era que eles fossem criar interesse em tantas pessoas. O número de comentários foi grande e várias dúvidas apareceram. Algumas eu consegui responder e outras não (mesmo tendo pesquisado bastante =[ ). Dentre os assuntos presentes nessas dúvidas, o que mais me chamou a atenção foi Inline Keyboard.

O que é um Inline Keyboard?

Para quem ainda não conhece, o Inline Keyboard é um tipo de teclado (é mesmo? kkk) que serve para o usuário interagir com o bot sem a necessidade de digitação de mensagens. O Inline Keyboard é vinculado às mensagens enviadas pelo bot e pode ser usado para dar acesso a um link ou para uma atualização da mensagem (o que na API do Telegram é chamado de on-the-fly updating ). As imagens abaixo mostram alguns exemplos de Inline Keyboards:

               

Implementando um Inline Keyboard

Agora que o Inline Keyboard foi apresentado, vamos ver como implementá-lo para o seu bot. Para isso, eu vou utilizar, como base para implementação, o código do bot da loteria que fiz nos primeiros posts sobre o Telegram.

Antes de partir para o código, precisamos entender como o Inline Keyboard está definido na API do Telegram. Basicamente, para se criar esse tipo de teclado, é preciso criar um objeto InlineKeyboardMarkup. Esse objeto é composto por um array e dentro dele são inseridos os arrays das linhas. Por sua vez, os botões do InlineKeyboardMarkup são especificados através de arrays do objeto InlineKeyboardButton, o qual contém o texto e outros parâmetros.

Eu sei que a definição é meio confusa, mas no código tudo ficará mais claro! (Pelo menos, é o que eu espero kkk)

Com a definição esclarecida podemos partir para a codificação. Logo a seguir está o trecho de código que deve ser utilizado para que um Inline Keyboard seja criado:

Como é possível ver no código acima, para se implementar um Inline Keyboard é preciso criar um campo reply_markup contendo um inline_keyboard como parâmetro. Como mencionei anteriormente, para cada linha do inline_keyboard é necessário um novo array. Além disso, inserido no array de cada linha, deve ser criado um array para cada botão. O botão, na forma mais simples, é constituído por um parâmetro text onde é definido o texto e outro url contendo o link a ser acessado no evento do clique.

A ideia do trecho de código citado acima foi gerar um teclado onde o usuário pudesse acessar os resultados jogos da loteria diretamente no site do G1. Dessa forma, o Inline Keyboard gerado terá duas linhas e cada linha terá dois botões que redirecionam o usuário para a página do respectivo resultado.

Com o teclado codificado, podemos inseri-lo no método sendMessage, o qual, como vimos nos posts anteriores, é usado para enviar a mensagem de resposta ao usuário. Sendo assim, o código fica da seguinte maneira:

Feito isso, o código final do bot, incluindo o Inline Keyboard, fica da seguinte forma:

Agora, com tudo pronto, podemos testar o nosso bot!

Para testar o bot, primeiro acesse https://telegram.me/loteriascaixabot e digite “g1”. Ao receber a mensagem, o bot irá responder com o novo teclado, como mostra a imagem abaixo:

telegram_inline_keyboard

Para visualizar o código-fonte completo do bot, acesse: Telegram Bot.

O bot desenvolvido neste tutorial foi hospedado na Umbler.

Qualquer dúvida, deixa um comentário.

23 comentários em “Utilizando Inline Keyboard em um Bot para o Telegram”

    • E ae Renato, blz?
      Não achei nada mencionando remoção de botão na documentação da API. Mas você pode, assim que o usuário clicar num botão do inline_keyboard, enviar outro sem o botão que você deseja retirar. Não sei se dessa forma te ajuda, mas é uma possibilidade. =]

      Responder
  1. Luiz Marcos blz ? Preciso urgente dessa ajuda.. to fazendo um bot baseado no script que vc criou do bot Loteria (que ficou ótimo) , mas agr estou usando inline keyborard (no msm script) e preciso de retornos ( callback_query ) nesses botões, ja pesquisei e ta dificil achar algo que se adapta ao seu código.. poderia me ajudar ou criar um post sobre seguindo os posts ja feito..?
    aguardando resposta, obg..

    Responder
  2. Como fazer um inline keyboard numa mensagem normal? Tipo eu quero enviar uma mensagem com vários links, é pra pessoa visualizar só basta ela clicar nos botões que tem o link

    Responder
    • Douglas, no inline keyboard você já tem a mensagem e os links associados a ela. Agora, se você quer digitar uma mensagem no seu telegram pessoal, e essa mensagem ter links. Acho que não dá.

      Responder
  3. Oie, que legal seu tópico.. Tem várias dicas boas pra quem tá brincando com Telegram. tô fazendo um trabalho da facul e queria saber se dá pra pegar a resposta do inline_keyboard e fazer algo com ela? Tipo se o botão clicado for “gostei”, responder alguma coisa e jogar esse “gostei” pra um arquivo de texto com echo e se for “não gostei”, responder outra coisa e jogar a resposta pra outro arquivo de texto com o chat_id de quem respondeu? Desculpa se o que falei não tiver nada a ver com o tópico. Sou bem iniciante.. 🙂

    Responder
  4. Ola, acho que eu tinha comentado aqui, mas não apareceu. Várias dicas legais aqui pro que eu preciso! Mto bom Luiz Marcus! Eu tô fazendo um trabalho da facul e é mais ou menos o que vc fez acima. Mas eu queria fazer um bot de pesquisa. Se o aluno clicar em “gostei” eu preciso responder “obrigado” e gravar isso em algum lugar, como um echo do “gostei” e do “chat_id” em um arquivo .txt. Se responder “não gostei” fazer a mesma coisa em outro arquivo. Dá pra fazer isso com o inline_keyboard?? Desculpa, mas sou um pouco leiga. Obrigada.

    Responder
    • Oi Larissa! Obrigado pelo elogio. =)
      Vou responder os 2 comentários em 1 só, ok? kkk

      Dá para pegar a resposta do inline_keyboard, sim! Você vai precisar usar o parâmetro callback_data quando o usuário clica no botão do inline_keyboard. Sendo assim, você pode ter dois botões, Gostei e Não Gostei, e customizar o comportamento do bot de acordo com o botão que o usuário clicar.

      Na documentação do Telegram você encontra como fazer uso desse parâmetro: https://core.telegram.org/bots/api#inlinekeyboardbutton

      Para ficar mais fácil de você entender, eu fiz um exemplo simples baseado no post, o qual você pode usar como ponto de partida tentar implementar o seu projeto da faculdade:
      https://gist.github.com/luizmarcus/c7adbd66543eeb8f21129aade2528d16
      O código que está no link acima é uma modificação do código do exemplo deste post. Além disso, eu comentei o código para facilitar o entendimento.

      Desculpa a demora pra responder.
      Espero ter ajudado.

      Responder
      • Ahh me ajuda a entender essa linha em que vc diz que o bot responde de acordo com o que o usuário clicou?

        sendMessage(“sendMessage”, array(‘chat_id’ => $update[“callback_query”][“from”][“id”], “text” => getResult($update[“callback_query”][“data”], $update[“callback_query”][“data”])));

        Pelo que consegui entender, você usa a função pra enviar a mensagem de volta para o chat_id de quem enviou e com o texto que tá chega no $update[“callback_query”][“data”]? Se eu quiser fazer uma condição if/else pra gravar esse texto em um arquivo, é aqui que devo fazer?

        Estou fazendo dessa forma, mas não volta nada de resposta:
        https://gist.github.com/larimacais/860844c6f40d05954ad0749423b8a204

        Responder
        • Olá, Larissa.

          Você entendeu bem. É isso mesmo. O sendMessage é usado para responder de acordo com o que o usuário clicou. Para saber em qual opção o usuário clicou é checado o parâmetro $update["callback_query"]["data"].
          Você pode gravar o conteúdo do $update["callback_query"]["data"], sim!

          Eu dei uma olhada no seu Gist. Você posicionou a criação dos arquivos no lugar correto. O código não está funcionando porque você escreveu as condições if/else erradas e o if (isset($update["message"])) estava duplicado. Dei uma corrigida e mudei o método de salvar o arquivo. Dá uma olhada no gist abaixo:
          https://gist.github.com/luizmarcus/804220a9ba4297c82661dc478bd0a113

          Espero ter ajudado.

          Responder
    • Obrigado pelo elogio, Marcelo! =)

      Muito boa a ideia do seu bot. A pessoal de redes/infraestrutura vai adorar! kkk
      Espero que o post ajude a melhorar seu projeto.

      Abs.

      Responder
      • Já ta melhorando bastante. Só fiquei com uma dúvida.

        Eu consigo fazer com que os botoes sejam dinâmicos?

        Por exemplo. O usuário pesquisa todos os problemas ativos, e ai a lista que ele me retorna sempre vai ta mudando. Eu queria fazer um botão pra cada problema pra ele poder escolher entre eles. Será q é possível utilizar dessa forma?

        Responder
  5. Oi Luiz eu fiz um bot mais estou com um problema que ele não finaliza a função poderia me ajudar?
    O código é esse e aí descreve meu problema

    stackoverflow.com/questions/70237929/finish-message-handler-on-pytelegrambotapi

    Responder
  6. Olá tudo bem? Obrigado pela sua contribuição seu artigo ficou excelente. Eu tenho uma dúvida não sei se pode me ajudar. Eu fiz um bot que controla a saída e a entrada de membros em um grupo do telegram usando PHP + api + mysql. O bot funciona perfeitamente mas eu queria substituir o link que ele envia por um botão com o link embutido no botão.

    Ao pesquisar sobre “inline_keyboards” o Google sempre me retorna o seu site em primeiro, e de fato sua solução é muito boa, mas ao tentar implementar ela no meu código não deu certo.

    Estou usando a função “function send($method,$datas=[]){” depois dela vem as credenciais de api do telegram e a função curl do php,.

    Feito isso eu uso o modelo “send(‘sendMessage’ [ ‘chat_id’ => $chat_id, ‘text’ => “Texto da msg aqui”, ‘parse_mode’ =>html]); Desse jeito mandando apens texto funciona, mas quando tento colocar o array do inline_keyboards dentro desse código que chama a função, o botão simplesmente não aparece. Saberia me dizer baseado nessa função como eu poderia implementar o código de forma que a sintaxe consiga chamar o botão no ato do envio? Desde já agradeço sua paciência e disposição em responder.

    Responder
    • Olá, Rodrigo. Obrigado pelo elogio!

      Seria interessante se você olhasse o erro que ocorreu no log do servidor.
      O código do exemplo do post não faz uso do curl, ele faz uso da função file_get_contents. Sabendo disso, um possível problema pode ser a montagem da requisição, uma vez que essa requisição recebe um array como parâmetro e a formatação dele pode não estar da forma correta para ser usado via curl.

      Outro problema que pode ter acontecido é que o curl pode ter dado erro de parse na sua string que contém a URL que você quer usar. Tenta usar a função urlencode e passa a sua URL como parâmetro antes de fazer a requisição. Pode ser que funcione.

      Espero ter ajudado.

      Responder

Deixe um comentário