lucasgiovanni / laravel-whatsapp
Integração Laravel com API WhatsApp
Requires
- php: ^8.0
- illuminate/config: ^10.0|^12.0
- illuminate/console: ^10.0|^12.0
- illuminate/database: ^10.0|^12.0
- illuminate/events: ^10.0|^12.0
- illuminate/http: ^10.0|^12.0
- illuminate/queue: ^10.0|^12.0
- illuminate/support: ^10.0|^12.0
- nesbot/carbon: ^2.67|^3.0
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.0|^10.0
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2025-03-28 13:25:22 UTC
README
Integração robusta entre Laravel e API WhatsApp Node.js com suporte a recursos avançados como tokens de atualização, circuit breaker, rastreamento de correlação, transações atômicas e muito mais.
Instalação
Instale o pacote via Composer:
composer require lucasgiovanni/laravel-whatsapp
Publicar configurações
php artisan vendor:publish --provider="LucasGiovanni\LaravelWhatsApp\LaravelWhatsAppServiceProvider" --tag="config"
Configuração
Ajuste as configurações em config/whatsapp.php
ou defina as variáveis de ambiente no arquivo .env
:
WHATSAPP_API_URL=http://localhost:3000
WHATSAPP_API_KEY=sua-api-key
WHATSAPP_DEFAULT_SESSION=default
Recursos principais
Autenticação avançada
O pacote oferece um sistema de autenticação com tokens de atualização para manter a segurança e evitar expiração:
use LucasGiovanni\LaravelWhatsApp\Facades\WhatsApp; // Autenticar e obter tokens $tokens = WhatsApp::authenticate(); // array('access_token' => '...', 'refresh_token' => '...', 'expires_in' => 3600) // Renovar tokens $newTokens = WhatsApp::refreshToken($refreshToken); // Definir token para requisições WhatsApp::withToken($accessToken)->sendText('5548999998888', 'Olá!');
Rastreamento entre sistemas
O pacote oferece ID de correlação para rastrear requisições entre sistemas:
// Definir ID de correlação $result = WhatsApp::withCorrelationId('seu-id-unico') ->sendText('5548999998888', 'Olá!'); // Obter logs pelo ID de correlação $logs = WhatsApp::getLogsByCorrelationId('seu-id-unico');
Transações atômicas
Garanta a atomicidade de operações complexas:
// Iniciar transação $transactionId = WhatsApp::beginTransaction(); try { // Enviar múltiplas mensagens na mesma transação WhatsApp::withTransaction($transactionId) ->sendText('5548999998888', 'Primeira mensagem'); WhatsApp::withTransaction($transactionId) ->sendText('5548999998888', 'Segunda mensagem'); // Confirmar transação WhatsApp::commitTransaction($transactionId); } catch (\Exception $e) { // Reverter em caso de falha WhatsApp::rollbackTransaction($transactionId); throw $e; }
Utilizando o Circuit Breaker
Proteja seu sistema contra falhas em cascata:
use LucasGiovanni\LaravelWhatsApp\Services\CircuitBreakerService; // Injetar o serviço public function __construct(CircuitBreakerService $circuitBreaker) { $this->circuitBreaker = $circuitBreaker; } // Executar operação protegida $result = $this->circuitBreaker->execute('whatsapp-api', function () { return WhatsApp::sendText('5548999998888', 'Mensagem protegida por circuit breaker'); }, function () { // Fallback em caso de falha return ['success' => false, 'message' => 'Serviço indisponível']; });
Envio de mensagens
O pacote suporta diversos tipos de mensagens para atender a todas as necessidades:
Mensagem de texto
// Mensagem de texto simples WhatsApp::sendText( '5548999998888', // Número do destinatário 'Olá, como vai?', // Texto da mensagem [ // Opções adicionais (opcional) 'priority' => 'high', // Prioridade: high, medium, low 'delay' => 0, // Atraso em segundos 'quoted_message_id' => '12345' // ID da mensagem que está sendo respondida ], 'default' // ID da sessão (opcional) );
Mensagem com template
// Mensagem com template WhatsApp::sendTemplate( '5548999998888', // Número do destinatário 'boas_vindas', // Nome do template [ // Dados para o template 'name' => 'João', 'company' => 'LucasGiovanni' ], 'default' // ID da sessão (opcional) );
Mensagem com imagem
// Enviar uma imagem WhatsApp::sendImage( '5548999998888', // Número do destinatário 'https://exemplo.com/imagem.jpg', // URL da imagem 'Veja esta imagem incrível!', // Legenda (opcional) 'default' // ID da sessão (opcional) );
Mensagem com arquivo/documento
// Enviar um arquivo/documento WhatsApp::sendFile( '5548999998888', // Número do destinatário 'https://exemplo.com/contrato.pdf', // URL do arquivo 'Contrato.pdf', // Nome do arquivo (opcional) 'default' // ID da sessão (opcional) );
Mensagem com áudio
// Enviar um áudio WhatsApp::sendAudio( '5548999998888', // Número do destinatário 'https://exemplo.com/audio.mp3', // URL do áudio 'default' // ID da sessão (opcional) );
Mensagem com mídia genérica
// Enviar mídia genérica (imagem, vídeo, documento, áudio) WhatsApp::sendMedia( '5548999998888', // Número do destinatário 'https://exemplo.com/video.mp4', // URL da mídia 'video', // Tipo: image, video, document, audio 'Veja este vídeo!', // Legenda (opcional) 'default' // ID da sessão (opcional) );
Mensagem com localização
// Enviar localização WhatsApp::sendLocation( '5548999998888', // Número do destinatário -27.5969, // Latitude -48.5495, // Longitude 'LucasGiovanni', // Título (opcional) 'default' // ID da sessão (opcional) );
Mensagem com contato
// Enviar contato WhatsApp::sendContact( '5548999998888', // Número do destinatário [ // Dados do contato 'name' => [ 'first_name' => 'João', 'last_name' => 'Silva', 'formatted_name' => 'João Silva' ], 'phones' => [ [ 'phone' => '+5548999997777', 'type' => 'CELL' ] ], 'emails' => [ [ 'email' => 'joao@example.com', 'type' => 'WORK' ] ] ], 'default' // ID da sessão (opcional) );
Mensagem com botões
// Enviar mensagem com botões WhatsApp::sendButtons( '5548999998888', // Número do destinatário 'Escolha uma opção:', // Texto principal [ // Lista de botões [ 'id' => 'btn1', 'text' => 'Sim' ], [ 'id' => 'btn2', 'text' => 'Não' ], [ 'id' => 'btn3', 'text' => 'Talvez' ] ], 'default' // ID da sessão (opcional) );
Mensagem com lista de opções
// Enviar lista de opções WhatsApp::sendList( '5548999998888', // Número do destinatário 'Cardápio do dia', // Título 'Escolha seu prato', // Descrição 'Ver opções', // Texto do botão [ // Seções da lista [ 'title' => 'Pratos principais', 'rows' => [ ['id' => 'p1', 'title' => 'Feijoada', 'description' => 'Porção completa'], ['id' => 'p2', 'title' => 'Lasanha', 'description' => 'De carne'] ] ], [ 'title' => 'Sobremesas', 'rows' => [ ['id' => 's1', 'title' => 'Pudim', 'description' => 'Tradicional'], ['id' => 's2', 'title' => 'Sorvete', 'description' => 'De chocolate'] ] ] ], 'default' // ID da sessão (opcional) );
Mensagem com enquete
// Enviar enquete WhatsApp::sendPoll( '5548999998888', // Número do destinatário 'Qual sua cor favorita?', // Pergunta [ // Opções 'Azul', 'Verde', 'Vermelho', 'Amarelo' ], false, // Permitir múltipla escolha 'default' // ID da sessão (opcional) );
Mensagem com produto
// Enviar produto do catálogo WhatsApp::sendProduct( '5548999998888', // Número do destinatário 'cat123', // ID do catálogo 'prod456', // ID do produto 'default' // ID da sessão (opcional) );
Mensagem com catálogo
// Enviar catálogo de produtos WhatsApp::sendCatalog( '5548999998888', // Número do destinatário 'cat123', // ID do catálogo [ // Lista de produtos (opcional) 'prod456', 'prod789' ], 'default' // ID da sessão (opcional) );
Mensagem com pedido
// Enviar pedido WhatsApp::sendOrder( '5548999998888', // Número do destinatário [ // Dados do pedido 'catalog_id' => 'cat123', 'items' => [ [ 'product_id' => 'prod456', 'quantity' => 2, 'price' => 1990 ], [ 'product_id' => 'prod789', 'quantity' => 1, 'price' => 2490 ] ], 'customer_details' => [ 'name' => 'João Silva', 'address' => 'Rua Exemplo, 123' ] ], 'default' // ID da sessão (opcional) );
Agendamento de mensagens
// Agendar uma mensagem WhatsApp::scheduleMessage([ 'type' => 'text', 'to' => '5548999998888', 'message' => 'Lembrete: Reunião às 15h', 'schedule_time' => '2023-12-31T15:00:00Z', 'options' => [ 'priority' => 'medium' ] ]); // Cancelar uma mensagem agendada WhatsApp::cancelScheduledMessage('message_id_123');
Webhooks
Configure webhooks para receber eventos do WhatsApp:
// Registrar webhook WhatsApp::registerWebhook( 'https://seu-site.com/api/whatsapp/webhook', ['message', 'message_ack', 'group_join'] ); // Listar webhooks $webhooks = WhatsApp::listWebhooks(); // Remover webhook WhatsApp::removeWebhook('https://seu-site.com/api/whatsapp/webhook');
Manipular eventos de webhook
// Em app/Http/Controllers/WhatsAppWebhookController.php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; class WhatsAppWebhookController extends Controller { public function handle(Request $request) { $payload = $request->all(); $event = $payload['event'] ?? 'unknown'; Log::info("Webhook WhatsApp recebido: {$event}", [ 'correlation_id' => $request->header('X-Correlation-ID'), 'payload' => $payload ]); // Processar o evento de acordo com o tipo switch ($event) { case 'message': // Processar mensagem recebida break; case 'message_ack': // Processar confirmação de entrega break; // outros eventos... } return response()->json(['success' => true]); } }
Filas e Jobs
Para processamento assíncrono:
use LucasGiovanni\LaravelWhatsApp\Jobs\ProcessWhatsAppJob; // Agendar envio de mensagem ProcessWhatsAppJob::dispatch('send-text', [ 'to' => '5548999998888', 'message' => 'Mensagem agendada', 'options' => [ 'priority' => 'medium', ] ], [ 'attempts' => 3, 'delay' => 60, // segundos 'correlation_id' => 'job-123', 'priority' => 'high' ]);
Middleware
Correlation ID Middleware
Adicione o middleware no seu app/Http/Kernel.php
:
protected $middlewareGroups = [ 'api' => [ // ... \LucasGiovanni\LaravelWhatsApp\Middleware\CorrelationIdMiddleware::class, ], ];
Este middleware adiciona automaticamente um ID de correlação para todas as requisições.
Comandos Artisan
# Configurar webhook php artisan whatsapp:setup-webhook https://seu-site.com/api/whatsapp/webhook # Limpar transações expiradas php artisan whatsapp:cleanup-transactions --older-than=60
Tratamento de Erros
use LucasGiovanni\LaravelWhatsApp\Exceptions\WhatsAppException; try { WhatsApp::sendText('5548999998888', 'Olá!'); } catch (WhatsAppException $e) { // Tratar erro específico da API WhatsApp report($e); return response()->json(['error' => $e->getMessage()], $e->getCode()); } catch (\Exception $e) { // Tratar outros erros report($e); return response()->json(['error' => 'Erro interno do servidor'], 500); }
Integração com Laravel Sanctum
Adicione suporte ao Laravel Sanctum:
// config/whatsapp.php 'sanctum' => [ 'enabled' => true, 'proxy_url' => '/api/whatsapp/proxy', ],
Verifica tokens do Sanctum:
// Verificar token Sanctum e autenticar com API $result = WhatsApp::verifySanctumToken($sanctumToken);
Testes
composer test
Licença
Este pacote é open-source e licenciado sob a Licença MIT.