Automation & Funnel Filters
FluentCRM Core IntermediateThese filter hooks let you customize automation funnels — trigger registration, block definitions, processing limits, delays, and sequence behavior.
Funnel Registration
fluentcrm_funnel_triggers
Filter the array of all registered funnel trigger definitions. Use this to add custom automation triggers.
Parameters
$triggersArray - Default[]
Usage:
add_filter('fluentcrm_funnel_triggers', function($triggers) {
$triggers['my_custom_trigger'] = [
'category' => 'Custom',
'label' => __('My Custom Trigger', 'fluent-crm'),
'description' => 'Fires when a custom event occurs'
];
return $triggers;
});TIP
This runs anywhere the trigger catalogue is assembled — the funnel editor, the dashboard, the MCP context tools and the Pro data exporter. Register triggers unconditionally rather than gating on the current screen.
Source: app/Http/Controllers/FunnelController.php, app/Http/Controllers/DashboardController.php, app/Modules/MCP/Tools/FunnelTools.php, app/Modules/MCP/Tools/ContextTools.php, fluentcampaign-pro/app/Hooks/Handlers/DataExporter.php
fluentcrm_funnel_blocks
Filter all funnel step block definitions available in the funnel editor.
Parameters
$blocksArray - Default[]$funnelFunnel Model
Usage:
add_filter('fluentcrm_funnel_blocks', function($blocks, $funnel) {
$blocks['my_action'] = [
'category' => 'Custom',
'label' => __('My Custom Action', 'fluent-crm'),
'description' => 'Does something custom',
'type' => 'action'
];
return $blocks;
}, 10, 2);WARNING
$funnel is null when the MCP context tools build the block catalogue with no funnel in scope, and a plain stdClass cast rather than a Funnel model when the Pro data exporter calls it. Guard before reading properties off it.
Source: app/Http/Controllers/FunnelController.php, app/Modules/MCP/Tools/ContextTools.php, fluentcampaign-pro/app/Hooks/Handlers/DataExporter.php
fluentcrm_funnel_block_fields
Filter custom field definitions for funnel step blocks in the editor UI.
Parameters
$fieldsArray - Default[]$funnelFunnel Model
Usage:
add_filter('fluentcrm_funnel_block_fields', function($fields, $funnel) {
$fields['my_action'] = [
'title' => 'My Action Settings',
'fields' => [
'message' => [
'type' => 'text',
'label' => 'Message'
]
]
];
return $fields;
}, 10, 2);Source: app/Http/Controllers/FunnelController.php, fluentcampaign-pro/app/Hooks/Handlers/DataExporter.php
fluent_crm_funnel_context_smart_codes
Filter the smart codes available in the funnel email composer for a specific trigger context.
Parameters
$smartCodesArray - Default[]$triggerNameString - The funnel trigger name$funnelFunnel Model
Usage:
add_filter('fluent_crm_funnel_context_smart_codes', function($smartCodes, $triggerName, $funnel) {
if ($triggerName === 'my_custom_trigger') {
$smartCodes[] = [
'key' => '{{trigger.order_id}}',
'title' => 'Order ID'
];
}
return $smartCodes;
}, 10, 3);Source: app/Http/Controllers/FunnelController.php
fluent_crm/funnel_icons
Filter the funnel trigger category icons (SVG paths or Element Plus icon class strings).
Parameters
$iconsArray - Associative array ofslug => icon
Usage:
add_filter('fluent_crm/funnel_icons', function($icons) {
$icons['my_category'] = '<svg>...</svg>';
return $icons;
});Source: app/Hooks/Handlers/AdminMenu.php
fluent_crm/funnel_label_color
Filter the array of available label colors for funnel steps.
Parameters
$colorsArray - Color hex values
Usage:
add_filter('fluent_crm/funnel_label_color', function($colors) {
$colors[] = '#FF5733';
return $colors;
});Source: app/Services/Helper.php
Processing & Limits
fluent_crm/funnel_subscriber_statuses
Filter which funnel-subscriber statuses the processor picks up each cycle. Only rows on a published funnel of type funnels whose next_execution_time is due are considered — this filter narrows that set by status.
Parameters
$statusesArray - Default['active']
Usage:
add_filter('fluent_crm/funnel_subscriber_statuses', function($statuses) {
$statuses[] = 'paused';
return $statuses;
});Source: app/Services/Funnel/FunnelProcessor.php
fluent_crm/funnel_processor_batch_limit
Filter the maximum number of funnel subscribers processed in a single processor run.
Parameters
$limitINT - Default200. Values below1are clamped to1.
Usage:
add_filter('fluent_crm/funnel_processor_batch_limit', function($limit) {
return 500;
});Source: app/Services/Funnel/FunnelProcessor.php
fluent_crm/funnel_processor_max_processing_seconds
Filter the hard time limit (seconds) for the funnel processor per run.
Parameters
$secondsINT - Default55. Values below1are clamped to1.
Usage:
add_filter('fluent_crm/funnel_processor_max_processing_seconds', function($seconds) {
return 30;
});Source: app/Services/Funnel/FunnelProcessor.php
fluent_crm/funnel_seq_delay_in_seconds
Filter the computed delay (in seconds) for a funnel sequence step. This applies to wait/delay steps, custom field date-based delays, and more.
Parameters
$waitTimeSecondsINT - Computed delay in seconds$settingsArray - Step settings$sequenceObject - Sequence data$funnelSubIdINT - Funnel subscriber ID; may be0/empty for a step evaluated outside a contact's run
Usage:
add_filter('fluent_crm/funnel_seq_delay_in_seconds', function($waitTime, $settings, $sequence, $funnelSubId) {
// Add an extra 1-hour buffer to all delays
return $waitTime + 3600;
}, 10, 4);Source: app/Services/Funnel/FunnelHelper.php
Trigger Gates & Sequence Hooks
fluentcrm_funnel_will_process_{$triggerName}
Dynamic filter to gate whether a funnel should be triggered for a specific event. Return false to prevent the funnel from firing.
Parameters
$willProcessBoolean - Defaulttrue$funnelFunnel Model$subscriberDataArray - Contact data$originalArgsArray - Original trigger arguments
Usage:
add_filter('fluentcrm_funnel_will_process_user_registration', function($willProcess, $funnel, $subscriberData, $originalArgs) {
// Only process for specific roles
if ($subscriberData['role'] !== 'subscriber') {
return false;
}
return $willProcess;
}, 10, 4);Source: Every trigger class that implements a willProcess() gate — app/Services/Funnel/Triggers/, app/Services/ExternalIntegrations/FluentCart/Triggers/, and the Pro integration triggers under fluentcampaign-pro/app/Services/Integrations/
fluentcrm_funnel_editor_details_{$triggerName}
Dynamic filter to enrich the Funnel object before it is returned to the editor. Use this to inject extra properties or computed data.
Parameters
$funnelFunnel Model
Usage:
add_filter('fluentcrm_funnel_editor_details_my_trigger', function($funnel) {
$funnel->extra_options = ['option1', 'option2'];
return $funnel;
});Source: app/Hooks/Handlers/FunnelHandler.php, app/Http/Controllers/FunnelController.php
fluentcrm_funnel_sequence_saving_{$actionName}
Dynamic filter to transform or validate a funnel sequence step before it is saved. The {$actionName} is the step's action type slug.
Parameters
$sequenceArray - Sequence step data$funnelFunnel Model
Usage:
add_filter('fluentcrm_funnel_sequence_saving_my_action', function($sequence, $funnel) {
// Validate or transform the sequence settings
$sequence['settings']['validated'] = true;
return $sequence;
}, 10, 2);Source: app/Services/Funnel/FunnelHelper.php, app/Http/Controllers/FunnelController.php
fluent_crm/webhook_ssl_verify
Control whether SSL is verified for the Send Test Webhook request fired from the funnel editor.
WARNING
This does not affect live webhook sends. The HTTP webhook automation action verifies SSL through Fluent Forms' ff_webhook_ssl_verify filter, which defaults to false. Filter that hook instead if you need to change verification for real automation traffic.
Parameters
$verifyBoolean - Defaulttrue
Usage:
add_filter('fluent_crm/webhook_ssl_verify', function($verify) {
return false; // Skip verification when testing against a self-signed endpoint
});Source: app/Http/Controllers/FunnelController.php
Conditions & A/B Testing
Profluentcrm_automation_condition_groups
Filter the available condition groups for automation rules. Fired by the Pro conditional block and by the abandoned-cart automation triggers, including the FluentCart abandoned-cart driver that ships in core.
TIP
This hook only registers the group in the UI. At run time, a group that is not one of the built-in ones is evaluated through fluentcrm_automation_conditions_assess_{$groupName} — implement that too, or your group always passes.
Parameters
$groupsArray - condition group definitions$funnelFunnel Model
Usage:
add_filter('fluentcrm_automation_condition_groups', function($groups, $funnel) {
$groups[] = [
'value' => 'my_custom_group',
'label' => 'My Custom Conditions'
];
return $groups;
}, 10, 2);Source: fluentcampaign-pro/app/Services/Funnel/Conditions/FunnelCondition.php, fluentcampaign-pro/app/Modules/AbandonCart/Woo/AbandonCartAutomationTrigger.php, app/Modules/AbandonCart/Drivers/FluentCart/FluentCartAutomationTrigger.php
fluentcrm_automation_custom_conditions
Filter custom condition options for automation rules.
Parameters
$conditionsArray - condition definitions$funnelFunnel Model
Usage:
add_filter('fluentcrm_automation_custom_conditions', function($conditions, $funnel) {
$conditions['has_membership'] = [
'label' => 'Has Active Membership',
'type' => 'yes_no_check'
];
return $conditions;
}, 10, 2);Source: fluentcampaign-pro/app/Services/Funnel/Conditions/FunnelCondition.php
fluentcrm_automation_custom_condition_assert_{$propertyName}
Dynamic filter to evaluate a custom automation condition. Return true or false to pass or fail the condition. It is also consulted by the abandoned-cart runner when it re-evaluates conditions.
WARNING
The default is true, so an unhandled property name passes the condition rather than failing it. When the abandoned-cart runner calls this filter, $sequence and $funnelSubscriberId are both null — guard for that before dereferencing them.
Parameters
$resultBoolean - Defaulttrue$conditionArray - condition config$subscriberSubscriber Model$sequenceFunnelSequence Model -nullwhen called from the abandoned-cart runner$funnelSubscriberIdINT - funnel subscriber ID;nullwhen called from the abandoned-cart runner
Usage:
add_filter('fluentcrm_automation_custom_condition_assert_has_membership', function($result, $condition, $subscriber) {
return user_has_membership($subscriber->user_id);
}, 10, 3);Source: fluentcampaign-pro/app/Services/Funnel/Conditions/FunnelCondition.php, app/Modules/AbandonCart/AbandonCartRunner.php
fluentcrm_automation_conditions_assess_{$groupName}
Dynamic filter that evaluates one condition group of an automation conditional split for a contact. Return true to pass the group, false to fail it. The dynamic portion, $groupName, is the value the group was registered under on fluentcrm_automation_condition_groups.
The built-in groups — subscriber, custom_fields, segment, activities, event_tracking and other — are assessed internally and never reach this filter (single conditions inside other go through fluentcrm_automation_custom_condition_assert_{$propertyName} instead, keyed by the condition's data_key). Everything else is dispatched here, which is how the Pro integrations (WooCommerce, EDD, LearnDash, LifterLMS, TutorLMS, PMPro, RCP, Wishlist Member, AffiliateWP) and the core FluentCart integration plug in their purchase/enrollment conditions. Within one condition set every group must pass (AND); multiple condition sets are OR-ed, and the contact goes down the "No" path of the split only when every set fails.
WARNING
The default is true, so a group name nobody handles passes silently. And as with fluentcrm_automation_custom_condition_assert_{$propertyName}: when the abandoned-cart runner calls this filter, $sequence and $funnelSubscriberId are both null — guard for that before dereferencing them. Most implementations register with 10, 3 and ignore the last two arguments entirely.
Parameters
$resultBoolean - Defaulttrue$groupArray - the conditions of this group, each carryingdata_key,operatorandvalue(plusproperty,extra_valueanddata_valuewhere set)$subscriberSubscriber Model$sequenceFunnelSequence Model - the conditional split step;nullwhen called from the abandoned-cart runner$funnelSubscriberIdINT - funnel subscriber ID;nullwhen called from the abandoned-cart runner
Usage:
add_filter('fluentcrm_automation_conditions_assess_my_group', function($result, $group, $subscriber) {
foreach ($group as $condition) {
if (!my_plugin_condition_matches($condition, $subscriber)) {
return false;
}
}
return true;
}, 10, 3);Source: fluentcampaign-pro/app/Services/Funnel/Conditions/FunnelCondition.php, app/Modules/AbandonCart/AbandonCartRunner.php
fluent_crm/funnel_ab_test_is_b
Determines whether a contact falls into the B variant of an automation A/B test. The unfiltered value is a weighted coin flip using the step's path_a / path_b split percentages (both default 50).
The third argument changed — breaking
FluentCampaign Pro 3.1.10 and earlier passed $sequence twice, so the contact was unreachable and per-contact bucketing was impossible. The duplicate has been dropped: the third argument is now the subscriber, and the funnel-subscriber id was added as a fourth. A callback that read the third argument as a sequence must be updated.
Parameters
$isBBoolean - whether this contact gets variant B$sequenceFunnelSequence Model - the A/B test step; read$sequence->settingsfor the split percentages$subscriberSubscriber Model - the contact being bucketed$funnelSubscriberIdINT - the funnel subscriber row id
Usage:
add_filter('fluent_crm/funnel_ab_test_is_b', function($isB, $sequence, $subscriber) {
// Stable bucketing: the same contact always lands in the same variant
return (crc32($subscriber->email) % 100) >= (int) ($sequence->settings['path_a'] ?? 50);
}, 10, 3);Source: fluentcampaign-pro/app/Services/Funnel/Conditions/FunnelABTesting.php
fluent_crm/event_tracking_condition_groups
Filter condition groups available for event tracking automation triggers.
Parameters
$groupsArray - condition groups
Usage:
add_filter('fluent_crm/event_tracking_condition_groups', function($groups) {
$groups[] = [
'value' => 'event_custom',
'label' => 'Custom Event Conditions'
];
return $groups;
});Source: fluentcampaign-pro/app/Services/Funnel/Triggers/TrackingEventRecordedTrigger.php
fluent_crm/http_webhook_body
Filter the request body sent to external webhooks in HTTP webhook automation actions. Smart codes in the configured body have already been parsed for the contact when this runs.
TIP
An empty body short-circuits the step before this filter — the step is marked skipped with a "No valid body data found" note. Use this filter to enrich a body, not to create one from nothing. On a GET step, the returned array becomes the query string rather than a request body.
Parameters
$bodyArray - request body, never empty$sequenceFunnelSequence Model - the webhook step$subscriberSubscriber Model
Usage:
add_filter('fluent_crm/http_webhook_body', function($body, $sequence, $subscriber) {
$body['custom_field'] = $subscriber->custom_values['my_field'] ?? '';
return $body;
}, 10, 3);Source: fluentcampaign-pro/app/Services/Funnel/Actions/HTTPSendDataAction.php