wallacemartinss/filament-whatsapp-conector
Installation:
composer require wallacemartinss/filament-whatsapp-conector
php artisan vendor:publish --tag="filament-evolution-config"
php artisan vendor:publish --tag="filament-evolution-migrations"
php artisan migrate
Register Plugin:
Add to your PanelProvider:
FilamentEvolutionPlugin::make()->whatsappInstanceResource()
Configure .env:
EVOLUTION_URL=https://your-evolution-api.com
EVOLUTION_API_KEY=your_api_key
EVOLUTION_WEBHOOK_URL=https://your-app.com/api/webhooks/evolution
EVOLUTION_WEBHOOK_SECRET=your_secret_key
Start Queue Worker:
php artisan queue:work
First Use Case:
Create/Connect Instances: Use the Instances resource to manage WhatsApp connections. The QR code flow is automated via Livewire.
// Customize instance creation in a Filament page
FilamentEvolutionPlugin::make()
->whatsappInstanceResource()
->instanceSettings([
'reject_call' => true,
'always_online' => true,
]);
Multi-Tenancy: Enable tenancy in config:
'tenancy' => [
'enabled' => true,
'column' => 'tenant_id',
'model' => App\Models\Tenant::class,
],
Instances will auto-associate with the current tenant.
Filament Actions: Add to tables/pages/widgets:
// Basic action
SendWhatsappMessageAction::make()
->numberFrom('customer_phone') // Auto-fill from record
->instanceFrom('default_whatsapp_instance');
// Pre-filled with defaults
SendWhatsappMessageAction::make()
->number('551199999999')
->message('Your order #{{ $record->id }} is processing.')
->hideNumberInput();
Programmatic Sending: Use the facade in controllers/services:
Whatsapp::sendText($instanceId, '551199999999', 'Hello!');
Whatsapp::sendImage($instanceId, '551199999999', 'path/to/image.jpg', 'Check this!');
Service Integration: Extend your services with the trait:
class NotificationService {
use CanSendWhatsappMessage;
public function sendOrderConfirmation(Order $order) {
$this->sendWhatsappText(
$order->customer->phone,
"Your order #{$order->id} is confirmed!"
);
}
}
Route Webhooks:
Add to routes/api.php:
Route::post('/webhooks/evolution', [EvolutionWebhookController::class, 'handle']);
Log Webhook Events: Enable in config:
'storage' => [
'webhooks' => true,
],
View logs in WhatsApp > Webhook Logs.
Process Events: Listen for events in services:
event(new WhatsAppMessageReceived($messageData));
Buttons/List/CTA:
Whatsapp::sendButtons(
$instanceId,
'Choose an option:',
[
['type' => 'reply', 'title' => 'Yes', 'payload' => 'confirm'],
['type' => 'reply', 'title' => 'No', 'payload' => 'cancel'],
],
'Order Confirmation',
'Please confirm your order.'
);
Carousel:
$cards = [
[
'title' => 'Product 1',
'description' => 'Description 1',
'image' => 'https://example.com/image1.jpg',
'buttons' => [['type' => 'url', 'title' => 'Buy', 'url' => 'https://example.com']],
],
];
Whatsapp::sendCarousel($instanceId, 'Products', $cards);
Upload Media: Files are stored on the default disk (configurable per action):
SendWhatsappMessageAction::make()
->disk('s3'); // Override default disk
Use storage_path('app/filament-whatsapp') for local paths.
Cleanup:
Schedule cleanup in routes/console.php:
Schedule::command('evolution:cleanup')->daily();
Queue Jobs: Offload heavy operations (e.g., sending media) to queues:
Whatsapp::dispatchSendImage($instanceId, $number, $path, $caption);
Validation: Validate phone numbers before sending:
use WallaceMartinss\FilamentEvolution\Rules\ValidWhatsAppNumber;
$form->rules([
'phone' => ['required', new ValidWhatsAppNumber],
]);
Testing:
Use the WhatsAppFake facade for tests:
Whatsapp::fake();
Whatsapp::assertSentText('551199999999', 'Hello!');
QR Code Expiry:
EVOLUTION_QRCODE_EXPIRES (default: 30 seconds). Refresh if it times out..env or handle the QRCodeExpired exception in your code.Webhook Verification:
Route::post('/webhooks/evolution', function () {
return app(EvolutionWebhookMiddleware::class)->handle(...);
});
EVOLUTION_WEBHOOK_SECRET will cause webhooks to fail silently.Media Storage:
storage/app/filament-whatsapp by default.SendWhatsappMessageAction::make()->disk('s3');
Multi-Tenancy:
Rate Limiting:
TooManyRequestsException:
try {
Whatsapp::sendText($instanceId, $number, 'Message');
} catch (TooManyRequestsException $e) {
// Retry or notify admin
}
Interactive Messages:
supportsInteractiveMessages() method to verify:
if (Whatsapp::supportsInteractiveMessages($instanceId)) {
Whatsapp::sendButtons(...);
}
Webhook Failures:
'debug' => true,
ngrok for local testing).Message Not Delivered:
sent_at and status fields in the database (whatsapp_messages table).WhatsAppFacade::getMessageStatus() method to fetch status updates.QR Code Issues:
\Log::info('QR Code Data', ['data' => $instance->qr_code_data]);
Queue Stuck Jobs:
failed_jobs table.php artisan queue:retry all
Default Instance:
EVOLUTION_DEFAULT_INSTANCE in .env to avoid selecting an instance manually.Cleanup Policy:
How can I help you explore Laravel packages today?