liberusoftware/webhooks-filament
A Filament plugin for managing webhooks in Laravel apps. Adds admin resources and UI to configure endpoints, monitor deliveries, and review webhook activity from your Filament panel, integrating with liberusoftware/webhooks.
This package is a thin Filament presentation layer over liberusoftware/module-webhooks — it does not implement webhook dispatch itself, so treat the core module as a prerequisite, not an optional peer.
Minimal setup:
composer require liberusoftware/module-webhooks liberusoftware/webhooks-filament
php artisan vendor:publish --tag=webhooks-filament-config
php artisan migrate
Then register the plugin in your panel provider:
use LiberuSoftware\WebhooksFilament\WebhooksFilamentPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugin(WebhooksFilamentPlugin::make());
}
Where to look first, in order:
src/WebhooksFilamentServiceProvider.php — shows what is auto-registered (resources, pages, widgets, config key) and whether the plugin is opt-in or auto-discovered.config/webhooks-filament.php — navigation group, slugs, resource enable/disable flags, tenancy behavior.src/Filament/Resources/ — the Resource + Pages classes you will actually extend or override.LiberuSoftware\Webhooks\Services\... or Actions/...) — this is where sending, retrying, and signing happen.First use case worth wiring end-to-end before touching anything else: create a webhook endpoint record through the Filament resource, point it at a request bin (webhook.site / ngrok), fire a test event from a model observer or php artisan tinker, then open the deliveries relation manager and confirm the request, response code, and payload are recorded. That single loop exercises the resource, the core dispatcher, your queue, and the log table at once — if any of those are misconfigured you will find out immediately rather than in production.
Because the package has no dependents and a NOASSERTION license, read LICENSE and the composer require constraints before adopting. Pin an exact tag and diff it against the core module's version; these Liberu packages are versioned in lockstep and a mismatch between the adapter and the core is the most common install failure.
Plugin registration per panel. The plugin is designed to be attached to a specific Panel. For a multi-panel app (admin + tenant portal), register it on the panel that should own webhook configuration, and use the config flags to suppress the resources on the other panel rather than writing your own authorization for each.
Extend, don't fork. The Resources are ordinary Filament resources. The durable pattern is:
class WebhookEndpointResource extends \LiberuSoftware\WebhooksFilament\Filament\Resources\WebhookEndpointResource
{
public static function form(Form $form): Form
{
return parent::form($form)->schema([...parent::form($form)->getSchema(), ...]);
}
}
and then point the config key at your subclass. This survives upstream updates; copying the vendor file into app/ does not.
Events as a domain concern. Webhook subscriptions map naturally to model events. The clean integration is a small observer or a model trait in your app that calls the core module's dispatch action on created/updated/deleted, with the Filament resource purely as the CRUD surface for endpoint/event configuration. Keep business rules (which events are subscribable, payload shaping) in your app or the core module, not in the Filament layer.
Queue everything. Configure the core module's queue connection and retry policy in config/webhooks.php, and run a worker. The Filament delivery log becomes genuinely useful only when retries and backoff are asynchronous — otherwise a slow or failing endpoint blocks the admin request that triggered it.
Permissions via policies. The resources will respect standard Filament authorization if you set canViewAny, canCreate, etc., against policies. In practice you want a split: developers/ops can manage endpoints and secrets, support staff can view delivery logs read-only. Register a WebhookEndpointPolicy and a separate read-only policy for deliveries; do not rely on the default permissive behavior.
Relation managers for deliveries. Expose deliveries as a relation manager on the endpoint resource (read-only table, no create action) so debugging lives one click from the configuration. Add a filter for response_status >= 400 — that is the query you will run most often.
Widgets for health. A small stats widget (success rate over 24h, count of exhausted retries) on the dashboard is cheap and catches silent breakage. Derive it from the delivery table, not from a cached counter, unless you already emit one.
Testing. Filament resources are Livewire components; use Livewire::test(WebhookEndpointResource\Pages\CreateWebhookEndpoint::class) for form behavior and Http::fake() for dispatch assertions. Assert on the core module's outbound HTTP call and on the delivery record being created, not on internal adapter classes — the adapter layer is the part most likely to change.
module-webhooks are released together; a ^1.0 on one and ^3.0 on the other will install cleanly and then fatal on a missing method. Constrain both explicitly and upgrade them in the same commit.NOASSERTION license. SPDX cannot classify the license file automatically. Verify the actual terms in LICENSE before shipping this in a commercial product — this is a legal question, not a Composer one.composer show liberusoftware/webhooks-filament --all rather than trusting the mirror; you may be pinning a dev branch inadvertently.webhooks can clash with an app resource. Change navigation.slug and navigation.group in the published config before registering the plugin, not after — Filament caches route names.php artisan filament:optimize-clear (and php artisan optimize:clear if you cache config in production). Stale component caches make resources appear missing, which reads like a broken install.->password()->revealable() or write-only with a "regenerate" action; never render the stored secret in the table. If the vendor resource shows it by default, override the table columns.localhost at the form level and again at dispatch; the Filament layer will not do this for you.team_id/tenant column and that the resource applies ->scopeToTenant(). A missing scope here leaks another tenant's endpoints and payloads — worth an explicit test.failed_jobs table → the delivery record's response body → the core module's log channel → whether the queue worker is actually running with the right connection. A "webhooks aren't sending" report is almost always the worker, not the package.Event/subscription enums, and the core module's dispatch action. Avoid subclassing the adapter's Livewire pages directly — those classes have the least stable API surface in a package this young.How can I help you explore Laravel packages today?