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:
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.
Depois que clicar em algum botão do inline_keyboard tem como remover os botões? Como?
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. =]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..
E ae Jhony, blz?
Eu não quis que o post ficasse muito longo, por isso não coloquei um exemplo com callback. xD
Mas para resolver a sua dúvida e outras parecidas que possam surgir, eu criei um Gist no Github com um código de exemplo:
https://gist.github.com/luizmarcus/06c182ec8a084a3f0d7adae18b79f76e
Além disso, no Gist abaixo tem um exemplo do JSON retornado no callback:
https://gist.github.com/luizmarcus/78f6e60dd49ba12b80d46bffae240600
Boa sorte!
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
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á.
Nossa, estou so lendo os post, pensei em criar um bot Hyip de bitcoin, mas não sei nem por onde começar rsrss… fiquei confuso agora,
Edgard, esse post que você leu é sobre um tópico um pouco mais avançado. É normal você estar confuso.
Já que você estar pensando em criar um bot, eu sugiro você a começar lendo a parte 1 do post sobre como criar um bot para o Telegram. O link é o seguinte:
https://luizmarcus.com/php/como-criar-um-bot-para-o-telegram-em-php-parte-1/
O post tem 3 partes e te dá um noção legal de como faz pra criar um bot. =]
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.. 🙂
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.
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.
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
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.
Cara, parabens. Ficou show de bola seus exemplos e explicações. Eu tenho um bot que eu fiz para interagir com o zabbix onde o pessoal tem q fica passando o ID do que quer como parametro do comando. Vou tentar substituir por esse método de enviar o botao pra pessoa escolher o que quer…
https://github.com/firetxelo/CDRTelegramBot
Parabens novamente.
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.
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?
Marcelo,
Para fazer os botões terem esse comportamento, você vai precisar usar o parâmetro
callback_data
quando o usuário clica no botão do inline_keyboard. Com esse parâmetro você pode customizar a resposta do bot e criar novos botões de acordo com o botão clicado pelo usuário.Na documentação do Telegram você encontra como fazer uso desse parâmetro: https://core.telegram.org/bots/api#inlinekeyboardbutton
Para responder a uma pergunta aqui no blog sobre o
callback_data
eu fiz o gist abaixo. Dá uma olhada nele:https://gist.github.com/luizmarcus/804220a9ba4297c82661dc478bd0a113
Boa sorte com seu projeto!
É possível criar um teclado semelhante ao elemento “Select” do html? para escolher entre valores de 0 à 59?
Olá, Jó.
Para resolver esse seu problema, seu bot poderia imprimir um inline_keyboard com uma única opção “Ver Menu”. No parâmetro
callback_data
desse botão você põe o valor “menu”. Dessa forma, quando o usuário clicar no “Ver Menu”, o seu bot irá receber o valor “menu” no atributo['callback_query']['data']
. Assim, você pode enviar um novo inline_keyboard com as opções de 0 à 59.A solução que imaginei foi essa. Para ficar mais fácil de compreender dá uma olhada no gist abaixo:
https://gist.github.com/luizmarcus/c7adbd66543eeb8f21129aade2528d16
Na documentação do Telegram você encontra como fazer uso dos parâmetros que eu mencionei: https://core.telegram.org/bots/api#inlinekeyboardbutton
Espero ter ajudado.
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
Olá, Amorim.
Infelizmente, com meu conhecimento muito básico de Python, não tenho como ajudar. Além disso, nunca fiz uso da pyTelegramBotAPI. =(
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.
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.