Custom triggers
A trigger is a node that starts a workflow. It extends
Qanna\WorkflowEngine\Trigger (itself a Node), so it has the same type() /
label() / schema() descriptors, plus:
handle(WorkflowContext $context, array $config = []): TriggerResult— decides whether an incoming payload should start an execution.register(Workflow $workflow): void— wires up whatever delivers events for a given workflow (a route, a cron entry, a model listener). Called once per workflow using this trigger, at application boot.
Generate one
php artisan workflow:make-node StripeEventTrigger --trigger --type=app::stripe-event
namespace App\Workflows\Triggers;
use Qanna\WorkflowEngine\Engine\Context\WorkflowContext;
use Qanna\WorkflowEngine\Engine\Schema\Schema;
use Qanna\WorkflowEngine\Models\Workflow;
use Qanna\WorkflowEngine\Trigger;
use Qanna\WorkflowEngine\TriggerResult;
class StripeEventTrigger extends Trigger
{
public static function type(): string
{
return 'app::stripe-event';
}
public static function label(): string
{
return 'Stripe event';
}
public static function schema(): array
{
return [
Schema::select('event')->options([
'invoice.paid' => 'Invoice paid',
'customer.subscription.deleted' => 'Subscription cancelled',
])->required(),
];
}
public function handle(WorkflowContext $context, array $config = []): TriggerResult
{
$payload = $context->get('payload');
if (($payload['type'] ?? null) !== $config['event']) {
return TriggerResult::ignore('event type mismatch');
}
return TriggerResult::continue($payload);
}
protected function register(Workflow $workflow): void
{
// e.g. nothing to do — your existing Stripe webhook controller calls
// Workflow::run($workflow->id, $stripeEvent) for every matching workflow.
}
}
TriggerResult
| Constructor | Meaning |
|---|---|
TriggerResult::continue($output = null) | Start an execution. $output is recorded as the trigger step's output. |
TriggerResult::ignore($reason = null) | Don't start. Workflow::run() returns null; a workflow.trigger-ignored hook fires with the reason. |
The engine resolves {{ }} expressions in the trigger's saved config before
calling handle(), the same as it does for nodes.
register()
Runs at boot for every workflow whose trigger type matches. Use it to subscribe to the outside world. The built-in triggers show the patterns:
- Webhook registers a
POSTroute per workflow. - Schedule adds an entry to Laravel's scheduler.
- Model event attaches Eloquent event listeners.
Because this happens at boot, a newly saved workflow's trigger is not wired up until the next boot — your app and queue workers must be restarted. The interactive builder reminds you of this.
Registering the trigger
use Qanna\WorkflowEngine\Engine\NodeRegistry;
$this->app->make(NodeRegistry::class)->register([
\App\Workflows\Triggers\StripeEventTrigger::class,
], 'trigger');
Registering under the 'trigger' category is what makes the engine call the
trigger's register() at boot and offer it in workflow:build.