fluentcrm-funnel-benchmark
FluentCRM: register a custom funnel benchmark
For developers building a funnel wait point — a node placed inside an automation that pauses the contact until a specific event matches the configured criteria (tag applied, course completed, payment received, custom event from your plugin). Unlike a trigger (which STARTS a funnel) or an action (which DOES something), a benchmark gates progress mid-flow. Extends FluentCrm\App\Services\Funnel\BaseBenchMark. Verified against FluentCRM 3.1.8.
API stability note
BaseBenchMark, the registration triplet (fluentcrm_funnel_blocks + fluentcrm_funnel_block_fields + fluentcrm_funnel_benchmark_start_{name}), the assertCurrentGoalState filter, and FunnelProcessor::startFunnelFromSequencePoint() have been stable since FluentCRM 2.6.0 (when goal-state assertion was introduced). The Optional vs Essential semantics and the can_enter direct-entry mechanism are part of that 2.6 baseline.
Misconception this skill corrects
"Benchmarks are special wait nodes — they have their own action listener separate from triggers."
Wrong. Benchmarks listen on the same WP action as triggers — FunnelHandler::mapTriggers() handles both in one pass. After dispatching fluentcrm_funnel_start_{triggerName} for matching trigger funnels, it queries FunnelSequence for benchmark sequences with action_name === $triggerName whose funnel is published, and dispatches fluentcrm_funnel_benchmark_start_{triggerName} for each.
Practical consequences:
- The same
fluentcrm_funnel_arg_num_{name}filter timing rule applies. Instantiate onfluentcrm_loadedpriority below 10. Hook onfluent_crm/after_initand your benchmark misses both active-trigger listener passes; hook too late ininitand events fired by otherinitcallbacks can be missed or reduced to the default one accepted arg. triggerNamecollision is fine between a trigger and a benchmark — they coexist on the same action.TagAppliedBenchmark::triggerName = 'fluentcrm_contact_added_to_tags'is used by both the trigger flow ("Tag Applied" trigger that starts a funnel) and the benchmark flow ("Tag Applied" wait point).fluentcrm_funnel_settingsoption lifecycle includes benchmarks.resetFunnelIndexes()queries published-funnel benchmark sequences — saving a funnel that uses your benchmark adds the trigger name to the listener registry.