Workflows
CommunityAutomation made easy!
Author:
Monzer Osman
Package health
BetaAutomated checks of this plugin's Composer package
15 checks
- Skipped: GitHub Actions pinned to SHA
- Skipped: GitLab CI includes pinned to SHA
- Passed: Open security advisories
- Passed: Dependabot PR responsiveness — No open Dependabot PRs.
- Skipped: Renovate MR responsiveness
- Failed: Dependabot or Renovate configured — No dependency updater configuration found. View details on Plumb
- Skipped: Dependency update cooldown configured
- Failed: Provides a security policy — View details on Plumb
- Passed: Abandoned or archived — No consulted source marks the package abandoned (packagist, github).
- Warning: Commit and release recency — Low activity: last commit 299 days ago; last release 299 days ago.
-
Failed:
composer.lock not committed by library
—
composer.lockis present in the released dist archive. View details on Plumb - Passed: Dist archive is lean
-
Passed:
Current Laravel version supported
—
Package dependencies resolve together with current Laravel
13.0. - Passed: Current PHP version supported — No PHP constraint declared; package imposes no version restriction.
- Skipped: Current Symfony version supported
filament/
namespace. Review the source and install at your own risk. Found
malware or an unresolved security issue the author won't
address?
Report it
.
Documentation
- ✨ Introduction
- 🌟 Features
- Screenshots
- ⚙️ Installation & Setup
- 📌 Setting Up Model Event Workflows
- NOTE:
- 🔧 Configuration
- 📝 Log Management
- 🪄 Magic Attributes
- 🎯 Defining Custom Workflow Actions
- 🔗 Sharing Data Between Actions
- Using workflows with tenancy
- 🧪 Tests
- ❤️ Support & Contributions
- 💰 Support the Project
- 📜 License
#✨ 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
composer require monzer/filament-workflows
#⚡ Publish Migration
php artisan vendor:publish --provider="Monzer\FilamentWorkflows\FilamentWorkflowsServiceProvider" --tag="migrations"
#⚡ Publish Configuration (Optional)
php artisan vendor:publish --provider="Monzer\FilamentWorkflows\FilamentWorkflowsServiceProvider" --tag="config"
#📊 Migrate Database
php artisan migrate
#🔧 Registering the Plugin
Users must manually register the plugin in their PanelProvider.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:
use Monzer\FilamentWorkflows\Traits\TrackWorkflowModelEvents;
class Order extends Model
{
use TrackWorkflowModelEvents;
}
To change the model display name you can use the getModelName() static function:
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:
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:
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:
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
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
For existing installations that experience database errors due to large logs, run the optional migration to increase column size:
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.
- Example:
#🎭 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.
- Example:
#🎯 Defining Custom Workflow Actions
Users can create custom actions by implementing the Action interface. Below is an example implementation of the *
SendEmail* action:
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
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
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
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
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
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 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:
Your support helps improve and maintain this package! 🙌
#📜 License
This package is licensed under the MIT License. See the LICENSE file for details.
The author
From the same author
Chatify integration
Seamlessly integrate real-time messaging into your filament application.
Author:
Monzer Osman
Email verification alert
A plugin that adds an email verification alert to your panels.
Author:
Monzer Osman
Featured Plugins
A selection of plugins curated by the Filament team
Blueprint
Filament Blueprint is a premium Laravel Boost extension that helps AI agents produce accurate, detailed implementation plans and security reports for Filament apps.
Filament
Custom Dashboards
Let your users build and share their own dashboards with a drag-and-drop interface. Define your data sources in PHP and let them do the rest.
Filament
Custom Fields
Eliminate custom field migrations forever. Let your users create and manage form fields directly in Filament admin panels with 20+ built-in field types, validation, and zero database changes.
Relaticle