PHPackages                             ixys/filament-workflows - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. ixys/filament-workflows

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

ixys/filament-workflows
=======================

Automation made easy!

0.3.0(5mo ago)03MITPHPPHP ^8.4CI passing

Since Dec 14Pushed 5mo agoCompare

[ Source](https://github.com/ixys/filament-workflows)[ Packagist](https://packagist.org/packages/ixys/filament-workflows)[ RSS](/packages/ixys-filament-workflows/feed)WikiDiscussions main Synced 1mo ago

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

🚀 Filament Workflows Plugin for Laravel
=======================================

[](#-filament-workflows-plugin-for-laravel)

✨ Introduction
--------------

[](#-introduction)

This package is a **FilamentPHP plugin** designed to provide a workflow automation system within FilamentPHP applications. It enables users to create and manage workflows triggered by model events, custom events, or scheduled tasks. The package integrates seamlessly with FilamentPHP, offering a Filament Resource for managing workflows.

🌟 Features
----------

[](#-features)

- 🔄 Workflow automation via **model events, custom events, or scheduling**.
- 🛠️ Filament Resource for **CRUD workflow management**.
- 🏗️ **Supports custom workflow actions**.
- 📜 **Execution logs** viewable through Filament.
- 🔗 Chaining of multiple actions.
- 🌍 **Webhook sending** as an external integration.
- ✨ **Magic Attributes** enable dynamic replacement of placeholders with model attributes or event data, allowing seamless data binding and automation within the system.

Screenshots
-----------

[](#screenshots)

[![Create workflow](art/1.png)](art/1.png)[![Action 1](art/2.png)](art/2.png)[![Action 2](art/3.png)](art/3.png)

⚙️ Installation &amp; Setup
---------------------------

[](#️-installation--setup)

### 🖥️ Requirements

[](#️-requirements)

Ensure your Laravel application meets the following requirements:

- Laravel 10+
- FilamentPHP 3.2
- PHP 8.1+

### 📥 Install the Package

[](#-install-the-package)

```
composer require ixys/filament-workflows
```

### ⚡ Publish Migration

[](#-publish-migration)

```
php artisan vendor:publish --provider="Ixys\FilamentWorkflows\FilamentWorkflowsServiceProvider" --tag="migrations"
```

### ⚡ Publish Configuration (Optional)

[](#-publish-configuration-optional)

```
php artisan vendor:publish --provider="Ixys\FilamentWorkflows\FilamentWorkflowsServiceProvider" --tag="config"
```

### 📊 Migrate Database

[](#-migrate-database)

```
php artisan migrate
```

### 🔧 Registering the Plugin

[](#-registering-the-plugin)

Users must manually register the plugin in their `PanelProvider.php`:

```
use Filament\Facades\Filament;
use Ixys\FilamentWorkflows\WorkflowsPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugin(WorkflowsPlugin::make());
}
```

📌 Setting Up Model Event Workflows
----------------------------------

[](#-setting-up-model-event-workflows)

To integrate a model with the model event workflow system, the model must implement the following trait:

```
use Ixys\FilamentWorkflows\Traits\TrackWorkflowModelEvents;

class Order extends Model
{
    use TrackWorkflowModelEvents;
}
```

To change the model display name you can use the getModelName() static function:

```
use Ixys\FilamentWorkflows\Traits\TrackWorkflowModelEvents;

class Order extends Model
{
    use TrackWorkflowModelEvents;

    public static function getModelName(): string
    {
        return __("order.plural"); //for example
    }
}
```

To change the attributes display name you can use the getAttributeName() static function:

```
use Ixys\FilamentWorkflows\Traits\TrackWorkflowModelEvents;

class Order extends Model
{
    use TrackWorkflowModelEvents;

    public static function getAttributeName(string $attribute): ?string
    {
        switch ($attribute) {
            case 'id':
                return __("order.fields.id");
            case 'type':
                return __("order.fields.type");
            //... extra
            default:
                return null;
        }
    }
}
```

NOTE:
-----

[](#note)

You need to run php artisan schedule:work command to run the workflows.

🔧 Configuration
---------------

[](#-configuration)

Example configuration in `config/workflows.php`:

```
return [
    'actions' => [
        \Ixys\FilamentWorkflows\Actions\SendFilamentNotification::class,
        \Ixys\FilamentWorkflows\Actions\SendEmail::class,
        \Ixys\FilamentWorkflows\Actions\SendSmsViaTwilio::class,
        \Ixys\FilamentWorkflows\Actions\CreateRecord::class,
        \Ixys\FilamentWorkflows\Actions\UpdateRecord::class,
        \Ixys\FilamentWorkflows\Actions\SendWebhook::class,
        \Ixys\FilamentWorkflows\Actions\PushFirebaseNotification::class,
        \Ixys\FilamentWorkflows\Actions\BackupMySqlDBUsingMySqlDump::class,
        \Ixys\FilamentWorkflows\Actions\SendWhatsAppMessageViaWassenger::class,
        \Ixys\FilamentWorkflows\Actions\SendTelegramMessage::class
    ],
    //scan the following directories for models
    'models_directory' => [
        'App\\Models',
    ],
    'services' => [
        'firebase' => [
            'server_key' => env('FIREBASE_SERVER_KEY'),
            'model_token_attribute_name' => env('FIREBASE_MODEL_TOKEN_ATTRIBUTE_NAME', 'fcm_token'),
            'icon' => env('FIREBASE_ICON'),
        ],
        'telegram' => [
            'bot_token' => env('TELEGRAM_BOT_TOKEN'),
        ],
        'wassenger' => [
            'api_key' => env('WASSENGER_API_KEY'),
        ],
        'twilio' => [
            'sid' => env('TWILIO_SID'),
            'token' => env('TWILIO_TOKEN'),
            'from' => env('TWILIO_FROM'),
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Maximum Log Entries
    |--------------------------------------------------------------------------
    |
    | This value determines the maximum number of log entries to keep for
    | each workflow. When this limit is exceeded, older entries will be
    | automatically removed to prevent database overflow. Set to null to
    | disable log rotation (not recommended for production).
    |
    */
    'max_log_entries' => env('WORKFLOWS_MAX_LOG_ENTRIES', 100),
];
```

📝 Log Management
----------------

[](#-log-management)

### Automatic Log Rotation

[](#automatic-log-rotation)

Starting from version 0.3.0, this package includes automatic log rotation to prevent database overflow. By default, only the last 100 log entries are kept for each workflow.

#### Configuration

[](#configuration)

You can customize the maximum number of log entries by setting the `WORKFLOWS_MAX_LOG_ENTRIES` environment variable:

```
WORKFLOWS_MAX_LOG_ENTRIES=200
```

Or modify it directly in the config file:

```
'max_log_entries' => 200, // Keep last 200 entries
```

To disable log rotation (not recommended):

```
'max_log_entries' => null, // Disable rotation
```

### Cleaning Up Existing Logs

[](#cleaning-up-existing-logs)

If you have existing workflows with large log histories, you can clean them up using the provided artisan command:

```
# Clean up logs using the configured limit
php artisan workflows:cleanup-logs

# Clean up logs with a custom limit
php artisan workflows:cleanup-logs --limit=50

# Preview what would be cleaned without making changes
php artisan workflows:cleanup-logs --dry-run
```

### Database Migration for Large Logs

[](#database-migration-for-large-logs)

For existing installations that experience database errors due to large logs, run the optional migration to increase column size:

```
php artisan migrate --path=vendor/ixys/filament-workflows/database/migrations/2024_01_01_000000_update_workflows_logs_column_size.php
```

🪄 Magic Attributes
------------------

[](#-magic-attributes)

Magic attributes are placeholders that get dynamically replaced with actual data from the model or event triggering the workflow.

### 🔄 **Model Event Workflows**

[](#-model-event-workflows)

- **`@email@`** → Replaced by the model's email attribute.
    - Example: ```
        Hello @email@, your order has been processed.

        ```
    - If the model contains `email = user@example.com`, the message will be: ```
        Hello user@example.com, your order has been processed.

        ```

### 🎭 **Custom Event Workflows**

[](#-custom-event-workflows)

- **`@event->name@`** → Replaced by the event’s name attribute.
    - Example: ```
        A new event named @event->name@ has been created.

        ```
    - If the event contains `name = System Update`, the message will be: ```
        A new event named System Update has been created.

        ```

🎯 Defining Custom Workflow Actions
----------------------------------

[](#-defining-custom-workflow-actions)

Users can create custom actions by implementing the `Action` interface. Below is an example implementation of the \* *SendEmail*\* action:

```
namespace Ixys\FilamentWorkflows\Actions;

use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Mail;
use Ixys\FilamentWorkflows\Contracts\Action;
use Ixys\FilamentWorkflows\Models\WorkflowActionExecution;

class SendEmail extends Action
{
    public function getId(): string
    {
        return 'send-email';
    }

    public function getName(): string
    {
        return 'Send Email';
    }

    public function getFields(): array
    {
        return [
            TextInput::make('data.email')
                ->helperText("Supports magic attributes")
                ->required(),
            TextInput::make('data.subject')
                ->helperText("Supports magic attributes")
                ->required(),
            Textarea::make('data.message')
                ->helperText("Supports magic attributes")
                ->required()
                ->rows(5),
        ];
    }

    public function getMagicAttributeFields(): array
    {
        return ['email', 'subject', 'message'];
    }

    public function execute(array $data, WorkflowActionExecution $actionExecution, ?Model $model, array $custom_event_data, array &$sharedData)
    {
        Mail::raw($data['message'], function ($message) use ($data) {
            $message->to($data['email'])->subject($data['subject']);
        });
        $actionExecution->log("Email successfully sent to: {$data['email']} regarding: {$data['subject']}");
    }

    public function canBeUsedWithScheduledWorkflows(): bool
    {
        return true;
    }

    public function canBeUsedWithRecordEventWorkflows(): bool
    {
        return true;
    }

    public function canBeUsedWithCustomEventWorkflows(): bool
    {
        return true;
    }

    public function requireInstalledPackages(): array
    {
        return [];
    }
}
```

Then add your custom action

```
use Filament\Facades\Filament;
use Ixys\FilamentWorkflows\WorkflowsPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugin(WorkflowsPlugin::make()->actions([CustomAction::class]));
}
```

🔗 Sharing Data Between Actions
------------------------------

[](#-sharing-data-between-actions)

To allow actions to be aware of each other and share data, a **shared data array** is passed between actions in the `execute` function. This enables actions to store and retrieve information dynamically as they execute.

### 📌 How It Works:

[](#-how-it-works)

- Each action **receives a shared data array**.
- Actions can **store values** inside this array to be used by subsequent actions.
- The shared data persists **throughout the workflow execution**.

### 📝 Example: Sharing Data Between Actions

[](#-example-sharing-data-between-actions)

Let's say we need to:

1️⃣ **Generate an Invoice** and store the `invoice_id`. 2️⃣ **Send an Email** using that `invoice_id`.

#### **🛠️ Action 1: Generate Invoice**

[](#️-action-1-generate-invoice)

```
class GenerateInvoice extends Action
{
    public function execute(array $data, WorkflowActionExecution $execution, ?Model $model, array $custom_event_data, array &$sharedData)
    {
        // Generate invoice
        $invoiceId = Str::uuid();
        $sharedData['invoice_id'] = $invoiceId;

        $execution->log("Generated Invoice ID: $invoiceId");
    }
}
```

#### **📧 Action 2: Send Email with Invoice ID**

[](#-action-2-send-email-with-invoice-id)

```
class SendEmail extends Action
{
    public function execute(array $data, WorkflowActionExecution $execution, ?Model $model, array $custom_event_data, array &$sharedData)
    {
        $invoiceId = $sharedData['invoice_id'] ?? 'Unknown';

        Mail::raw("Invoice ID: $invoiceId", function ($message) use ($data) {
            $message->to($data['email'])->subject("Your Invoice");
        });

        $execution->log("Email sent with Invoice ID: $invoiceId");
    }
}
```

Using workflows with tenancy
----------------------------

[](#using-workflows-with-tenancy)

Create a middleware to setup tenancy

```
namespace App\Http\Middleware;

use Ixys\FilamentWorkflows\Models\Workflow;

class ApplyTenantScopes
{
    /**
     * Handle an incoming request.
     *
     * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
     */
    public function handle(Request $request, Closure $next): Response
    {
            Workflow::resolveRelationUsing('team', function ($model) {
            return $model->belongsTo(Team::class, 'team_id');
        });
        return $next($request);
    }
}
```

Then, add the middleware to the panel

```
use Filament\Facades\Filament;
use Ixys\FilamentWorkflows\WorkflowsPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
            ->tenantMiddleware([
                ApplyTenantScopes::class,
            ], isPersistent: true);
}
```

---

🧪 Tests
-------

[](#-tests)

Currently, **automated tests are not available** for this package. Future updates may include unit tests and integration tests to ensure workflow stability and execution accuracy.

❤️ Support &amp; Contributions
------------------------------

[](#️-support--contributions)

For issues and feature requests, please visit the [GitHub repository](https://github.com/ixys/filament-workflows) and create an issue.

Pull requests are welcome. Make sure to follow the contribution guidelines.

💰 Support the Project
---------------------

[](#-support-the-project)

If you find this package helpful and would like to support its development, consider making a donation:

[☕ Buy Me a Coffee](https://buymeacoffee.com/ixys)

Your support helps improve and maintain this package! 🙌

📜 License
---------

[](#-license)

This package is licensed under the MIT License. See the `LICENSE` file for details.

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance73

Regular maintenance activity

Popularity3

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 63.3% 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

Unknown

Total

1

Last Release

155d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/5b471a275a83f23e4234ebf864dc6939dbf32ba62e60e78ac69c69d63d8eecd1?d=identicon)[jsimoncini](/maintainers/jsimoncini)

---

Top Contributors

[![monzer15](https://avatars.githubusercontent.com/u/59767837?v=4)](https://github.com/monzer15 "monzer15 (38 commits)")[![matteobreschig](https://avatars.githubusercontent.com/u/69394134?v=4)](https://github.com/matteobreschig "matteobreschig (10 commits)")[![jsimoncini](https://avatars.githubusercontent.com/u/11820714?v=4)](https://github.com/jsimoncini "jsimoncini (8 commits)")[![pedrobruning](https://avatars.githubusercontent.com/u/48540328?v=4)](https://github.com/pedrobruning "pedrobruning (2 commits)")[![husam-tariq](https://avatars.githubusercontent.com/u/16601695?v=4)](https://github.com/husam-tariq "husam-tariq (1 commits)")[![vasilGerginski](https://avatars.githubusercontent.com/u/1145019?v=4)](https://github.com/vasilGerginski "vasilGerginski (1 commits)")

---

Tags

automationfilamentworkflows

### Embed Badge

![Health badge](/badges/ixys-filament-workflows/health.svg)

```
[![Health](https://phpackages.com/badges/ixys-filament-workflows/health.svg)](https://phpackages.com/packages/ixys-filament-workflows)
```

###  Alternatives

[monzer/filament-workflows

Automation made easy!

646.3k](/packages/monzer-filament-workflows)[awcodes/filament-table-repeater

A modified version of the Filament Forms Repeater to display it as a table.

262815.1k5](/packages/awcodes-filament-table-repeater)[codewithdennis/filament-select-tree

The multi-level select field enables you to make single selections from a predefined list of options that are organized into multiple levels or depths.

320392.1k17](/packages/codewithdennis-filament-select-tree)[pxlrbt/filament-environment-indicator

Indicator for the current environment inside Filament

151923.9k12](/packages/pxlrbt-filament-environment-indicator)[pboivin/filament-peek

Full-screen page preview modal for Filament

253319.6k12](/packages/pboivin-filament-peek)[statikbe/laravel-cookie-consent

Cookie consent modal for EU

213396.7k](/packages/statikbe-laravel-cookie-consent)

PHPackages © 2026

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