callcocam/laravel-whatsapp-cloud
Composer 安装命令:
composer require callcocam/laravel-whatsapp-cloud
包简介
Núcleo reutilizável da WhatsApp Cloud API (Meta) para Laravel: envio de templates/sessão/interativo por-tenant, webhook com assinatura e eventos, e gestão de templates via Artisan.
README 文档
README
Núcleo reutilizável da WhatsApp Cloud API (Meta) para Laravel: envio de templates / texto de sessão / interativo por-tenant, webhook com assinatura e eventos, e gestão de templates via Artisan.
Extraído do núcleo Meta-only do Coordena. O pacote cuida do transporte + protocolo + ciclo de vida de template; o app cuida da regra de negócio + gatilhos + textos.
- Envio por intenção:
sendTemplate/sendSessionText/sendInteractive. - Multi-tenant: credenciais resolvidas por contrato (
WhatsApp::for($tenant)), com fallback pras credenciais default do config (dev/single-tenant). - Webhook GET (hub-challenge) + POST (assinatura
X-Hub-Signature-256), disparando eventos — sem regra de negócio dentro do pacote. - Templates: registry (config + runtime) e comandos
whatsapp:template:*. - Erros terminais da Meta mapeados (
isTemporaryRestriction()) pra você não re-tentar o que não adianta (janela de 24h fechada, template pausado, etc.).
Requisitos
- PHP
^8.3 - Laravel
^11.0 || ^12.0 || ^13.0
Instalação
Repositório Git privado, consumido via Composer:
// composer.json do app "repositories": [ { "type": "vcs", "url": "git@github.com:callcocam/laravel-whatsapp-cloud.git" } ]
composer require callcocam/laravel-whatsapp-cloud
php artisan whatsapp:install # publica config + migration e imprime o checklist
php artisan migrate
Onboarding de um projeto novo (6 passos)
composer require callcocam/laravel-whatsapp-cloud(com orepositories: vcs).php artisan whatsapp:install&&php artisan migrate..env:WHATSAPP_CLOUD_APP_SECRET,WHATSAPP_CLOUD_VERIFY_TOKEN,WHATSAPP_CLOUD_GRAPH_VERSION. Cadastre o número — use o model defaultWhatsAppNumberou implementeWhatsAppCredentialsno seu model + binde um resolver (veja Credenciais).- Declare os templates em
config/whatsapp-cloud.phpe crie-os na Meta comphp artisan whatsapp:template:create <nome>. - (Opcional) Ouça
WhatsAppMessageReceived/WhatsAppStatusReceived. - Envie:
WhatsApp::for($tenant)->sendTemplate('chave', [...params]);.
Uso
Enviar
use Callcocam\WhatsAppCloud\Facades\WhatsApp; use Callcocam\WhatsAppCloud\Messages\InteractiveMessage; use Callcocam\WhatsAppCloud\Messages\TemplateMessage; // Template aprovado (única forma fora da janela de 24h): WhatsApp::for($team)->sendTemplate('5548999999999', TemplateMessage::make('assignment', [ 'name' => 'Maria', 'event' => 'Congresso', 'url' => 'https://app.test/x', ])); // Texto livre (só dentro da janela de 24h): WhatsApp::for($team)->sendSessionText('5548999999999', 'Recebido, obrigado!'); // Pergunta com opções (lista interativa da Meta): WhatsApp::for($team)->sendInteractive('5548999999999', InteractiveMessage::multiChoice('Quando você pode?', ['Sexta à noite', 'Sábado de manhã']));
WhatsApp::for() sem argumento usa as credenciais default do config (dev /
single-tenant). Prefira injetar WhatsAppManager a usar a Facade em código
testável.
Tratar erros da Meta
use Callcocam\WhatsAppCloud\Exceptions\WhatsAppException; try { WhatsApp::for($team)->sendTemplate(...); } catch (WhatsAppException $e) { if ($e->isTemporaryRestriction()) { // Terminal (janela fechada, template pausado…): logue e NÃO re-tente. } // Senão: deixe a fila re-tentar (rate limit, rede). }
Templates
Declare cada chave de mensagem do app → template aprovado na Meta:
// config/whatsapp-cloud.php 'templates' => [ 'assignment' => [ 'name' => 'coordena_assignment', 'language' => 'pt_BR', 'category' => 'utility', 'params' => ['name', 'event', 'url'], // ordem de {{1}}, {{2}}, {{3}} ], ],
Ou em runtime:
use Callcocam\WhatsAppCloud\Templates\MetaTemplate; WhatsApp::registerTemplate('assignment', new MetaTemplate('coordena_assignment', 'pt_BR', 'utility', ['name', 'event', 'url']));
Credenciais (multi-tenant)
Implemente o contrato no seu model (ou use a trait) e binde um resolver:
use Callcocam\WhatsAppCloud\Contracts\WhatsAppCredentials; use Callcocam\WhatsAppCloud\Support\HasWhatsAppCredentials; class TeamWhatsappConnection extends Model implements WhatsAppCredentials { use HasWhatsAppCredentials; // lê phone_number_id, cloud_access_token, waba_id }
// AppServiceProvider::register() use Callcocam\WhatsAppCloud\Contracts\WhatsAppCredentialsResolver; $this->app->bind(WhatsAppCredentialsResolver::class, fn () => new class implements WhatsAppCredentialsResolver { public function resolve(mixed $context): ?WhatsAppCredentials { return $context instanceof \App\Models\Team ? $context->whatsappConnection : null; } });
Projeto novo que não quer escrever resolver: guarde os números no model default
WhatsAppNumber e binde o ModelCredentialsResolver (busca por key).
Webhook
O provider registra GET|POST {prefix} (default webhooks/whatsapp/cloud, no
grupo api — sem CSRF). Aponte o webhook da Meta pra essa URL. Para registrar
você mesmo, ponha whatsapp-cloud.webhook.enabled = false e mire o
WebhookController.
// Um listener no app: use Callcocam\WhatsAppCloud\Events\WhatsAppStatusReceived; Event::listen(function (WhatsAppStatusReceived $event) { logger()->info('status', ['id' => $event->status['id'], 'status' => $event->status['status']]); });
Eventos: WhatsAppMessageReceived, WhatsAppStatusReceived,
WhatsAppWebhookVerified.
Comandos Artisan
php artisan whatsapp:template:list # lista templates da WABA + status php artisan whatsapp:template:get <nome> # detalha um template php artisan whatsapp:template:create <nome> # cria na Meta a partir de um arquivo de definição php artisan whatsapp:template:send <nome> <to> ... # envia um template aprovado
Todos aceitam --tenant= (contexto pro resolver). O create lê
config('whatsapp-cloud.definitions_path')/<nome>.php (ou --path=), um arquivo
que retorna TemplateBuilder::...->toArray().
Configuração
Veja config/whatsapp-cloud.php: graph_version,
app_secret, verify_token, default (creds dev), webhook, model,
templates, definitions_path.
Testes
composer test # pint --test + phpstan + pest
Segurança
Nunca versione tokens. cloud_access_token fica encrypted no model; segredos
(app_secret, verify_token, tokens) só via .env.
Licença
MIT.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-07-08