Como Criar um Bot para o Facebook Messenger em PHP

Aqui no blog, eu já demonstrei como implementar um bot para o Telegram. Porém, existem outras plataformas que também suportam o desenvolvimento de bots, como é o caso do Messenger do Facebook. O Messenger já conta com uma série de bots das mais variadas funções.

Como não é possível saber qual plataforma é a que dominará o mercado de bots no futuro, é sempre bom conhecermos mais de uma, não é mesmo? Sendo assim, nesta postagem, eu irei demonstrar como implementar um bot para o Messenger em PHP.

A implementação de um bot para o Messenger pode ser feita, basicamente, seguindo quatro passos, os quais estão descritos nas seções abaixo.

1-Criar uma Página no Facebook

Todo bot a ser criado para o Messenger deve estar associado a uma página no Facebook. Dessa forma, nosso primeiro passo deve ser a criação da página. Caso você já possua uma página e deseja adicionar o bot a ela, pode pular para a próxima seção. xD

Para criar a página acesse: https://www.facebook.com/pages/create/. A imagem abaixo mostra a página que será aberta:

criar pagina facebook

Em seguida, escolha a categoria e dê um nome a sua página.

criar página facebook

Ao final de todo esse processo, a página irá ficar como a da imagem a seguir:

pagina loteria bot

2-Criar um App no Facebook

Com a página já criada, a segunda etapa é criar o app no Facebook que será responsável pela ligação entre a página e o código do nosso bot. Para criar um app no Facebook é necessário acessar o link https://developers.facebook.com/apps e clicar em “Adicionar um novo aplicativo”.

adicionar novo aplicativo

Ao clicar em “Adicionar um novo aplicativo”, será exibida uma janela igual a da imagem abaixo. Nessa janela, clique em “basic setup”.

criar app facebook

Na janela seguinte, preencha com o nome do bot, seu email de contato e escolha uma categoria.

new app facebook id

Feito isso, será exibida uma página com os detalhes do app recém-criado.

loterias bot app

3-Obter Access Token e Definir Webhook

Com o app criado, o próximo passo é obter o Access Token e definir o link do Webhook. Para isso, no menu no lado esquerdo da tela do app, clique em “Adicionar Produto”. Quando isso for feito, uma tela semelhante a da imagem abaixo será aberta. No tópico Messenger, clique em “Get Started”.

8

Na tela seguinte, clique em “Começar”.

messenger setup

Na seção “Geração de token”, escolha a página para a qual deseja gerar o token.

dashboard app facebook

Dê acesso às permissões que forem exigidas e, logo em seguida, você irá notar que o token será gerado no campo ao lado.

app facebook token

Após gerar o token, na seção Webhooks, clique em “Setup Webhooks”.

webhook

Ao abrir a janela, digite a URL que será usada como Webhook. É importante ressaltar que essa URL deve suportar HTTPS. Digite também um token para identificar o app e escolha as funcionalidades que você deseja integrar ao seu bot. Não clique em “Verificar e Salvar” ainda!

webhook dados

Quando você clica em “Verificar e Salvar”, o Facebook envia uma requisição para a URL inserida. Essa requisição precisa ser respondida pelo seu servidor. Dessa forma, é necessário que você crie um arquivo chamado “index.php” contendo o código abaixo:

O código acima serve para que Facebook valide o seu Webhook. Não vou entrar em detalhes de como essa validação é feita, mas ao acessar a documentação sobre Webhooks na Graph API, você poderá verificar como ocorre o processo e quais parâmetros são requisitados.

Feito isso, agora você pode clicar em “Verificar e Salvar”. Se tudo ocorrer bem, a seção “Webhooks” ficará igual a da foto abaixo:

webhook app

Para finalizar, você deve inscrever o app a uma página do Facebook. Sendo assim, selecione a página a qual o bot será associado.

4-Receber e Enviar Mensagens

Finalizadas as etapas anteriores, o passo final é implementarmos o código para processar as mensagens recebidas e respondê-las. Para isso, primeiramente, é preciso verificar na documentação do Facebook qual são os dados enviados ao Webhook quando uma mensagem é enviada ao chat da página associada ao bot. Esses dados são enviados ao Webhook no formato JSON, o qual pode ser visto no trecho de código abaixo:

No trecho de código acima é necessário dar atenção a três objetos: sender, recipient e message. O sender contém o ID do usuário que enviou a mensagem. O recipient contém o ID da página que recebeu a mensagem. Por sua vez, o objeto message contém o atributo text, o qual compreende o conteúdo da mensagem.

Agora que a estrutura do JSON recebido pelo Webhook já é conhecida, precisamos entender como fazer para responder a mensagem que foi recebida, ou seja, como o bot deve enviar a resposta ao usuário. Basicamente, a resposta também deve ser enviada em JSON para a seguinte URL:

https://graph.facebook.com/v2.6/me/messages?access_token=(SEU_ACCESS_TOKEN)

A estrutura do JSON a ser enviada através da URL acima poder ser vista no trecho de código a seguir:

Como é possível notar no código acima, o JSON precisa conter apenas o ID do emissor como recipient e o texto da mensagem a ser enviada ao usuário.

Agora que a estrutura dos JSON de recebimento e envio de mensagens já é conhecida, o próximo passo é implementar o bot para receber a mensagem e responder de acordo com o seu conteúdo. Para implementar o bot, eu me baseei no código em PHP do bot do tutorial para o Telegram. Sendo assim, o bot deste tutorial também irá informar os resultados das loterias da Caixa. O código completo do bot pode ser visto abaixo:

No código do bot existe o método processMessage. Esse método é responsável por manipular as mensagens recebidas pelo bot. Essas mensagens são obtidas por meio do JSON recebido via Webhook. Sendo assim, quando o método processMessage é chamado, ele verifica, a partir da mensagem recebida, qual loteria o usuário deseja saber o resultado e envia uma resposta.

As respostas às solicitações recebidas pelo bot são enviadas através do método sendMessage. Esse método recebe como parâmetro um array contendo o ID do emissor e o resultado da loteria escolhida. Antes de enviar a resposta, o método sendMessage converte o array em JSON.

A imagem abaixo mostra o bot construído neste tutorial funcionando. O usuário digita o nome da loteria (Ex: Quina) que deseja saber o resultado e o bot responde com os dados do último sorteio.

messenger bot funcionando

Bom, é isso! Espero que este tutorial ajude a criar vários bots úteis e legais. =]

Para conversar com o bot acesse: https://m.me/loteriasbot

Para visualizar o código-fonte do bot que foi desenvolvido neste tutorial, acesse: Messenger Bot.

Qualquer dúvida, deixa um comentário.

37 Comment

  1. Rangel R Morais says: Responder

    Só para confirmar: os dados ficam nesse arquivo parser.php, certo?

    1. Luiz Marcus Luiz Marcus says: Responder

      Oi, Rangel.
      Não, o arquivo parser.php faz a leitura da página do G1 para obter os resultados das loterias.

      1. sam says: Responder

        Esta desatualizado o código, certo?
        Fiz exatamente o que você compartilhou, mas meu chat não responde :(

        1. Luiz Marcus Luiz Marcus says: Responder

          Tudo blz, Samir?

          O código está correto. Inclusive, está rodando no bot que eu fiz como exemplo pra o post.
          Você está rodando o bot localmente ou em alguma hospedagem? Se estiver rodando localmente, vc tem que usar o código que está na parte 2 do post. Se for rodar em algum host, use o código da parte 3. O código que está no Github não é para ser usado localmente.

          Samir, desconsidere a parte em que eu mencionei outros posts. O post sobre bots para o Facebook Messenger é único, não possui outras partes. Mas, apenas confirmando, o código que está no post e no Github deve ser hospedado em algum host remoto, ele não funciona localmente.

          Espero ter ajudado e desculpe a confusão. =[

          1. Oyama says:

            Ola LUiz,

            Não entendi bem, qual é a “parte 2 do post” ? o.O

          2. Luiz Marcus Luiz Marcus says:

            Desculpa, Oyama.
            Eu me confundi, pensei que a dúvida era sobre o bot para o Telegram, o qual possui um post com 3 partes. O post sobre o bot para o Facebook Messenger não possui outras partes. xD

            Desculpa pela confusão.

          3. sam says:

            Obrigado pelo retorno Luiz, tudo certo graças a deus.
            Estou rodando o app em servidor https, conforme o facebook solicita e usando os arquivos de seu git, com os token que o facebook gerou ao criar o app na central developer. Mas sem sucesso ainda.

            Forte abraço.

          4. Luiz Marcus Luiz Marcus says:

            Samir,

            Lembre que o endereço que deve ser posto lá no painel do Facebook deve apontar para o arquivo “index.php”. Além disso, o BOT_TOKEN (gerado pelo Facebook) é diferente do VERIFY_TOKEN (você que define).
            Outra coisa, só você pode conversar com o seu bot no Messenger. Para que outras pessoas tenham acesso a ele, veja este post aqui do blog: Liberando Acesso ao Bot no Facebook Messenger

            Qualquer dúvida, é só falar.

    2. Ronny says: Responder

      el chat bot solo responde cuando uno es administrador de la pagina, si otro usuario de facebook escribe al chat bot no responde
      a que se debe esto me podrias ayudar ???

      1. Luiz Marcus Luiz Marcus says: Responder

        Sí, es normal que esto suceda. El bot está en modo de desarrollo.
        Para liberar el acceso de su bot a todos los usuarios, lea este post del blog:

        https://luizmarcus.com/php/liberando-acesso-ao-bot-no-facebook-messenger/

        El procedimiento es muy simple.

        Cualquier problema, comenta de nuevo =]

  2. Olá,
    Fiz, refiz, revisei, mas o bot não responde.
    A mensagem dá como entregue, mas nada.
    Estou rodando o app em servidor https, conforme o facebook solicita e usando os arquivos de seu git, com os BOT_TOKEN que o facebook gerou ao criar o app na central developer e VERIFY_TOKEN que eu defini.
    Se ativo a opção “Ativar respostas instantâneas” ele retorna o que configurei.
    Cleber

    1. Ah, o exemplo do Telegram funcionou perfeitamente.
      Obrigado.

      1. Luiz Marcus Luiz Marcus says: Responder

        E ae Cleber, blz?
        Eita, o negócio tá complicado. kkk
        Se o código do Telegram funcionou e o do Messenger não, acho que o problema não tá no código. Os códigos do dois bots são praticamente o mesmo, diferenciando apenas o endpoint de cada API.
        Seria interessante você verificar qual mensagem o Facebook está mandando para o seu bot quando o usuário fala com ele. Para isso, adicione o seguinte código no fonte do seu bot:

        $update_response = file_get_contents("php://input");//embaixo dessa linha
        $fh = fopen("saida.txt", "w+");
        fwrite($fh, $update_response);
        fclose($fh);

        Esse código vai salvar o JSON enviado pelo Facebook em um arquivo (saida.txt) no seu servidor. Fale com seu bot, ai o arquivo vai ser salvo. Depois disso, veja a estrutura do JSON e verifique se a implementação do bot está lendo os campos do JSON corretamente.

        Se não tiver problema no JSON, não sei mais o que pode ser. =[

        1. E aí!
          Infelizmente o arquivo é criado vazio, sem informação nenhuma.
          Testei estas linhas no código do Telegram e retorna os dados certinho.
          Tem mais alguma dica?

          1. Luiz Marcus Luiz Marcus says:

            Cleber, se não apareceu nada no arquivo é porque o Facebook não está enviado o JSON para você. Mas sobre esse problema, infelizmente, eu não tenho nenhuma solução no momento. =[
            Se conseguir resolver, por favor, depois comenta aqui. Pode ser que alguém mais tenha esse problema. =]

  3. Arnaldo says: Responder

    Olá Luiz, muito bom!
    Eu coloquei o arquivo saida.txt e vejo que o JSON está sendo armazenado corretamente. Entretanto, a resposta ao comando não aparece na janela de mensagem. O que pode estar errado?

    1. Luiz Marcus Luiz Marcus says: Responder

      Tudo blz, Arnaldo?

      Como o JSON está sendo armazenado corretamente, muito provavelmente, você não está tratando a resposta corretamente. Dá uma olhada no fonte do seu bot e verifique se os campos presentes no JSON estão sendo obtidos no código de forma correta. Pode ser que tenha algum errinho que está fazendo com que o bot obtenha algum campo errado e não responda.

      Caso o código esteja correto, veja se o Webhook foi setado corretamente. Vê se os token estão corretos também.

      Qualquer coisa, é só falar.

      1. Arnaldo says: Responder

        Exatamente isso! estava tratando a resposta de forma errada, agora está tudo bem. Muito obrigado mesmo, essa dica adiantou em muito o meu trabalho.

        1. Luiz Marcus Luiz Marcus says: Responder

          De nada, Arnaldo!

          Que bom que funcionou. Boa sorte com o trabalho! =]

  4. Victor says: Responder

    Olá, Luiz Marcus! Tudo bem?

    Sendo bem sincero contigo, copiei e colei o seu código. Quando eu fui fazer o teste pelo messenger através da minha página no facebook (criei uma página teste) eu digitei “Quina” e ele respondeu certinho. O problema é que agora o chatbot não para nunca mais de responder os números da Quina. Não sei de quantos em quantos segundos ele fica me respondendo o número da quina. Sabe o que pode ser?

    Valeu!

    1. Victor says: Responder

      Então. Limpei a conversa e dei um “oi” e ele me respondeu a Quina de novo! ;s

      1. Luiz Marcus Luiz Marcus says: Responder

        Blz, Victor!
        Por algum motivo a pilha de mensagens recebidas pelo seu bot não tá “andando”. Como você copiou o código, na linha file_get_contents("php://input");, o bot deveria pegar a ultima mensagem recebida. Tenta debugar o código no seu servidor pra ver como a mensagem chega ao seu bot. Infelizmente, não tenho solução pra esse problema. =[

        1. Victor says: Responder

          Então, não entendi! hahahah

          Não sei se fiz o procedimento correto que tu pediu(sou leigo), mas eu fiz um echo $update_response(variável que corresponde ao file_get_contents(“php://input”) e também fiz um console.log(que é a mesma coisa, mas mostra no meu console ao invés do localhost, que no meu caso estou usando através do Cloud9). Enfim, fiz isso e não apareceu nada na minha tela. E o mais doido é que agora não importa o que eu fale e sempre cai no else(Olá, sou um bot…), posso falar quina, mega-sena ou paralelepípedo que dá na mesma!

          Agora, o mais estranho: Criei um novo if (porque eu não quero um bot que mostre a loteria) apenas com a resposta para oi, olá e qualquer outra coisa e assim funciona! Em tese estou usando a mesma array e agora ele não trava. Veja o código abaixo:

          function processMessage($message) {
          // processa a mensagem recebida

          $sender = $message[‘sender’][‘id’];
          $text = $message[‘message’][‘text’];//texto recebido na mensagem

          if (isset($text)) {
          if ($text === “oi”) {
          sendMessage(array(‘recipient’ => array(‘id’ => $sender), ‘message’ => array(‘text’ => ‘Olá!’)));
          } else if ($text === “olá”) {
          sendMessage(array(‘recipient’ => array(‘id’ => $sender), ‘message’ => array(‘text’ => ‘Oiii!’)));
          } else {
          sendMessage(array(‘recipient’ => array(‘id’ => $sender), ‘message’ => array(‘text’ => ‘Não entendi! Repete!!!!!!!!!’)));
          }

          }
          }

          Se souber me dizer porque deste modo que fiz funciona já vai ajudar pra caramba. De qualquer modo, muito obrigado por responder!

          Abraço

          1. Luiz Marcus Luiz Marcus says:

            Agora é que eu não sei explicar mesmo, Victor. kkkk
            O código é praticamente o mesmo!
            Talvez, quando você mudou o if, coincidiu do servidor ter limpado as mensagens recebidas anteriormente e por isso ele passou a responder normalmente. Nunca usei o Cloud9 como servidor, por isso não tenho como dar uma ajuda mais efetiva. =[

            Abs.

  5. Victor says: Responder

    Eaí, Luiz Marcos! Eu mais uma vez. hehehe

    Tu já fizestes algum chatbot com utilização de banco de dados? Se sim, podemos trocar uma ideia por e-mail?

    Abração

    1. Luiz Marcus Luiz Marcus says: Responder

      E ae Victor! Bem vindo de volta kkkk
      Todos os bots que eu desenvolvi estão descritos e com código fonte disponível aqui no blog.
      Ainda não desenvolvi nenhum bot que faz uso de banco de dados. Mas se você quiser, pode me enviar um email que agente troca uma ideia.

  6. Junior Souza says: Responder

    Boa noite, Tudo bem?
    Eu vi que o teu bot esta funcionando perfeitamente… porém configurei tudo no facebook, validei o token e etc… mas quando chamo o PHP não recebe as mensagens enviadas, como recebo as mensagens enviadas para a bot/página?

    1. Luiz Marcus Luiz Marcus says: Responder

      E ae, Junior, blz?
      Esse seu problema pode ter varias causas. A URL que você ta setou para o bot faz uso do protocolo HTTPS? Outra possibilidade é que seu bot pode estar recebendo as mensagens mas não está conseguindo interpretar. Tentar inserir o seguinte código no fonte do seu bot:

      $update_response = file_get_contents(“php://input”);//embaixo dessa linha
      $fh = fopen(“saida.txt”, “w+”);
      fwrite($fh, $update_response);
      fclose($fh);

      Esse código vai salvar o JSON enviado pelo Facebook em um arquivo (saida.txt) no seu servidor. Fale com seu bot, ai o arquivo será salvo. Depois disso, veja a estrutura do JSON e verifique se a implementação do bot está lendo os campos do JSON corretamente.
      Lembre que para testar o bot, você deve falar com ele através da conta “dona” da página, uma vez que o bot tá em modo de desenvolvimento. Para liberar o acesso do bot ao público dá uma olhada nesse post: https://luizmarcus.com/php/liberando-acesso-ao-bot-no-facebook-messenger/

      Espero que as dicas ajudem. =]

  7. Olive says: Responder

    Buenas, Luiz!

    Se eu quisesse enviar uma imagem ao invés de texto, tu sabe como faria?

    Abração!

    1. Luiz Marcus Luiz Marcus says: Responder

      Buenas, Olive!
      Para enviar uma imagem invés do texto, você deve usar o método sendPhoto da API do Telegram.
      Eu pensei que sua dúvida era sobre a API de bots do Telegram e acabei respondendo errado. xD
      No Messenger, para o bot enviar uma imagem como anexo na mensagem, você precisa criar um objeto attachment no JSON a ser enviado pelo bot. Dá uma olhada no link abaixo:
      https://developers.facebook.com/docs/messenger-platform/send-messages#sending_attachments
      Esse link te leva direto para a parte da documentação do Messenger que fala a respeito de anexos nas mensagens. Nele tem um modelo de JSON que você pode seguir.

      Desculpa pelo erro. Qualquer dúvida, é só falar. =]

  8. Qual a melhor forma de armazenar jSON sendo que posso precisar passar variaveis no jSON? Pergunto porque os jSON’s de botões e imagens são bem grandes, e o editor que uso (ATOM) não lê jSON dentro do PHP (Isso gera dificuldade para identificar o fechamento dos }]).

    1. Luiz Marcus Luiz Marcus says: Responder

      E ae Ronny, blz?
      Acho que uma solução, em PHP, para o seu problema seria salvar as informações em um array e depois transformar em JSON. Dessa forma, você monta o array com os parâmetros e passando as suas variáveis, e ao enviar, transforma em JSON
      usando o método json_encode do PHP.
      Trabalhar com JSON no formato de string é complicado, usando o array seu código fica bem mais legível. =)

  9. Obrigado Luiz, mas não tenho tanta experiencia com ARRAY’s, teria algum tutorial de como montar a estrutura do ARRAY para converter JSON?

  10. Nada como a pratica para resolver, é um pouco chato montar a estrutura, mas estou conseguindo. Vou prosseguir com os estudos. Obrigado.

    array(‘id’ => ‘sender’),
    ‘message’ => array(
    “text” => ‘O chatbot para atendimento web via Facebook Messenger.’,
    “quick_replies” => array(
    array(“content_type” => “text”,”title” => “Sobre”,”payload” => “Sobre”),
    array(“content_type” => “text”,”title” => “Mais Informações”,”payload” => “MaisInfo”),
    ),
    )
    );

    print json_encode($a1,JSON_PRETTY_PRINT);
    ?>

    {
    “recipient”: {
    “id”: “sender”
    },
    “message”: {
    “text”: “O chatbot para atendimento web via Facebook Messenger.”,
    “quick_replies”: [
    {
    “content_type”: “text”,
    “title”: “Sobre”,
    “payload”: “Sobre”
    },
    {
    “content_type”: “text”,
    “title”: “Mais Informa\u00e7\u00f5es”,
    “payload”: “MaisInfo”
    }
    ]
    }
    }

    1. Luiz Marcus Luiz Marcus says: Responder

      É isso ai, Rony! É bem por ai.
      No código do bot para o Messenger que eu disponibilizei no GitHub tem um exemplo de como implementar. Depois dá uma olhada lá:
      https://github.com/luizmarcus/PHP/tree/master/messengerbot
      Você também pode procurar posts relacionados a esse assunto no Stack Overflow.
      Boa sorte!

  11. Peguei esse exemplo mesmo e estou implementando Luiz, estou estudando aos poucos como tudo funciona, mas já consegui colocar o persistent_menu e até usar o mesmo app em duas páginas diferentes.

    Você saberia me dizer como funciona o processo de enviar mensagem em massa para as pessoas que já acessaram o bot? É salvando os id’s em banco de dados?

    1. Luiz Marcus Luiz Marcus says: Responder

      Massa, Ronny. Tá progredindo! =]
      Essa parte de envio em massa de mensagens eu nunca fiz, mas a sua ideia de salvar o ids num banco de dados é boa. Salvando num BD, você pode usar os ids quando quiser.
      Só cuidado pra esses envios em massa não ficarem chatos. Seria massa se você desse a opção do usuário poder cancelar o recebimento dessa mensagem.
      Boa sorte!

Deixe uma resposta