https://github.com/monzer15/filament-workflows
Automation made easy!
https://github.com/monzer15/filament-workflows
Last synced: 3 months ago
JSON representation
Automation made easy!
- Host: GitHub
- URL: https://github.com/monzer15/filament-workflows
- Owner: monzer15
- License: mit
- Created: 2025-02-24T14:25:38.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-09-30T12:28:57.000Z (9 months ago)
- Last Synced: 2026-03-26T16:11:57.891Z (3 months ago)
- Language: PHP
- Size: 183 KB
- Stars: 64
- Watchers: 5
- Forks: 14
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# π Filament Workflows Plugin for Laravel
## β¨ 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
- π 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



## βοΈ Installation & Setup
### π₯οΈ Requirements
Ensure your Laravel application meets the following requirements:
- Laravel 10+
- FilamentPHP 3.2
- PHP 8.1+
### π₯ Install the Package
```bash
composer require monzer/filament-workflows
```
### β‘ Publish Migration
```bash
php artisan vendor:publish --provider="Monzer\FilamentWorkflows\FilamentWorkflowsServiceProvider" --tag="migrations"
```
### β‘ Publish Configuration (Optional)
```bash
php artisan vendor:publish --provider="Monzer\FilamentWorkflows\FilamentWorkflowsServiceProvider" --tag="config"
```
### π Migrate Database
```bash
php artisan migrate
```
### π§ Registering the Plugin
Users must manually register the plugin in their `PanelProvider.php`:
```php
use Filament\Facades\Filament;
use Monzer\FilamentWorkflows\WorkflowsPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugin(WorkflowsPlugin::make());
}
```
## π Setting Up Model Event Workflows
To integrate a model with the model event workflow system, the model must implement the following trait:
```php
use Monzer\FilamentWorkflows\Traits\TrackWorkflowModelEvents;
class Order extends Model
{
use TrackWorkflowModelEvents;
}
```
To change the model display name you can use the getModelName() static function:
```php
use Monzer\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:
```php
use Monzer\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:
You need to run php artisan schedule:work command to run the workflows.
## π§ Configuration
Example configuration in `config/workflows.php`:
```php
return [
'actions' => [
\Monzer\FilamentWorkflows\Actions\SendFilamentNotification::class,
\Monzer\FilamentWorkflows\Actions\SendEmail::class,
\Monzer\FilamentWorkflows\Actions\SendSmsViaTwilio::class,
\Monzer\FilamentWorkflows\Actions\CreateRecord::class,
\Monzer\FilamentWorkflows\Actions\UpdateRecord::class,
\Monzer\FilamentWorkflows\Actions\SendWebhook::class,
\Monzer\FilamentWorkflows\Actions\PushFirebaseNotification::class,
\Monzer\FilamentWorkflows\Actions\BackupMySqlDBUsingMySqlDump::class,
\Monzer\FilamentWorkflows\Actions\SendWhatsAppMessageViaWassenger::class,
\Monzer\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
### 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
You can customize the maximum number of log entries by setting the `WORKFLOWS_MAX_LOG_ENTRIES` environment variable:
```env
WORKFLOWS_MAX_LOG_ENTRIES=200
```
Or modify it directly in the config file:
```php
'max_log_entries' => 200, // Keep last 200 entries
```
To disable log rotation (not recommended):
```php
'max_log_entries' => null, // Disable rotation
```
### Cleaning Up Existing Logs
If you have existing workflows with large log histories, you can clean them up using the provided artisan command:
```bash
# 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
For existing installations that experience database errors due to large logs, run the optional migration to increase column size:
```bash
php artisan migrate --path=vendor/monzer/filament-workflows/database/migrations/2024_01_01_000000_update_workflows_logs_column_size.php
```
## πͺ Magic Attributes
Magic attributes are placeholders that get dynamically replaced with actual data from the model or event triggering the
workflow.
### π **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**
- **`@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
Users can create custom actions by implementing the `Action` interface. Below is an example implementation of the *
*SendEmail** action:
```php
namespace Monzer\FilamentWorkflows\Actions;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Mail;
use Monzer\FilamentWorkflows\Contracts\Action;
use Monzer\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
```php
use Filament\Facades\Filament;
use Monzer\FilamentWorkflows\WorkflowsPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugin(WorkflowsPlugin::make()->actions([CustomAction::class]));
}
```
## π 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:
- 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
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**
```php
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**
```php
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
Create a middleware to setup tenancy
```php
namespace App\Http\Middleware;
use Monzer\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
```php
use Filament\Facades\Filament;
use Monzer\FilamentWorkflows\WorkflowsPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->tenantMiddleware([
ApplyTenantScopes::class,
], isPersistent: true);
}
```
---
## π§ͺ 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 & Contributions
For issues and feature requests, please visit the [GitHub repository](https://github.com/monzer15/filament-workflows) and
create an issue.
Pull requests are welcome. Make sure to follow the contribution guidelines.
## π° 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://paypal.me/monzer15)
Your support helps improve and maintain this package! π
## π License
This package is licensed under the MIT License. See the `LICENSE` file for details.