Multi-Factor WhatsApp plugin screenshot
Dark mode ready
Multilingual support
Supports v5.x

Multi-Factor WhatsApp by Jefferson Gonçalves

Community

WhatsApp authentication sends the user one-time codes to their WhatsApp address, which they must enter to verify their identity.

Tags: Panel Authentication
Supported versions:
5.x 4.x
Jefferson Gonçalves avatar Author: Jefferson Gonçalves

Package health

Automated checks of this plugin's Composer package

100 / 100
Security 100
Maintenance 100
Ecosystem 100
15 checks
  • Passed: GitHub Actions pinned to SHA
  • Skipped: GitLab CI includes pinned to SHA
  • Passed: Open security advisories
  • Passed: Dependabot PR responsiveness — No open Dependabot PRs.
  • Skipped: Renovate MR responsiveness
  • Passed: Dependabot or Renovate configured
  • Passed: Dependency update cooldown configured
  • Passed: Provides a security policy
  • Passed: Abandoned or archived — No consulted source marks the package abandoned (packagist, github).
  • Passed: Commit and release recency — Active: last commit 0 days ago; last release 123 days ago.
  • Passed: composer.lock not committed by library — composer.lock is absent from the released dist archive.
  • Passed: Dist archive is lean
  • Passed: Current Laravel version supported — Package dependencies resolve together with current Laravel 13.0.
  • Passed: Current PHP version supported — Constraint ^8.2 supports current PHP 8.5.
  • Skipped: Current Symfony version supported
Third-party plugin. This is built by the community, not the Filament team. Filament does not review, endorse, or vet the security of plugins outside the filament/ namespace. Review the source and install at your own risk. Found malware or an unresolved security issue the author won't address? Report it .
Powered by Plumb Last scanned 1 month ago

Documentation

Version:

Filament Multifactor Whatsapp

Latest Version on Packagist GitHub Code Style Action Status Total Downloads License

#Requirements

  • PHP 8.3 or higher
  • Filament 4.0

#Installation

You can install the package via composer:

composer require jeffersongoncalves/filament-multifactor-whatsapp

#WhatsApp authentication

WhatsApp authentication sends the user one-time codes to their WhatsApp address, which they must enter to verify their identity.

To enable WhatsApp authentication in a panel, you must first add a new column to your users table (or whichever table is being used for your "authenticatable" Eloquent model in this panel). The column needs to store a boolean indicating whether or not WhatsApp authentication is enabled:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('users', function (Blueprint $table) {
    $table->boolean('has_whatsapp_authentication')->default(false);
});

In the User model, you need to ensure that this column is cast to a boolean:

use Filament\Models\Contracts\FilamentUser;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements FilamentUser
{
    /**
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            // ...
            'has_whatsapp_authentication' => 'boolean',
        ];
    }
    
    // ...
}

Next, you should implement the HasWhatsAppAuthentication interface on the User model. This provides Filament with the necessary methods to interact with the column that indicates whether or not WhatsApp authentication is enabled:

use Filament\Models\Contracts\FilamentUser;
use Illuminate\Foundation\Auth\User as Authenticatable;
use JeffersonGoncalves\Filament\MultiFactorWhatsApp\Contracts\HasWhatsAppAuthentication;

class User extends Authenticatable implements FilamentUser, HasWhatsAppAuthentication
{
    // ...

    public function hasWhatsappAuthentication(): bool
    {
        // This method should return true if the user has enabled WhatsApp authentication.
        
        return $this->has_whatsapp_authentication;
    }

    public function toggleWhatsappAuthentication(bool $condition): void
    {
        // This method should save whether or not the user has enabled WhatsApp authentication.
    
        $this->has_whatsapp_authentication = $condition;
        $this->save();
    }
}

Tip: Since Filament uses an interface on your User model instead of assuming that the has_whatsapp_authentication column exists, you can use any column name you want. You could even use a different model entirely if you want to store the setting in a different table.

Finally, you should activate the WhatsApp authentication feature in your panel. To do this, use the multiFactorAuthentication() method in the panel configuration, and pass a WhatsAppAuthentication instance to it:

use Filament\Panel;
use JeffersonGoncalves\Filament\MultiFactorWhatsApp\WhatsAppAuthentication;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->multiFactorAuthentication([
            WhatsAppAuthentication::make(),
        ]);
}

#Changing the WhatsApp code expiration time

WhatsApp codes are issued with a lifetime of 4 minutes, after which they expire.

To change the expiration period, for example to only be valid for 2 minutes after codes are generated, you can use the codeExpiryMinutes() method on the WhatsAppAuthentication instance, set to 2:

use Filament\Panel;
use JeffersonGoncalves\Filament\MultiFactorWhatsApp\WhatsAppAuthentication;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->multiFactorAuthentication([
            WhatsAppAuthentication::make()
                ->codeExpiryMinutes(2),
        ]);
}

#WhatsApp Connector — wallacemartinss/filament-whatsapp-conector

This starter kit ships with the WhatsApp Connector plugin (Evolution API v2 client) already required in composer.json and ready to be registered in your Filament Admin panel. It lets you manage WhatsApp instances, display live QR Codes to connect, log webhooks, and send messages (text, images, videos, audio, documents) from Filament actions or your own services.

What’s already configured

  • Dependency: wallacemartinss/filament-whatsapp-conector is included
  • Admin panel registration: add to your Admin panel provider FilamentEvolutionPlugin::make()->whatsappInstanceResource()->viewMessageHistory()->viewWebhookLogs()

#1) Publish config and run migrations

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

#2) Environment variables (.env)

Add your Evolution API credentials and webhook settings:

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

# Webhook URL (required to receive events)
# Use the public URL to your app’s webhook endpoint (see below):
EVOLUTION_WEBHOOK_URL=https://your-app.com/api/webhooks/evolution

# Optional security secret (recommended)
EVOLUTION_WEBHOOK_SECRET=your_secret_key

# Optional defaults (useful for single‑instance setups)
EVOLUTION_DEFAULT_INSTANCE=your_instance_id

#3) Webhook endpoint

  • The plugin exposes an endpoint for Evolution API to POST events (QR updates, messages, connection changes, etc.).
  • Set EVOLUTION_WEBHOOK_URL to your public URL pointing to: https://your-app.com/api/webhooks/evolution.
  • Ensure your app is accessible publicly and that the route is not blocked by auth or CSRF.

#4) Optional configuration (config/filament-evolution.php)

After publishing, you can tune behaviors such as queues, storage, cleanup, and tenancy. Key options:

return [
    'queue' => [
        'enabled' => true,
        'connection' => null, // default connection
        'name' => 'default',
    ],
    'storage' => [
        'webhooks' => true,   // persist webhook payloads
        'messages' => true,   // persist sent/received messages
    ],
    'cleanup' => [
        'webhooks_days' => 30,
        'messages_days' => 90,
    ],
    'instance' => [
        'reject_call' => false,
        'always_online' => false,
        // ...other defaults
    ],
    'tenancy' => [
        'enabled' => false,
        'column' => 'team_id',
        'table' => 'teams',
        'model' => 'App\\Models\\Team',
    ],
];

#5) Managing WhatsApp instances (Admin panel)

  1. Go to: WhatsApp > Instances
  2. Create a new instance (name/phone)
  3. Save to open the QR Code modal
  4. Scan the QR Code with your WhatsApp
  5. Watch status updates (Always Online, Read Messages, Reject Calls, etc.)

#6) Sending messages

The plugin provides three ways to send WhatsApp messages:

  • Filament Action (UI): attach SendWhatsappMessageAction to tables/pages/widgets
  • Facade: quick sending from anywhere in your code
  • Trait: integrate into your services for reusable sending logic

Examples (UI actions)

use WallaceMartinss\\FilamentEvolution\\Actions\\SendWhatsappMessageAction;

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

// In a page header
protected function getHeaderActions(): array
{
    return [
        SendWhatsappMessageAction::make()
            // Optional sensible defaults
            ->number('5511999999999')
            ->message('Hello from EvolutionKit!'),
    ];
}

Prefilling from records

SendWhatsappMessageAction::make()
    ->numberFrom('phone')                // attribute on the record
    ->instanceFrom('whatsapp_instance_id');

Limiting message types or hiding fields

use WallaceMartinss\\FilamentEvolution\\Enums\\MessageTypeEnum;

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

Media storage (optional)

EVOLUTION_MEDIA_DISK=public
EVOLUTION_MEDIA_DIRECTORY=whatsapp-media
EVOLUTION_MEDIA_MAX_SIZE=16384

You can also specify a custom disk per action: SendWhatsappMessageAction::make()->disk('s3');

#7) Cleanup command

Remove old webhook/message records automatically:

php artisan evolution:cleanup           # uses config defaults
php artisan evolution:cleanup --dry-run # preview deletions
php artisan evolution:cleanup --webhooks-days=7 --messages-days=30

Schedule it (example):

// routes/console.php
use Illuminate\\Support\\Facades\\Schedule;
Schedule::command('evolution:cleanup')->daily();

#Troubleshooting

  • QR Code does not appear: verify EVOLUTION_URL and EVOLUTION_API_KEY, and that your Evolution API v2 instance is reachable from the app
  • Webhooks not received: confirm EVOLUTION_WEBHOOK_URL is a public HTTPS URL to /api/webhooks/evolution, no auth/CSRF blocking, and that your hosting firewall allows inbound requests
  • Media uploads failing: check EVOLUTION_MEDIA_DISK permissions and file size limits
  • Messages queued but not sent: ensure queues are running (e.g., php artisan queue:listen) and that the configured queue connection is available

Reference

#Development

You can run code analysis and formatting using the following commands:

# Run static analysis
composer analyse

# Format code
composer format

#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.

The author

Jefferson Gonçalves avatar Author: Jefferson Gonçalves

I'm a Full Stack PHP Developer from Assis, SP, Brazil with over 18 years of hands-on experience building robust platforms, managing server infrastructures, and crafting scalable solutions for businesses of all sizes.

My passion lives in the open source world — I actively maintain 20+ Filament plugins and a growing collection of Laravel packages used by thousands of developers worldwide. I believe great software should be accessible to everyone.

Plugins
44
Stars
210

From the same author

Scanner Guard plugin thumbnail

Scanner Guard

Filament UI for jeffersongoncalves/laravel-scanner-guard: list, filter and unban vulnerability-scanner IPs directly from your admin panel. This plugin ships a read-only Resource over the scanner_guard_bans table, an active/expired filter, and unban / bulk unban actions.

Jefferson Gonçalves avatar Author: Jefferson Gonçalves
100 / 100 package health score out of 100
0 stars
Tag: Widget Tag: Analytics
Dark mode ready Multilingual support
Free
Get it now
Short URL plugin thumbnail

Short URL

A complete Filament v5 admin layer for jeffersongoncalves/laravel-short-url — the headless core package that owns the models, migrations, redirect pipeline, tracking and every business rule. This package duplicates none of that: it's the presentation layer (Resources, Pages and Filament components) built on top of the core's Facade and contracts.

Jefferson Gonçalves avatar Author: Jefferson Gonçalves
100 / 100 package health score out of 100
3 stars
Tag: Analytics Tag: Widget
Dark mode ready Multilingual support
Free
Get it now
TeamKit v5 plugin thumbnail

TeamKit v5

Teamkit is a robust starter kit, designed to accelerate the development of modern web applications with a ready-to-use multi-panel structure.

Jefferson Gonçalves avatar Author: Jefferson Gonçalves
97 / 100 package health score out of 100
6 stars
Tag: Kit
Dark mode ready Multilingual support
Free
Get it now
Ban plugin thumbnail

Ban

Ban and unban any Eloquent model directly from your Filament panel. This package wraps cybercog/laravel-ban and ships ready-to-use actions, bulk actions, an icon column and a status filter for your Filament resources and tables. Inspired by cybercog/laravel-nova-ban.

Jefferson Gonçalves avatar Author: Jefferson Gonçalves
100 / 100 package health score out of 100
0 stars
Tag: Action
Dark mode ready Multilingual support
Free
Get it now