oriceon/laravel-n8n-bridge

Full-featured bidirectional Laravel 13+ bridge for n8n โ€” DB-driven workflows, inbound/outbound tools, queue, circuit breaker, webhook auth.

Maintainers

Package info

github.com/oriceon/laravel-n8n-bridge

pkg:composer/oriceon/laravel-n8n-bridge

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-04-02 14:55 UTC

This package is auto-updated.

Last update: 2026-04-02 15:58:09 UTC


README

Laravel N8N Bridge

๐Ÿ”— laravel-n8n-bridge

A full-featured, bidirectional Laravel 13+ bridge for n8n โ€” DB-driven workflows, secured outbound webhook, secured inbound webhook receiver, circuit breakers, delivery statistics, tools exposed to n8n, DB queue system with live progress tracking, and multi-channel failure notifications.

Latest Version PHP Version Laravel License Tests

โœจ What this package does

Unlike other n8n packages for Laravel โ€” which are simple outbound HTTP clients โ€” laravel-n8n-bridge is a complete bidirectional integration:

Feature Other packages laravel-n8n-bridge
Trigger workflow outbound โœ… โœ…
Outbound auth (token / bearer / HMAC-SHA256) โŒ โœ…
Outbound rate limiting (global + per-workflow) โŒ โœ…
Webhook mode (test / production / auto) โŒ โœ…
Inbound webhook receiver โŒ โœ…
Webhook auth (one key, all routes) โŒ โœ…
Rotatable API keys with grace period โŒ โœ…
Circuit Breaker per workflow โŒ โœ…
DB-driven workflows (not config files) โŒ โœ…
DB Queue with priority, batches, DLQ โŒ โœ…
Live progress tracking + broadcasting โŒ โœ…
Estimated completion time (EMA) โŒ โœ…
Tool system โ€” GET/POST/PATCH/DELETE โŒ โœ…
OpenAPI schema auto-generated โŒ โœ…
Daily statistics with chart-ready data โŒ โœ…
Notifications Slack/Discord/Teams/Mail โŒ โœ…
Idempotency native โŒ โœ…
DLQ + replay โŒ โœ…
Artisan commands โŒ โœ… (20+)
Full Pest test suite โŒ โœ… (832 tests)

๐Ÿ“‹ Requirements

  • PHP 8.5+
  • Laravel 13.x
  • n8n (self-hosted or cloud)

๐Ÿš€ Installation

composer require oriceon/laravel-n8n-bridge

โš™๏ธ Configuration

If you want to publish the config or migrations, you can do so with:

php artisan vendor:publish --tag="n8n-bridge-config"
php artisan vendor:publish --tag="n8n-bridge-migrations"

Then, run the migrations

php artisan migrate

Set .env variables

# n8n instance (multiple supported via config)
N8N_BRIDGE_N8N_DEFAULT_API_BASE_URL=https://n8n.myapp.com
N8N_BRIDGE_N8N_DEFAULT_API_KEY=your-n8n-api-key
N8N_BRIDGE_N8N_DEFAULT_WEBHOOK_BASE_URL=https://n8n.myapp.com/webhook
# Optional: explicit test URL (null = auto-derived by replacing /webhook โ†’ /webhook-test)
N8N_BRIDGE_N8N_DEFAULT_WEBHOOK_TEST_BASE_URL=https://n8n.myapp.com/webhook-test

# Table prefix (default: n8n โ†’ n8n__workflows__lists etc.)
N8N_BRIDGE_TABLE_PREFIX=n8n

# Notifications
N8N_BRIDGE_NOTIFY_ENABLED=true
N8N_BRIDGE_NOTIFY_CHANNELS=slack,mail
N8N_BRIDGE_NOTIFY_SLACK_WEBHOOK=https://hooks.slack.com/services/xxx
N8N_BRIDGE_NOTIFY_DISCORD_WEBHOOK=https://discord.com/api/webhooks/xxx
N8N_BRIDGE_NOTIFY_MAIL_TO=ops@myapp.com
N8N_BRIDGE_NOTIFY_ERROR_RATE=20.0

# Outbound rate limiting (0 = unlimited)
N8N_BRIDGE_OUTBOUND_RATE_LIMIT=0

# Queue system
N8N_BRIDGE_QUEUE_DEFAULT=default
N8N_BRIDGE_QUEUE_DELETE_CHECKPOINTS=true
N8N_BRIDGE_QUEUE_DURATION_SAMPLES=50

๐Ÿ”‘ Authentication

All /n8n/* routes require an X-N8N-Key header. One credential key works across all modules โ€” inbound, tools, and queue progress.

# Create a credential + key
php artisan n8n:credential:create "Production" --instance=default
# โ†’ outputs: n8br_sk_a3f9b2c1...

# In n8n: Personal โ†’ Credentials โ†’ Create credential โ†’ Header Auth
# Name:  X-N8N-Key
# Value: n8br_sk_a3f9b2c1...

See docs/credentials.md for rotation, IP whitelisting, grace periods, and multi-webhook setups.

๐Ÿ“ฅ Inbound โ€” receive data from n8n

1. Create an endpoint

php artisan n8n:endpoint:create invoice-paid \
  --handler="App\N8n\InvoicePaidHandler" \
  --queue=high

2. Write the handler

namespace App\N8n;

use Oriceon\N8nBridge\DTOs\N8nPayload;
use Oriceon\N8nBridge\Inbound\N8nInboundHandler;

final class InvoicePaidHandler extends N8nInboundHandler
{
    public function handle(N8nPayload $payload): void
    {
        $invoice = Invoice::findOrFail($payload->required('invoice_id'));
        $invoice->update([
            'status'  => 'paid',
            'paid_at' => $payload->getCarbon('paid_at'),
        ]);
    }

    public function rules(): array
    {
        return [
            'invoice_id' => 'required|integer',
            'paid_at'    => 'required|date',
        ];
    }
}

3. Configure in n8n

URL:    POST https://myapp.com/n8n/in/invoice-paid
Header: X-N8N-Key: n8br_sk_...
Header: X-N8N-Execution-Id: {{ $execution.id }}

Security pipeline

Every request passes through 6 layers automatically:

POST /n8n/in/{slug}
        โ”‚
        โ–ผ  1. RateLimiter      โ†’ 429 if exceeded
        โ–ผ  2. ApiKeyVerifier   โ†’ 401 if key invalid
        โ–ผ  3. IpWhitelist      โ†’ 403 if IP not allowed
        โ–ผ  4. HmacVerifier     โ†’ 401 if signature mismatch
        โ–ผ  5. IdempotencyCheck โ†’ 200 skip if already processed
        โ–ผ  6. PayloadStore     โ†’ persist delivery to DB
        โ–ผ  ACK 202 + dispatch job to queue

See docs/inbound.md for HMAC, rate limits, IP whitelist, DLQ, and handler validation.

๐Ÿ“ค Outbound โ€” trigger n8n from Laravel

use Oriceon\N8nBridge\Facades\N8nBridge;

// By workflow name
N8nBridge::trigger('order-shipped', [
    'order_id'   => $order->id,
    'shipped_at' => now()->toIso8601String(),
]);

// Sync (waits for HTTP response)
N8nBridge::trigger($workflow, $payload, async: false);

Automatic from Eloquent models

use Oriceon\N8nBridge\Concerns\TriggersN8nOnEvents;

class Invoice extends Model
{
    use TriggersN8nOnEvents;

    protected array $n8nTriggers = [
        'created' => 'invoice-created',
        'updated' => [
            'workflow'  => 'invoice-status-changed',
            'only_when' => ['status', 'paid_at'],
        ],
    ];
}

Webhook mode (test vs production URL)

Each workflow has a webhook_mode that controls which n8n URL is called:

use Oriceon\N8nBridge\Enums\WebhookMode;

N8nWorkflow::find($id)->update([
    'webhook_mode' => WebhookMode::Auto,        // default โ€” /webhook-test in dev, /webhook in prod
    // 'webhook_mode' => WebhookMode::Production, // always /webhook
    // 'webhook_mode' => WebhookMode::Test,        // always /webhook-test
]);

With Auto, the URL is selected based on APP_ENV: production โ†’ /webhook, anything else โ†’ /webhook-test.

See docs/outbound.md for full details.

Outbound authentication

Protect your n8n webhooks with a per-workflow secret (AES-256 encrypted at rest):

use Oriceon\N8nBridge\Auth\WebhookAuthService;
use Oriceon\N8nBridge\Enums\WebhookAuthType;

N8nWorkflow::where('name', 'order-shipped')->update([
    'auth_type' => WebhookAuthType::HmacSha256, // or HeaderToken / Bearer
    'auth_key'  => WebhookAuthService::generateKey(),
]);

Auth headers are added automatically by both the outbound dispatcher and the queue worker.

Outbound rate limiting

Prevent flooding n8n with too many requests per minute:

N8N_BRIDGE_OUTBOUND_RATE_LIMIT=30   # global: 30 req/min (0 = unlimited)

Per-workflow override:

N8nWorkflow::where('name', 'bulk-sync')
    ->update(['rate_limit' => 10]);  // 10 req/min for this workflow

When the limit is exceeded: async triggers are re-dispatched after the window resets; sync triggers fail immediately; queue worker releases the job back to pending with a delay.

See docs/outbound.md for auth types, rate limiting, n8n credential setup, and the HMAC verification Code node.

๐Ÿ”ง Tool System โ€” n8n calls Laravel

Define typed Laravel endpoints that n8n nodes call as an internal API.

php artisan make:n8n-tool GetInvoiceTool
final class GetInvoiceTool extends N8nToolHandler
{
    public function get(N8nToolRequest $request): N8nToolResponse
    {
        return N8nToolResponse::item(
            Invoice::findOrFail($request->required('id')),
            fn($i) => ['id' => $i->id, 'total' => $i->total, 'status' => $i->status]
        );
    }
}
GET  /n8n/tools/schema          โ†’ full OpenAPI 3 spec (import into n8n)
GET  /n8n/tools/{name}          โ†’ handler->get()
GET  /n8n/tools/{name}/{id}     โ†’ handler->getById()
POST /n8n/tools/{name}          โ†’ handler->post()
PATCH /n8n/tools/{name}/{id}    โ†’ handler->patch()
DELETE /n8n/tools/{name}/{id}   โ†’ handler->delete()

See docs/tools.md for filters, pagination, rate limiting, and schema definition.

๐Ÿ“‹ Queue System โ€” async jobs with live progress

use Oriceon\N8nBridge\Enums\QueueJobPriority;use Oriceon\N8nBridge\Queue\QueueDispatcher;

$job = QueueDispatcher::workflow('invoice-processing')
    ->payload(['invoice_id' => $invoice->id])
    ->priority(QueueJobPriority::High)
    ->maxAttempts(5)
    ->idempotent("invoice-{$invoice->id}")
    ->dispatch();

n8n sends checkpoint progress back:

POST /n8n/queue/progress/{jobUuid}
{ "node": "send_email", "status": "completed", "progress_percent": 75 }

POST /n8n/queue/progress/{jobUuid}
{ "node": "__done__", "status": "completed" }

Real-time updates via Laravel Echo:

window.Echo.private(`n8n-job.${jobId}`)
    .listen('N8nQueueJobProgressUpdatedEvent', (e) => {
        updateTimeline(e.checkpoint);
        if (e.is_terminal) console.log('Done:', e.job_status);
    });

See docs/queue.md for full queue documentation โ€” priorities, batches, DLQ, worker setup, Supervisor config, and estimated completion time.

๐Ÿ”„ Circuit Breaker

Closed โ”€โ”€(5 consecutive failures)โ”€โ”€โ†’ Open
  โ†‘                                       โ”‚
  โ”‚ (2ร— consecutive success) (60s cooldown)โ”‚
  โ””โ”€โ”€โ”€โ”€ HalfOpen โ†โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

See docs/circuit-breaker.md.

๐Ÿ“Š Statistics

$overview = N8nBridge::stats()->overview();
// ['total_deliveries' => 14823, 'success_rate' => 98.4, 'avg_duration_ms' => 142]

$chart = N8nBridge::stats()
    ->forWorkflow($workflow)
    ->lastDays(30)
    ->toChartData();

See docs/statistics.md.

๐Ÿ”” Notifications

Alerts sent automatically on DLQ, circuit breaker open, and high error rate:

N8N_BRIDGE_NOTIFY_CHANNELS=slack,discord,mail
N8N_BRIDGE_NOTIFY_SLACK_WEBHOOK=https://hooks.slack.com/services/xxx
N8N_BRIDGE_NOTIFY_MAIL_TO=ops@myapp.com

See docs/notifications.md.

๐Ÿ—„๏ธ Database Tables

With the default n8n prefix:

Table Description
n8n__credentials__lists Credential identities (one per n8n instance)
n8n__api_keys__lists Rotatable API keys (many per credential)
n8n__workflows__lists Workflows synced from n8n
n8n__endpoints__lists Inbound endpoints
n8n__deliveries__lists Full delivery log
n8n__circuit_breakers__lists Per-workflow circuit breaker state
n8n__stats__lists Daily aggregated statistics
n8n__tools__lists Tool definitions
n8n__event_subscriptions__lists Laravel event โ†’ workflow mappings
n8n__queue__jobs DB queue jobs
n8n__queue__batches Batch grouping
n8n__queue__failures Per-attempt failure history
n8n__queue__checkpoints Live progress nodes from n8n

๐Ÿ› ๏ธ Artisan Commands

# Webhook & endpoint management
php artisan n8n:credential:create "Production" --instance=default
php artisan n8n:credential:rotate {id} --grace=300
php artisan n8n:endpoint:create invoice-paid --handler="App\N8n\Handler"
php artisan n8n:endpoint:list
php artisan n8n:endpoint:rotate invoice-paid --grace=300

# Workflow sync
php artisan n8n:workflows:sync --instance=default
php artisan n8n:workflow:auth-setup "Workflow name" --type=header_token

# Testing
php artisan n8n:test-inbound invoice-paid --payload='{"invoice_id":42}'
php artisan n8n:test-inbound invoice-paid --dry-run

# DLQ
php artisan n8n:dlq:list
php artisan n8n:dlq:retry
php artisan n8n:dlq:retry {delivery-id}

# Queue
php artisan n8n:queue:work
php artisan n8n:queue:work --queue=critical --sleep=1
php artisan n8n:queue:status
php artisan n8n:queue:retry
php artisan n8n:queue:cancel {uuid}
php artisan n8n:queue:prune --days=30

# Stats & health
php artisan n8n:stats --last=30
php artisan n8n:health --instance=default

# Generators
php artisan make:n8n-tool GetInvoiceTool

๐Ÿงช Tests

composer test           # 846 tests (Unit + Feature + Architecture)
composer analyse        # PHPStan level 8

๐Ÿ“š Documentation

Guide Description
docs/credentials.md Credential keys, rotation, IP whitelist
docs/inbound.md Inbound handler, pipeline, HMAC, idempotency
docs/outbound.md Outbound triggers, Eloquent trait, event subscriptions, outbound auth, webhook mode
docs/tools.md Tool handlers, routing, OpenAPI schema
docs/queue.md DB queue, priorities, batches, DLQ, live progress
docs/circuit-breaker.md State machine, configuration
docs/statistics.md Stats aggregation, chart data
docs/notifications.md Alert channels, thresholds
docs/security.md Key hashing, HMAC, timing attacks
docs/multitenancy.md Multi-tenant setup
docs/n8n-setup.md Configuring n8n credentials and nodes
docs/testing.md Testing handlers, tools, and queue jobs
docs/upgrade.md Upgrade guide

๐Ÿ“„ License

MIT โ€” Copyright ยฉ 2026 Valentin Ivaศ™cu