Guia completo sobre como criar um bot Telegram stateful

Maxim Abramchuk Blocked Unblock Seguir Seguindo 19 de junho de 2016

Eu tenho algumas razões para escrever este artigo. Primeiro de tudo eu tenho um repositório chamado ruby-telegram-bot-starter-kit , que contém um clichê para a criação de simples bots Telegram. É muito legal, ele permite que você persista seus dados, traduza suas mensagens via i18n, use teclados personalizados e etc., mas como percebi mais tarde, perdi algumas coisas que são muito importantes.

  1. Fui perguntado muito por questões do Github sobre a maneira certa / possível de armazenar o estado de uma comunicação do usuário do Telegram bot vs.
  2. A técnica de comunicação com os usuários que usei neste repositório era simples, o que é péssimo, porque o Telegram tem a API Webhooks, que é uma forma muito mais conveniente de configurar a comunicação do usuário / bot porque você só recebe atualizações quando o usuário envia uma mensagem para o seu bot.

Então, hoje vamos escrever um pequeno bot de quest em Telegram usando Ruby on Rails, Webhooks API e alguma arquitetura que irá ajudá-lo a armazenar seu estado de usuário / bot como um charme ?

Vamos imaginar que você já tenha criado um aplicativo Rails e um servidor Rails rodando em localhost: 3000 .

API de webhooks funciona apenas com HTTPS, por isso precisamos usar o ngrok para proxy nosso localhost: 3000 com algum servidor acessível via HTTPS. Então, vamos baixar o ngrok (ou instalá-lo via brew no OS X) e executar:

 ngrok http 3000 

Se tudo correr bem, você verá algo assim:

Então, como precisamos de HTTPS, vamos usar este:

Nosso próximo passo é criar um bot no Telegram e obter seu token.

Para fazer isso você precisa encontrar um Botfather no Telegram.

Escreva-lhe um comando / newbot para iniciar a criação de um novo bot:

Legal, agora temos um servidor Rails rodando e um bot Telegram disponível para se comunicar com nossos usuários.

Nosso próximo passo é configurar a comunicação com nosso usuário usando a API Webhooks. Vamos fazer isso.

Precisamos visitar o URL, que pode ser construído como este:

https://api.telegram.org/bot < telegram_bot_token_from_botfather > / setWebhook?url= < your_https_ngrok_url > / webhooks / telegram _ < place_some_big_random_token_here >

Então, no meu caso, será algo assim:

https://api.telegram.org/ bot 220521163: AAHNZe-njGuJz_6-zwOyR1BKkhyJoGpNPyo / setWebhook? url = https://4691cf2f.ngrok.io / webhooks / telegram _ vbc43edbf1614a075954dvd4bfab34l1

Como você pode ver, eu coloquei uma string aleatória no final do nosso URL para ter certeza de que ninguém vai adivinhar e ter acesso à nossa comunicação bot / usuário.

Se você fez tudo certo, ao visitar este URL, você verá uma mensagem de sucesso que se parece com algo assim:

Então, esta mensagem significa que todas as mensagens enviadas para o seu bot passarão pelo WebhooksController do seu aplicativo Rails, que vamos implementar mais.

Abra um arquivo existente ou crie um novo arquivo webhooks_controller.rb e implemente um método chamado # callback.

Não esqueça de adicionar mapeamento a routes.rb .

 post '/ webhooks / telegram_vbc43edbf1614a075954dvd4bfab34l1' => 'webhooks # callback' 

Seu WebhooksController será agora assim:

Quando o usuário envia uma mensagem para o nosso bot, ele acessa nosso callback WebhooksController # em um hash params ['webhook'] , que contém a mensagem e informações sobre o usuário que o enviou e etc.

Então, agora temos uma ação de controlador para receber mensagens recebidas.

Mas nós usamos um modelo de usuário que ainda não foi criado, vamos gerá-lo.

 rails g model User 

Abra nossa migração em db / migrate e substitua-a por este código:

PS Não se esqueça de adicionar uma validação de exclusividade para telegram_id na classe de modelo de usuário .

 validates_uniqueness_of: telegram_id 

Execute migrações então:

 bundle exec rake db: migrar 

O próximo passo é implementar uma classe Ruby simples que diferencie nossas mensagens e as responda corretamente de acordo com a etapa em que o usuário está agora. Então, para esses propósitos, precisamos criar uma classe chamada BotMessageDispatcher que terá uma lista de comandos disponíveis para o usuário.

Como estamos escrevendo um jogo de quest muito simples, precisamos definir um comando para cada etapa específica do nosso jogo. Mais uma coisa que precisamos fazer para que o nosso jogo funcione é lembrar em qual etapa o usuário está agora e não saltar entre etapas independentes.

Então, vamos decidir o que vamos fazer no nosso jogo de quests. Eu decidi ir com o jogo ' Torne-se um Rockstar ', que terá 3 passos simples:

1. Nasça.

2. Realize seu primeiro tutorial de Rails.

3. Escreva um blog em 15 minutos.

Você é um verdadeiro rockstar Rails!

Portanto, você não pode realizar nenhum tutorial do Rails sem ter nascido e também não pode escrever um blog em 15 minutos sem realizar nenhum tutorial do Rails. Portanto, precisamos tomar cuidado com isso e não permitir que o usuário pule para a etapa 2 sem realizar a etapa 1 e etc.

É aí que entra o armazenamento de estados. Vamos criar alguns métodos para o nosso modelo de usuário para obter o passo atual, o próximo passo, salvar o passo atual e etc.

Então, como você pode ver, implementamos alguns helpers muito úteis que nos ajudarão a armazenar e recuperar o estado do usuário do banco de dados. Aqui você pode ver a palavra bot_command , então, vamos construir nossa comunicação usuário / bot com abstrações representadas na classe Ruby simples chamada BotCommand .

Vamos criar uma classe base com funcionalidade básica e uma classe herdada para cada comando que precisamos.

Então, primeiro vamos implementar nosso BotMessageDispatcher, que saberá qual comando específico deve ser aplicado em qualquer momento da comunicação do usuário com bot.

Aqui está:

Aqui você pode ver uma matriz constante de todos os comandos que precisamos e um método chamado #process. Ele irá descobrir qual comando nosso usuário pode processar agora, salvá-lo e, em seguida, preparar o usuário para processar outro comando.

Portanto, temos um mecanismo para despachar mensagens, armazenar estados, descobrir qual comando precisamos executar em cada momento de comunicação entre usuários e bots. Portanto, o último passo de nossa implementação é implementar a classe BotCommand e uma classe separada para cada comando. Vamos fazer isso.

Nossa classe BotCommand irá realmente enviar mensagens para os usuários, então precisamos instalar uma gem Ruby para comunicação com o Telegram para fazer isso.

Apenas adicione esta linha ao seu Gemfile e faça um comando bundle install .

 gem 'telegrama-bot-rubi' 

Mais uma coisa que precisamos enviar mensagens é o nosso token de bot Telegram, então vamos adicioná-lo ao arquivo secrets.yml em uma chave chamada bot_token .

Para mim será:

Estamos prontos para ir!

Aqui está como sua classe de BotCommand :: Base se parecerá:

Aqui está. Nós temos uma classe base para o nosso comando abstract bot. Aqui temos um método para enviar mensagens e 2 métodos que precisam ser implementados em todas as outras classes de comando que serão herdadas da classe Base.

Então, vamos fazer isso. O primeiro comando é chamado Iniciar e é usado para acionar o bot do Telegram para iniciar a conversa com o usuário.

O próximo comando que precisamos implementar é a classe BotCommand :: Born .

Legal, nós nascemos, vamos tentar realizar o nosso primeiro tutorial do Rails.

Feito o tutorial, seu usuário já sabe muita coisa sobre o Rails. Vamos dar a ele a habilidade de escrever um blog e se tornar um rockstar do Rails.

O último passo que precisamos é implementar uma classe BotCommand :: Undefined que será acionada sempre que o bot não entender o comando que você enviou.

Parece que fizemos isso.

Como você pode ver, nossa arquitetura é bastante simples e muito flexível, então você pode alterá-la de acordo com suas necessidades.

Boa sorte na criação de bots úteis e obrigado por recomendar este artigo para seus amigos clicando no ícone 'coração' 🙂

Obter TODAS AS INFORMAÇÕES ÚTEIS sobre bots em um repositório incrível grátis no Github !

Texto original em inglês.