[PARTE 3] Stealth: Adicionando fluxos ao seu chatbot

Esse é o terceiro post da série Criando chatbots com Stealth, veja a parte 1 e a parte 2. Você pode encontrar código completo deste projeto aqui.

Nesse post vamos tornar nosso chatbot mais útil e dar um significado para sua existência, neste exemplo vamos recriar, utilizando o Stealth, esse chatbot que criei usando o Chatfuel. Ele basicamente auxilia pessoas que estão em buscas de informações sobre um atrativo turístico, como por exemplo, como chegar, como funciona, quanto paga pra entrar, etc…

Esse vai ser nosso roadmap para criação do Chatbot:

  • Welcome Message: Mensagem de boas vindas, apresentada para novas interações;
  • Default Answer: Uma mensagem De fallback, para casos que o chatbot não entenda a intenção do usuário;
  • MAIN_MENU: Um menu principal que vai mostrar todas as opções que o usuário pode utilizar.
  • COMO_CHEGAR: Exibe informações de localização e rotas;
  • INFORMACOES GERAIS: Um roll de informações gerais como valor da entrada, taxas, avisos e outras informações úteis.
  • CARDAPIO: O cardápio com os lanches e refeições oferecidos no local.

Para organização de nosso projeto podemos dividi-los em dois módulos (ou flows como é a denominação do framework). Para simplificar vamos utilizar o flow Hello já existente em nosso projeto para adicionar as action: default_answer e main_menu . Vamos fazer uma adaptação aqui, nossowelcome_message se transformará em nossa action say_hello que tem o mesmo objetivo. O restante colocaremos no segundo flow que criaremos posteriormente.

Primeira coisa que deve ser feita é adicionar nossas actions no FlowMap que fica dentro da pasta config . O Stealth utiliza uma convenção de nomenclatura para as actions que eu sigo a maior parte do tempo, mas para o main_menu eu não usei, pois achei que não fazia muito sentido, mas a minha sugestão é: use sempre que puder.

Feito isso em nosso FlowMap, precisamos criar essas actions em nosso controller também.

Estamos fazendo todo esse procedimento manualmente, mas no próximo flow iremos utilizar o gerador que vem com o framework =).

Cada action já tem seu método send_replies , isso significa que quando essa action for chamada, ele vai buscar o conteúdo a ser enviado no arquivo replies de mesmo nome, então vamos criá-los.

Todos os arquivos replies ficam no diretório bot/replies/<nome_do_flow>s . Vamos começar com o say_welcome_message crie o arquivo bot/replies/hellos/say_welcome_message.yml e onde colocaremos nossa mensagem de boas vindas e um botão, com o texto “Começar”, que irá direcionar o usuário para o Menu principal (MAIN_MENU) do chatbot. O conteúdo seria algo assim:

Que no Facebook Messenger é exibida assim:

Agora precisamos fazer com que o nosso bot entenda quando o botão “Começar” seja acionado, para isso ele terá que processar o payload MAIN_MENU que é enviado.

Primeira coisa que deve ser feita é, verificar se o a opção “messaging_postbacks” (na seção Webhook ) está selecionada, caso não selecione-a.

Subscrever o evento messaging_postbacks
message_postback subscrito

Feito isso, ao acionar o botão “Começar” em nosso bot, receberemos o postback com o payload MAIN_MENU:

{“recipient”=>{“id”=>”758654081350020"}, “timestamp”=>1540480158132, “sender”=>{“id”=>”1730635526990816"}, “postback”=>{“payload”=>”MAIN_MENU”, “title”=>”Começar”}}

Vamos então adicionar a nosso BotController a capacidade de interpretar essa requisição. Sempre um payload é chega em nosso bot, a propriedade payload do objeto current_message recebe esse valor, vamos criar um handle ( handle_payloads) para agir nesses casos.

Nesse código vamos separar em métodos distintos as duas formas de interação do bot. Para as mensagens convencionais vamos utilizar o handle_messages e para os postbacks utilizaremos o método handle_payloads .

Utilizamos um case...when para tratar os payloads que chegam (essa é uma forma temporária e simplificada de trabalhar esses valores, nos próximos posts vamos mostrar como melhorar isso 😉 )

Então, caso o payload seja MAIN_MENU utilizaremos o método step_to para direcionar o usuário para o flow hello no state main_menu , caso nenhuma das alternativas seja satisfeita, o usuário é direcionado para a actionsay_hello .

Quando o usuário foi direcionado para o main_menu precisamo exibir as possíveis interações que ele pode fazer com o bot, a principio não vamos fazer como no Chatfuel, criando uma galeria (definida como Generic Template na documentação) para simplificar o procedimento vamos utilizar botões. Então nosso então criaremos um aquivo bot/replies/hellos/main_menu.yml e teremos como conteúdo:

main_menu.yml
Importante: O template de botões só permite no máximo 3 itens, caso esse limite não seja respeitado você receberá um erro #105 param name_place_holder[buttons] has too many elements .

Dessa forma assim que acionarmos o botão começar essa será a mensagem exibida:

Ótimo, nosso chatbot já está ganhando um fluxo bacana. Próximo passo é fazer esses 3 botões funcionarem, mantendo um bom fluxo e sinergia entre todo o restante do bot.

Vamos começar então criando um novo flow que irá conter essas informações, vamos chamá-lo de informations , pois vai conter essas sessões de nosso bot.

Como nosso bot é bem simples, estou criando esse flow genérico para conter essas informações. Para bots mais complexos o ideal é que você crie flow específicos para funcionalidades específicas, assim você mantem uma organização melhor de seu projeto.
bundle exec stealth generate flow informations

Isso irá gerar toda a estrutura de arquivos necessária para criação de um novo fluxo. Esse comando cria também algumas actions com códigos e replies de exemplos para iniciarmos a codificação mais facilmente.

Precisamos, então, alterar três actions, do exemplo gerado, para Como chegar (directions), informações gerais (general_informations) e o cardápio (menu) . Vamos começar pelo InformationsController:

Verifique se o CLI não gerou o nome do controller no singular

Substitua o conteúdo original por este com a implementação das 3 actions que iremos utiliza. Próximo passo é alterar nossa entrada no arquivo config/bot_flow.rb

Substitua todo o conteúdo gerado para o flow informations por esse exibido acima, aqui só mapeamos quais as actions contidas nesse flow. Próximo passo é criar nossas replies. Renomeie os arquivos dentro de bot/replies/informations/ para directions.yml, general.yml e menu.yml e coloque os seguintes conteúdos.

E por fim, precisamos instruir nosso bot a responder a cada botão, com a actions respectiva. Vamos fazer isso em nosso bot_controller.rb . Basicamente o que precisamos fazer é alterar nosso método handle_payloads para direcionar o fluxo para a respectiva action, ao receber o payload de cada botão.

Ok, eu sei que dá pra fazer isso de uma forma bem melhor, mas para ficar mais didática e visível o funcionamento, decidi fazer desta forma, a princípio, nos próximos posts iremos mostrar como criar um orquestrador de rotas bem mais eficiente.

É isso galera, agora vocês tem um bot com um fluxo estático básico completo, fica para os próximos posts então a melhoria no controle de fluxos, utilizar says, ask e get para trabalhar com entradas manuais do usuário e adicionar conteúdo dinâmico.

Até a próxima.

Outros posts da serie