~ / tutoriais /tutorial-como-integrar-o-laravel-com-twilio-para-enviar-e-receber-mensagens-no-whatsapp $ _

Tutorial: Como Integrar o Laravel com Twilio para Enviar e Receber Mensagens no WhatsApp

Lucas Souza Lucas Souza 1 min de leitura Tutoriais
Tutorial: Como Integrar o Laravel com Twilio para Enviar e Receber Mensagens no WhatsApp

Criando uma Conta no Twilio e Pegando as Credenciais

Pra começar, você precisa de uma conta no Twilio. É bem simples: vai lá no site deles, cria sua conta e, assim que logar, você vai cair no painel principal. Não precisa mexer em nada no topo por enquanto, só desce a página até encontrar os Account Info. Lá você vai ver dois campos importantes: o Account SID e o Auth Token. Esses dois são o coração da integração, então anota eles com cuidado.

Link: https://twilio.com

Configurando o .env e o arquivo de Config

Depois de pegar essas credenciais, abre o arquivo .env da sua aplicação Laravel. Eu gosto de organizar tudo direitinho, então criei três variáveis no final do meu .env:

TWILIO_ACCOUNT_SID=seu_account_sid_aqui
TWILIO_AUTH_TOKEN=seu_auth_token_aqui
TWILIO_PHONE_NUMBER=numero_do_twilio

O TWILIO_PHONE_NUMBER a gente vai pegar mais pra frente, porque ele não vem dessa tela inicial — vamos usar o número do sandbox do Twilio pra testar.

Depois de preencher o .env, eu não acesso essas variáveis direto no código. Por quê? Porque, se você rodar um comando como php artisan optimize, o Laravel vai cachear tudo e o acesso direto ao .env pode quebrar. Então, eu criei um arquivo de configuração no diretório config chamado twilio.php. Ele é simples, só retorna um array com as configs:

<?php

return [
    'account_sid' => env('TWILIO_ACCOUNT_SID'),
    'auth_token' => env('TWILIO_AUTH_TOKEN'),
    'phone_number' => env('TWILIO_PHONE_NUMBER'),
];

Agora, no código, eu acesso essas variáveis com o helper config() assim: config('twilio.account_sid'). Fica mais seguro e organizado.

Configurando as Rotas

Beleza, com as credenciais no lugar, vamos configurar as rotas da nossa aplicação. Eu criei duas rotas no arquivo routes/api.php, porque vamos trabalhar com webhooks (comunicação entre o Twilio e nossa app via API). Aqui estão elas:

Route::post('/new-message', [MessageController::class, 'newMessage'])->name('new-message');
Route::post('/status', [MessageController::class, 'status'])->name('status');

A rota /new-message vai receber as mensagens enviadas pelo usuário no WhatsApp, e a /status vai pegar os status da mensagem (tipo "enviado", "entregue" ou "lido").

Expondo a Aplicação com o Expose

Como estamos desenvolvendo localmente, o Twilio não consegue acessar nossa aplicação direto no localhost. Pra resolver isso, eu uso o Expose, uma ferramenta massa do BeyondCode que cria um túnel seguro pra expor nossa app na internet. Se você não tem o Expose instalado, é só seguir o processo no site deles: https://expose.dev/docs/introduction

  1. Rode o comando de instalação: wget -qO- expose.dev/install.sh | bash.
  2. Dê permissão: chmod +x expose.
  3. Mova pra um diretório global: mv expose /usr/local/bin/.

Depois disso, pra expor minha aplicação, eu rodei:

expose share http://localhost:8888

O Expose vai te dar duas URLs: uma HTTP e outra HTTPS. Eu sempre pego a HTTPS pra garantir segurança. No meu caso, ficou algo como https://meu-tunel.expose.dev. Testei acessando no navegador e caiu direitinho na rota raiz da minha app. Agora, as rotas completas pra configurar no Twilio são:

Configurando o Sandbox do Twilio

Voltando pro Twilio, eu fui na seção Messaging > Try it out > Sandbox. Se é a primeira vez que você acessa, vai aparecer um QR code. Escaneia ele no WhatsApp do seu celular e envia a mensagem que eles pedem (no meu caso, foi join magic-automobile). Isso conecta seu número ao sandbox.

Depois disso, o Twilio atualiza a tela e mostra seu número no sandbox (começa com +1415..., por exemplo). Anota esse número e coloca no .env como TWILIO_PHONE_NUMBER. No meu .env, ficou assim:

TWILIO_PHONE_NUMBER=+14155238886

Agora, na mesma tela do sandbox, desce até Sandbox Settings. Em When a message comes in, cola a URL da rota new-message que o Expose te deu (no meu caso, https://meu-tunel.expose.dev/api/new-message). Em Status Callback URL, cola a rota status. Salva tudo e pronto, o Twilio já sabe pra onde mandar as mensagens e os status.

Testando a Chegada das Mensagens e Respondendo

Antes de ir pro código pesado, eu gosto de testar se os webhooks estão funcionando. Primeiro, instalei o SDK do Twilio:

sail composer require twilio/sdk

No meu MessageController, eu comecei com algo simples pra logar as requisições e já responder a mensagem:

use Twilio\Rest\Client;

public function newMessage(Request $request)
{
    // Validação simples pra garantir que é do Twilio
    if ($request->input('AccountSid') !== config('twilio.account_sid')) {
        return response('Unauthorized', 401);
    }

    // Log pra debug
    Log::build(['driver' => 'single', 'path' => storage_path('logs/twilio.log')])
        ->info(json_encode($request->all()));

    // Pegando a mensagem enviada
    $message = $request->input('Body');

    // Enviando uma resposta simples de volta
    $twilio = new Client(config('twilio.account_sid'), config('twilio.auth_token'));
    $twilio->messages->create(
        $request->input('From'), // Número de quem enviou
        [
            'from' => config('twilio.phone_number'),
            'body' => "Recebi sua mensagem: '$message'. Beleza, funcionou!",
        ]
    );

    return response('OK', 200);
}

public function status(Request $request)
{
    Log::build(['driver' => 'single', 'path' => storage_path('logs/twilio.log')])
        ->info("--- STATUS --- " . json_encode($request->all()));
    return response('OK', 200);
}

Depois, peguei meu celular, abri o WhatsApp e mandei um "teste" pro número do sandbox. Pra ver os logs em tempo real, rodei:

sail artisan logs -f

E olha só: a mensagem chegou direitinho no log! O payload tinha um campo Body com o texto "teste". Poucos segundos depois, recebi no WhatsApp a resposta: "Recebi sua mensagem: 'teste'. Beleza, funcionou!". Isso significa que o Twilio tá conversando com nossa app e enviando mensagens de volta sem problemas.

Monitorando os Status

No método status, eu deixei o log pra ver os status das mensagens:

public function status(Request $request)
{
    Log::build(['driver' => 'single', 'path' => storage_path('logs/twilio.log')])
        ->info("--- STATUS --- " . json_encode($request->all()));
    return response('OK', 200);
}

Quando a mensagem foi entregue, vi no log os status delivered e read. Isso mostra que a mensagem chegou no meu celular e eu abri ela. Se eu quisesse, poderia usar isso pra atualizar uma interface em tempo real (com Laravel Reverb, por exemplo), mas pra esse tutorial, só saber que tá chegando já é o suficiente.

Lucas Souza
Lucas Souza

{AI Engineer} — apaixonado por Laravel, arquitetura de software e construir produtos com impacto. Compartilho aqui tutoriais, descobertas e reflexões sobre o dia a dia de engenharia.

Você também pode gostar

VirguIA

beer & code assistant

conectando…

Não foi possível iniciar o chat agora.

tocando