wallacemartinss/filament-whatsapp-conector

Filament plugin for WhatsApp integration with Evolution API v2

Installs: 6

Dependents: 1

Suggesters: 0

Security: 0

Stars: 4

Watchers: 0

Forks: 1

Open Issues: 0

pkg:composer/wallacemartinss/filament-whatsapp-conector

v1.0.0 2025-12-08 01:21 UTC

This package is auto-updated.

Last update: 2025-12-08 01:27:03 UTC


README

Latest Version on Packagist Total Downloads

A Filament v4 plugin for WhatsApp integration using Evolution API v2.

Features

  • 🔌 Easy Integration - Connect your WhatsApp with Evolution API v2
  • 🏢 Multi-Tenancy - Full support for Filament's native multi-tenancy
  • 📱 QR Code Connection - Real-time QR code display with countdown timer
  • 📨 Webhook Support - Receive events from Evolution API (messages, connection updates, etc.)
  • 💬 Message Sending - Send text, images, videos, audio, documents and more
  • 🎯 Filament Action - Ready-to-use action for sending messages from anywhere
  • 🔧 Service Trait - Easily integrate message sending into your own services
  • 🔐 Secure - Credentials stored in config/env, never in database
  • 🎨 Filament v4 Native - Beautiful UI with Filament components and Heroicons
  • 🌍 Translations - Full i18n support (English and Portuguese included)
  • Real-time - Livewire-powered components with Alpine.js countdown

Requirements

  • PHP 8.2+
  • Laravel 11+
  • Filament v4
  • Evolution API v2 instance

Installation

Step 1: Install via Composer

composer require wallacemartinss/filament-whatsapp-conector

Step 2: Publish Configuration

php artisan vendor:publish --tag="filament-evolution-config"

Step 3: Run Migrations

php artisan vendor:publish --tag="filament-evolution-migrations"
php artisan migrate

Step 4: Register the Plugin

Add the plugin to your Filament Panel Provider:

use WallaceMartinss\FilamentEvolution\FilamentEvolutionPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            FilamentEvolutionPlugin::make(),
        ]);
}

Step 5: Configure Tailwind CSS

Add the plugin's views and source files to your Filament theme CSS file (e.g., resources/css/filament/admin/theme.css):

@import '../../../../vendor/filament/filament/resources/css/theme.css';

@source '../../../../app/Filament/**/*';
@source '../../../../resources/views/filament/**/*';

/* Add these lines for Filament Evolution */
@source '../../../../vendor/wallacemartinss/filament-evolution/resources/views/**/*';
@source '../../../../vendor/wallacemartinss/filament-evolution/src/**/*';

Then rebuild your assets:

npm run build

Plugin Options

You can customize which resources are available in the panel:

FilamentEvolutionPlugin::make()
    ->viewMessageHistory()    // Enable message history resource
    ->viewWebhookLogs()       // Enable webhook logs resource
Method Default Description
whatsappInstanceResource(bool) true Show/hide the WhatsApp Instances resource
viewMessageHistory(bool) false Show/hide the Message History resource
viewWebhookLogs(bool) false Show/hide the Webhook Logs resource

Example: Full Configuration

FilamentEvolutionPlugin::make()
    ->whatsappInstanceResource()  // Show instances (default: true)
    ->viewMessageHistory()        // Show message history
    ->viewWebhookLogs()           // Show webhook logs

Configuration

Environment Variables (.env)

Only API credentials should be in your .env file:

# Evolution API Connection (Required)
EVOLUTION_URL=https://your-evolution-api.com
EVOLUTION_API_KEY=your_api_key

# Webhook URL (Required for receiving events)
EVOLUTION_WEBHOOK_URL=https://your-app.com/api/evolution/webhook

# Webhook Secret (Optional - for security)
EVOLUTION_WEBHOOK_SECRET=your_secret_key

# Default Instance (Optional - for single instance setups)
EVOLUTION_DEFAULT_INSTANCE=your_instance_id

Step 6: Start the Queue Worker

The plugin uses Laravel queues to process webhooks and send messages. Make sure you have a queue worker running:

php artisan queue:work

For production, use a process manager like Supervisor to keep the worker running. See the Laravel Queue Documentation for more details.

Config File

All other settings are in config/filament-evolution.php. Publish and customize:

php artisan vendor:publish --tag="filament-evolution-config"

Key configuration options:

// config/filament-evolution.php

return [
    // Queue settings
    'queue' => [
        'enabled' => true,
        'connection' => null,  // null = default connection
        'name' => 'default',   // queue name
    ],

    // Storage settings
    'storage' => [
        'webhooks' => true,    // save webhooks to database
        'messages' => true,    // save messages to database
    ],

    // Cleanup policy (automatic deletion of old records)
    'cleanup' => [
        'webhooks_days' => 30, // delete webhooks older than 30 days
        'messages_days' => 90, // delete messages older than 90 days
    ],

    // Instance defaults
    'instance' => [
        'reject_call' => false,
        'always_online' => false,
        // ...
    ],

    // Multi-tenancy
    'tenancy' => [
        'enabled' => false,
        'column' => 'team_id',
        'table' => 'teams',
        'model' => 'App\\Models\\Team',
    ],
];

Cleanup Command

The plugin includes a cleanup command to remove old records:

# Run cleanup with config settings
php artisan evolution:cleanup

# Preview what would be deleted (dry run)
php artisan evolution:cleanup --dry-run

# Override config settings
php artisan evolution:cleanup --webhooks-days=7 --messages-days=30

Scheduling Cleanup

Add to your routes/console.php:

use Illuminate\Support\Facades\Schedule;

Schedule::command('evolution:cleanup')->daily();

Instance Management

Creating an Instance

  1. Navigate to WhatsApp > Instances
  2. Click New Instance
  3. Fill in the instance name and phone number
  4. Configure settings (reject calls, always online, etc.)
  5. Click Save - the QR Code modal will open automatically
  6. Scan the QR Code with your WhatsApp

Instance Settings

Setting Description
Reject Calls Automatically reject incoming calls
Message on Call Message sent when rejecting calls
Ignore Groups Don't process messages from groups
Always Online Keep WhatsApp status as online
Read Messages Automatically mark messages as read
Read Status Automatically view status updates
Sync Full History Sync all message history on connection

Sending Messages

The plugin provides three ways to send WhatsApp messages:

  1. Filament Action - For UI-based sending in tables, pages and widgets
  2. Whatsapp Facade - For quick message sending anywhere
  3. CanSendWhatsappMessage Trait - For integration into your services

1. Using the Filament Action

The SendWhatsappMessageAction can be used in any Filament page, resource, or widget.

Basic Usage

use WallaceMartinss\FilamentEvolution\Actions\SendWhatsappMessageAction;

// In a table
public function table(Table $table): Table
{
    return $table
        ->actions([
            SendWhatsappMessageAction::make(),
        ]);
}

// In a page header
protected function getHeaderActions(): array
{
    return [
        SendWhatsappMessageAction::make(),
    ];
}

Pre-filling Values

SendWhatsappMessageAction::make()
    ->number('5511999999999')              // Default phone number
    ->instance($instanceId)                 // Default instance
    ->message('Hello World!')               // Default message

Using with Table Records

Get the phone number automatically from the record:

// Using attribute name
SendWhatsappMessageAction::make()
    ->numberFrom('phone'),

// Using dot notation for relationships
SendWhatsappMessageAction::make()
    ->numberFrom('contact.phone'),

// Using closure for custom logic
SendWhatsappMessageAction::make()
    ->numberFrom(fn ($record) => $record->celular ?? $record->telefone),

// Also set instance from record
SendWhatsappMessageAction::make()
    ->numberFrom('phone')
    ->instanceFrom('whatsapp_instance_id'),

Hiding Form Fields

SendWhatsappMessageAction::make()
    ->hideInstanceSelect()     // Hide instance selector
    ->hideNumberInput()        // Hide phone number input
    ->textOnly()               // Only allow text messages (hide file upload)

Limiting Message Types

use WallaceMartinss\FilamentEvolution\Enums\MessageTypeEnum;

SendWhatsappMessageAction::make()
    ->allowedTypes([
        MessageTypeEnum::TEXT,
        MessageTypeEnum::IMAGE,
    ]);

Custom Storage Disk

SendWhatsappMessageAction::make()
    ->disk('s3')   // Use S3 for file uploads

2. Using the Whatsapp Facade

For programmatic message sending from anywhere in your application:

use WallaceMartinss\FilamentEvolution\Facades\Whatsapp;

// Send text
Whatsapp::sendText($instanceId, '5511999999999', 'Hello!');

// Send image with caption
Whatsapp::sendImage($instanceId, '5511999999999', 'path/to/image.jpg', 'Check this out!');

// Send video with caption
Whatsapp::sendVideo($instanceId, '5511999999999', 'path/to/video.mp4', 'Watch this!');

// Send audio
Whatsapp::sendAudio($instanceId, '5511999999999', 'path/to/audio.mp3');

// Send document
Whatsapp::sendDocument($instanceId, '5511999999999', 'path/to/file.pdf', 'report.pdf', 'Monthly Report');

// Send location
Whatsapp::sendLocation($instanceId, '5511999999999', -23.5505, -46.6333, 'My Office', 'São Paulo, SP');

// Send contact card
Whatsapp::sendContact($instanceId, '5511999999999', 'John Doe', '+5511888888888');

// Generic send method
Whatsapp::send($instanceId, '5511999999999', 'text', 'Hello World!');
Whatsapp::send($instanceId, '5511999999999', 'image', 'path/to/image.jpg', ['caption' => 'Nice!']);

3. Using the Trait in Your Services

Add the CanSendWhatsappMessage trait to integrate message sending into your business logic:

use WallaceMartinss\FilamentEvolution\Concerns\CanSendWhatsappMessage;

class InvoiceService
{
    use CanSendWhatsappMessage;

    public function sendPaymentReminder(Invoice $invoice): void
    {
        $this->sendWhatsappText(
            $invoice->customer->phone,
            "Hello {$invoice->customer->name}, your invoice #{$invoice->number} is due on {$invoice->due_date->format('d/m/Y')}."
        );
    }

    public function sendInvoicePdf(Invoice $invoice): void
    {
        $this->sendWhatsappDocument(
            $invoice->customer->phone,
            $invoice->pdf_path,
            "invoice-{$invoice->number}.pdf",
            "Your invoice is ready!"
        );
    }

    public function sendPromoImage(Customer $customer, string $imagePath): void
    {
        $this->sendWhatsappImage(
            $customer->phone,
            $imagePath,
            "Special promotion just for you! 🎉"
        );
    }
}

Available Trait Methods

Method Description
sendWhatsappText($number, $message) Send text message
sendWhatsappImage($number, $path, $caption) Send image
sendWhatsappVideo($number, $path, $caption) Send video
sendWhatsappAudio($number, $path) Send audio
sendWhatsappDocument($number, $path, $fileName, $caption) Send document
sendWhatsappLocation($number, $lat, $lng, $name, $address) Send location
sendWhatsappContact($number, $contactName, $contactNumber) Send contact card
sendWhatsappMessage($number, $type, $content, $options) Generic send method
hasWhatsappInstance() Check if an instance is available
getConnectedWhatsappInstances() Get all connected instances

Customizing the Instance Selection

Override getWhatsappInstanceId() to use a specific instance:

class TenantInvoiceService
{
    use CanSendWhatsappMessage;

    protected function getWhatsappInstanceId(): ?string
    {
        // Use tenant's specific WhatsApp instance
        return auth()->user()->tenant->whatsapp_instance_id;
    }
}

Storage Support

The plugin supports both local and cloud storage (S3, etc.) for media files.

Configuration

EVOLUTION_MEDIA_DISK=public
EVOLUTION_MEDIA_DIRECTORY=whatsapp-media
EVOLUTION_MEDIA_MAX_SIZE=16384

Using Different Disks

// Using the Facade with S3
Whatsapp::sendDocument($instanceId, $number, 'documents/report.pdf', 'report.pdf', null, 's3');

// Using the Action with custom disk
SendWhatsappMessageAction::make()->disk('s3');

Webhooks

The plugin includes a webhook endpoint to receive events from Evolution API.

Available Events

Event Description
APPLICATION_STARTUP API started
QRCODE_UPDATED New QR code generated
CONNECTION_UPDATE Connection status changed
NEW_TOKEN New authentication token
SEND_MESSAGE Message sent
PRESENCE_UPDATE Contact online/offline
MESSAGES_UPSERT New message received

Webhook URL

Configure this URL in your Evolution API:

https://your-app.com/api/webhooks/evolution

Multi-Tenancy

The plugin supports Filament's native multi-tenancy. When enabled:

  • All tables include the tenant foreign key
  • Models automatically scope queries by tenant
  • Records are auto-assigned to current tenant on creation

Configuration

Edit the config/filament-evolution.php file:

'tenancy' => [
    'enabled' => true,
    'column' => 'team_id',
    'table' => 'teams',
    'model' => 'App\\Models\\Team',
    'column_type' => 'uuid', // 'uuid' or 'id'
],

Using the Evolution Client Directly

For advanced use cases, you can use the Evolution client directly:

use WallaceMartinss\FilamentEvolution\Services\EvolutionClient;

$client = app(EvolutionClient::class);

// Create instance
$response = $client->createInstance('my-instance', '5511999999999', true, [
    'reject_call' => true,
    'always_online' => true,
]);

// Get connection state
$state = $client->getConnectionState('my-instance');

// Send text message
$client->sendText('my-instance', '5511999999999', 'Hello World!');

// Send image (path is base64 encoded by the service)
$client->sendImage('my-instance', '5511999999999', $base64Content, 'image.jpg', 'Check this!');

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.