Install & usage
Everything you need to get WBA Filament running: the licensed install, connecting your Meta account, the webhook, and the day-to-day features.
Requirements
- PHP 8.2+
- Laravel 11 or 12
- FilamentPHP 5
- A queue worker (
php artisan queue:work) — sends and webhook processing are queued - A Meta WhatsApp Business account for production (not needed to evaluate — see simulation mode)
Install the package
Your purchase email (and the My License page) contains a personal license token. Add the private repository, authenticate, then require the package:
composer config repositories.schemava composer https://repo.schemava.dev/r/plugins
composer config bearer.repo.schemava.dev YOUR-LICENSE-TOKEN
composer require asimnet/wba-filament
php artisan vendor:publish --tag="wba-filament-migrations"
php artisan migrateFor CI or Docker builds, pass the token through COMPOSER_AUTH instead of writing it to disk:
COMPOSER_AUTH='{"bearer":{"repo.schemava.dev":"YOUR-LICENSE-TOKEN"}}' composer installRegister the plugin
Add the plugin to your panel provider — the template manager, message log, chat center, quick replies, and dashboard widgets all appear with zero extra wiring:
use Asimnet\WbaFilament\WbaPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
WbaPlugin::make()
->navigationGroup('WhatsApp'),
]);
}Everything is opt-out if you want a slimmer panel:
| Option | What it controls |
|---|---|
->templateResource(false) | Meta template management resource |
->messageResource(false) | Outgoing message log |
->chatCenterPage(false) | The real-time chat center |
->sendMessagePage(false) | Standalone "send message" page |
->quickReplyResource(false) | Quick replies management |
->statsWidget(false) / ->analyticsWidget(false) | Dashboard widgets |
Connect your Meta account
Create (or open) your app in the Meta App Dashboard → WhatsApp, then copy these values into your .env:
WBA_BUSINESS_ACCOUNT_ID=your_whatsapp_business_account_id
WBA_PHONE_NUMBER_ID=your_phone_number_id
WBA_ACCESS_TOKEN=your_permanent_access_token
WBA_APP_ID=your_app_id # only needed for template media headersPublish the config file for the full option set (queues, rate limits, storage, caching, authorization callbacks):
php artisan vendor:publish --tag="wba-filament-config"Set up the webhook
The plugin registers the webhook route automatically at https://your-domain.com/api/wba/webhook. In the Meta App Dashboard → WhatsApp → Configuration:
- Set the Callback URL to
https://your-domain.com/api/wba/webhook - Set the Verify token to the value of your
WBA_WEBHOOK_VERIFY_TOKEN - Subscribe to the
messageswebhook field
WBA_WEBHOOK_VERIFY_TOKEN=any_random_string_you_choose
WBA_WEBHOOK_SECRET=your_meta_app_secretWBA_WEBHOOK_SECRET (your Meta App Secret) is set. Don't skip it — it's what proves a webhook really came from Meta.Sending messages
Send templated messages from anywhere in your app with the facade:
use Asimnet\WbaFilament\Facades\Wba;
Wba::sendByTemplateName(
phone: '966501234567',
templateName: 'order_confirmation',
language: 'ar',
parameters: ['Jane', '#4512'],
scheduledAt: now()->addMinutes(10), // optional — cancellable until sent
);Or integrate your Eloquent models once and send from any Filament table via the bundled actions:
use Asimnet\WbaFilament\Attributes\WbaParameter;
use Asimnet\WbaFilament\Contracts\HasWbaMessages;
use Asimnet\WbaFilament\Traits\InteractsWithWba;
class Order extends Model implements HasWbaMessages
{
use InteractsWithWba;
public function getWbaPhone(): ?string
{
return $this->customer_phone;
}
#[WbaParameter(name: 'customer_name')]
public function customerName(): string
{
return $this->customer->name;
}
}Then add SendWbaMessageAction (single record) or SendWbaMessageBulkAction (selection) to the resource's table — template variables are filled from the attributes automatically.
The chat center
Incoming messages arrive via the webhook and appear in the chat center in real time. Out of the box it refreshes by polling — no extra infrastructure. If your app runs Laravel Echo with Reverb or Pusher, switch to WebSockets:
WBA_REALTIME_DRIVER=echoAccess is open to panel users by default; scope any feature with the authorization callbacks in config/wba.php (e.g. access_chat_center, send_messages, manage_templates).
Quick replies
Canned responses available in the chat center composer — personal or shared with the whole team, with ordering. Manage them from the Quick Replies resource the plugin registers on your panel.
Multi-tenancy
Resolve per-tenant WhatsApp credentials by implementing one small contract:
use Asimnet\WbaFilament\Contracts\CredentialsResolverContract;
class TenantCredentialsResolver implements CredentialsResolverContract
{
public function resolve(): array
{
$tenant = tenancy()->tenant;
return [
'business_account_id' => $tenant->wba_business_account_id,
'phone_number_id' => $tenant->wba_phone_number_id,
'access_token' => $tenant->wba_access_token,
];
}
}Register it via WbaPlugin::make()->credentialsResolver(TenantCredentialsResolver::class) or in config/wba.php under tenant.credentials_resolver (the config route also covers queue workers). Keys you omit fall back to your .env values. On stancl/tenancy apps, webhook jobs carry the tenant id and re-initialize the tenant before processing.
Simulation mode
Evaluate the plugin — or run a demo — without a Meta Business account:
WBA_SIMULATE=trueWhile enabled, no real Meta API calls are made: sends return fake wamid.SIM… ids, template sync returns sample templates, and analytics return sample data. Generate incoming chat activity through the real webhook pipeline:
php artisan wba:simulate-activity --messages=10Troubleshooting
Composer says 403 / could not find package
Your token isn't reaching the registry, or the repository URL is wrong. For WBA Filament the repository URL is exactly https://repo.schemava.dev/r/plugins (with the /r/plugins suffix), while the bearer host is just repo.schemava.dev. Re-run both composer config lines from the install section and copy the token exactly from your My License page.
"No such table: wba_…"
Run the migrations: php artisan vendor:publish --tag="wba-filament-migrations" && php artisan migrate.
Meta won't verify the webhook
The Verify token in the Meta dashboard must equal WBA_WEBHOOK_VERIFY_TOKEN exactly, and the callback URL must be publicly reachable over HTTPS.
Messages stay "queued"
A queue worker isn't running. Start php artisan queue:work (the send queue is named whatsapp — with Horizon, make sure that queue is consumed).
Template submission rejected
Meta reviews every template. Check the rejection reason on the template in the panel, adjust the content to Meta's template policies, and resubmit.
Support
Stuck on something the docs don't cover? Email support@schemava.dev. Support is included for one year from purchase.
See also: My License · Terms · Refund policy