PHPackages                             shelfwood/laravel-n8n - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. shelfwood/laravel-n8n

ActiveLibrary[API Development](/categories/api)

shelfwood/laravel-n8n
=====================

Tag-based n8n webhook integration for Laravel — fire events, auto-dispatch to matching n8n workflows

v0.2.0(2mo ago)0655MITPHPPHP ^8.3CI passing

Since Apr 12Pushed 2mo agoCompare

[ Source](https://github.com/j-shelfwood/laravel-n8n)[ Packagist](https://packagist.org/packages/shelfwood/laravel-n8n)[ Docs](https://laravel-n8n.shelfwood.co)[ RSS](/packages/shelfwood-laravel-n8n/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (1)Dependencies (6)Versions (6)Used By (0)

laravel-n8n
===========

[](#laravel-n8n)

Tag-based n8n webhook integration for Laravel. Fire events in your app, auto-dispatch to matching n8n workflows. Zero configuration per workflow — just tag your n8n workflows and the package handles the rest.

How it works
------------

[](#how-it-works)

1. Add the `HasN8nTrigger` trait to any Laravel Event class
2. The event auto-generates a tag from its class name (e.g. `OrderCompleted` → `app:order-completed`)
3. When the event fires, the package finds all active n8n workflows tagged with `app:order-completed`
4. It POSTs the event payload to each workflow's webhook URL
5. Fire-and-forget — your app doesn't depend on n8n being available

Installation
------------

[](#installation)

```
composer require shelfwood/laravel-n8n
```

The service provider auto-discovers. Publish the config:

```
php artisan vendor:publish --tag=n8n-config
```

Add to your `.env`:

```
N8N_URL=https://your-n8n-instance.com
N8N_API_KEY=your-api-key
```

Usage
-----

[](#usage)

### 1. Create an event with the trait

[](#1-create-an-event-with-the-trait)

```
use Illuminate\Foundation\Events\Dispatchable;
use Shelfwood\N8n\Traits\HasN8nTrigger;

class OrderCompleted
{
    use Dispatchable, HasN8nTrigger;

    public function __construct(
        public string $orderId,
        public float $total,
    ) {}

    public function toArray(): array
    {
        return [
            'order_id' => $this->orderId,
            'total' => $this->total,
        ];
    }
}
```

### 2. Fire the event normally

[](#2-fire-the-event-normally)

```
event(new OrderCompleted($order->id, $order->total));
```

### 3. Create an n8n workflow with matching tag

[](#3-create-an-n8n-workflow-with-matching-tag)

In your n8n instance, create a workflow with:

- A **Webhook** trigger node
- A tag matching the event: `app:order-completed`

The package finds the workflow by tag and POSTs:

```
{
    "event": "App\\Events\\OrderCompleted",
    "timestamp": "2026-04-13T00:00:00+00:00",
    "tags": ["app:order-completed"],
    "data": {
        "order_id": "abc-123",
        "total": 99.95
    }
}
```

### Custom tags

[](#custom-tags)

Override the auto-generated tag:

```
$event = new OrderCompleted($id, $total);
$event->setN8nTags(['custom:high-value-order']);
event($event);
```

Filament Status Page
--------------------

[](#filament-status-page)

If your project uses [Filament](https://filamentphp.com), register the status page in your `AdminPanelProvider`:

```
use Shelfwood\N8n\Filament\Pages\N8nStatus;

->pages([
    N8nStatus::class,
])
```

This shows:

- n8n connection health
- All discovered events with their tags
- Which n8n workflows are connected to which events

Configuration
-------------

[](#configuration)

```
// config/n8n.php

return [
    'api' => [
        'url' => env('N8N_URL', ''),
        'key' => env('N8N_API_KEY', ''),
    ],
    'workflows' => [
        'timeout' => (int) env('N8N_WORKFLOW_TIMEOUT', 10),
        'retry_attempts' => 3,
        'retry_delay' => 5,
        // Cache TTL for the workflow list (seconds). Every event dispatch
        // would otherwise refetch the full workflow set. 0 disables.
        'cache_ttl' => (int) env('N8N_WORKFLOWS_CACHE_TTL', 60),
    ],
    // Tag prefix for auto-generated event tags. Override per environment to
    // discriminate workflows on a single shared n8n (`staging:`, `prod:`).
    'tag_prefix' => env('N8N_TAG_PREFIX', 'app:'),
    // Directories scanned by the Filament status page
    'event_directories' => [
        'app/Events',
    ],
];
```

### Domain-driven layouts

[](#domain-driven-layouts)

If your application stores events outside `app/` (e.g. a `src/Domain/*/Events`layout under a `Domain\` PSR-4 root), override `event_directories`:

```
'event_directories' => [
    'src/Domain/*/Events',
],
```

The status page resolves class names from `composer.json` PSR-4, so any namespace mapped there works — no extra registration needed.

### Multi-environment tag separation

[](#multi-environment-tag-separation)

Two apps sharing one n8n? Set `N8N_TAG_PREFIX=staging:` on staging and `N8N_TAG_PREFIX=prod:` on production. Tag your workflows accordingly and the two streams stay isolated without duplicated workflows.

Graceful degradation
--------------------

[](#graceful-degradation)

- **No `N8N_URL`** → events fire normally but no webhooks are dispatched
- **n8n is down** → the queued job retries 3 times, then logs and moves on
- **No matching workflow** → the job silently returns (no error)

Testing
-------

[](#testing)

In your test suite, set `N8N_URL` to empty in `phpunit.xml`:

```

```

This disables webhook dispatch. Your n8n-specific tests can override:

```
config(['n8n.api.url' => 'https://n8n.test']);
Queue::fake();

event(new OrderCompleted('123', 50.00));

Queue::assertPushed(DispatchN8nWebhook::class);
```

License
-------

[](#license)

MIT

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance82

Actively maintained with recent releases

Popularity17

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

5

Last Release

89d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e09f1c5f884add18861aa69eaae3c669601e867050f35112ca6691a0c1ba6e7a?d=identicon)[j-shelfwood](/maintainers/j-shelfwood)

---

Top Contributors

[![j-shelfwood](https://avatars.githubusercontent.com/u/14902964?v=4)](https://github.com/j-shelfwood "j-shelfwood (6 commits)")

---

Tags

laravelautomationeventswebhooksfilamentn8n

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/shelfwood-laravel-n8n/health.svg)

```
[![Health](https://phpackages.com/badges/shelfwood-laravel-n8n/health.svg)](https://phpackages.com/packages/shelfwood-laravel-n8n)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[laravel/horizon

Dashboard and code-driven configuration for Laravel queues.

4.2k95.4M321](/packages/laravel-horizon)[laravel/scout

Laravel Scout provides a driver based solution to searching your Eloquent models.

1.7k55.0M632](/packages/laravel-scout)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k15.1M136](/packages/laravel-pulse)[nuwave/lighthouse

A framework for serving GraphQL from Laravel

3.5k11.8M118](/packages/nuwave-lighthouse)[illuminate/auth

The Illuminate Auth package.

10528.2M1.3k](/packages/illuminate-auth)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
