fluentcrm-funnel-trigger
FluentCRM: register a custom funnel trigger
For developers building a companion plugin that needs to start a FluentCRM automation when something happens (course enrolled, SaaS webhook arrived, custom CPT published, third-party event). Extends FluentCrm\App\Services\Funnel\BaseTrigger and registers via the fluentcrm_funnel_triggers filter chain. This skill maps the contract verified end-to-end against FluentCRM 3.1.8 source, with the lifecycle order written out in full because timing is where this contract silently breaks.
API stability note
The BaseTrigger abstract class, the fluentcrm_funnel_triggers / fluentcrm_funnel_start_* / fluentcrm_funnel_editor_details_* / fluentcrm_funnel_arg_num_* hook family, and the FunnelProcessor::startFunnelSequence() entry point have been stable across the 2.7+ line. In FluentCRM 3.1.8, active trigger listeners are registered by FunnelHandler::registerEarlyActiveTriggers() on init:2 when the arg-count filter is already present, with a fallback registerActiveTriggers() pass on init:20.
Misconception this skill corrects
"I'll register my trigger on
fluent_crm/after_initlike the other addons do — it's a clean post-boot hook."
Wrong hook. fluent_crm/after_init runs on init priority 1000 (boot/app.php). In 3.1.8, FluentCRM's FunnelHandler registers core funnel items on init:1, then performs an early active-trigger listener pass on init:2 and a fallback pass on init:20. The early pass only registers trigger listeners whose fluentcrm_funnel_arg_num_{name} filter already exists. By the time fluent_crm/after_init fires, both listener passes have already run.
The visible bug: a trigger like lw_lms_after_grant (which fires with 5 args) either misses events fired during init:10, or gets only $user_id delivered if the fallback listener captured the default arg count. $courseId = (int) ($originalArgs[1] ?? 0) becomes 0. Any guard if ($courseId <= 0) return; silently drops every event.
The fix is one line: instantiate your BaseTrigger subclass on fluentcrm_loaded priority 5 instead of fluent_crm/after_init. FluentCampaign Pro registers its funnel items on init:1, which lands before the init:2 early active-trigger pass.
Other AI-prone misconceptions: