Contents

Hooks reference - Plugixa Chat

The plugin fires 19 actions and 31 filters, all prefixed plugixa_chat_. All of them are part of the free edition. The Pro features are built on the same hooks and add none of their own.

It also dispatches two events in the visitor’s browser, listed under Browser events.

Hooks marked internal exist so the plugin’s own parts can talk to each other. They are listed for completeness. Their arguments can change between versions, so prefer the others.

The ones you are most likely to want

Hook Type What it is for
plugixa_chat_lead_created action React to a new contact form message
plugixa_chat_lead_email filter Change the notification email: recipients, subject, body, headers
plugixa_chat_lead_errors filter Add your own validation to the contact form
plugixa_chat_channels filter Add a channel to the catalogue, or change a built-in one
plugixa_chat_merge_tags filter Add your own merge tags
plugixa_chat_should_render filter Keep the widget off a request the rules cannot describe
plugixa_chat_config_invalidated action Purge your page cache when a widget or setting changes
plugixa_chat_visitor_country filter Supply the visitor’s country for Pro country rules
plugixa_chat_behind_proxy filter Tell the plugin the site is behind a trusted reverse proxy

Actions

Lifecycle

Action When it fires Arguments
plugixa_chat_fs_loaded When the Freemius SDK, which handles licensing and updates, has been set up None
plugixa_chat_loaded Once the plugin has finished starting, on plugins_loaded $container: the plugin’s service container
plugixa_chat_activated On activation, after the tables exist None
plugixa_chat_deactivated On deactivation, before anything else None
plugixa_chat_uninstall During uninstall, before the tables are dropped None
plugixa_chat_migration_failed When a database update did not finish $failures: an array keyed by the part of the plugin that failed, each with tables and reason
add_action( 'plugixa_chat_loaded', function ( $container ) {
	// Plugixa Chat is present and booted.
} );

Admin and REST

Action When it fires Arguments
plugixa_chat_admin_submenus While the admin menu is built, after the Dashboard entry $parent_slug (string, plugixa-chat), $render (the callable that draws the app)
plugixa_chat_enqueue_assets On the plugin’s admin screen, after its own files are enqueued $hook_suffix (string)
plugixa_chat_register_rest_routes On rest_api_init, after the plugin’s own routes $namespace (string, plugixa-chat/v1), $container

Settings and the front-end data

Action When it fires Arguments
plugixa_chat_settings_saved After the settings are saved $settings (array): the saved settings
plugixa_chat_config_invalidated Whenever the data the widget reads has to be rebuilt: a widget, channel, rule, agent or A/B test changed, or the settings were saved None

plugixa_chat_config_invalidated is the place to purge a page cache. The plugin purges none itself.

add_action( 'plugixa_chat_config_invalidated', function () {
	if ( function_exists( 'rocket_clean_domain' ) ) {
		rocket_clean_domain();
	}
} );

Leads

plugixa_chat_lead_created

Fires after a contact form message has been stored, before the notification email is sent.

Argument Type Meaning
$lead array The stored lead: id, widget_id, channel_slug, name, email, phone, message, consent, subscribed, page_url, status, created_at. The IP value is not included
$widget array The widget row the form belongs to, including id and name
$fields array The cleaned values the visitor submitted, keyed by field name. In Pro this includes answers to your own questions, keyed f1, f2 and so on
add_action( 'plugixa_chat_lead_created', function ( $lead, $widget, $fields ) {
	if ( $lead['subscribed'] ) {
		my_newsletter_add( $lead['email'], $lead['name'] );
	}
}, 10, 3 );

Records

Every record the plugin stores is written through one layer, which fires the same six actions for all of them.

Action When it fires Arguments
plugixa_chat_entity_created After a row is inserted $entity, $id, $row (the row as written)
plugixa_chat_entity_updated After a row is updated $entity, $id, $row (the columns that changed)
plugixa_chat_entity_trashed After a row is moved to the trash $entity, $id
plugixa_chat_entity_restored After a row is restored from the trash $entity, $id
plugixa_chat_before_purge Just before a row is deleted for good $entity, $id, $row
plugixa_chat_entity_purged After a row is deleted for good $entity, $id, $row

$entity is one of widget, widget_channel, widget_rule, lead, and in Pro agent, webhook, crm_connection and experiment.

Two things to know:

  • Saving a widget replaces its channels and rules. Each save purges the old widget_channel and widget_rule rows and creates new ones, so those entities fire often.
  • The daily retention task deletes old leads directly and does not fire these actions.
add_action( 'plugixa_chat_entity_trashed', function ( $entity, $id ) {
	if ( 'lead' === $entity ) {
		error_log( "Lead {$id} was deleted." );
	}
}, 10, 2 );

An action you fire

plugixa_chat_require_runtime

Fire this from your own front-end code to ask for the widget’s script on a page where no widget is shown. The plugin fires it itself for chat buttons. It takes no arguments.

do_action( 'plugixa_chat_require_runtime' );

Filters

Rendering

Filter Value Other arguments Purpose
plugixa_chat_should_render $render (bool, default true) None Return false to keep the widget off the current request
plugixa_chat_runtime_needed $needed (bool, default false) None Return true to load the widget’s script on a page with no widget
plugixa_chat_launcher_icon $markup (string, default empty) $appearance (array) The markup of a custom launcher icon for the pre-drawn button. The result is limited to SVG shapes and an image
plugixa_chat_widget_strings $strings (array) None The words the widget supplies itself, such as open, panel, dismiss, back and the form’s labels. Runs on every page view
plugixa_chat_unevaluable_rule $show (bool) $kind (string), $site_mode (open or closed) Whether a visitor rule that could not be checked counts as matching
plugixa_chat_max_widgets $max (int, default 0) None A ceiling on the number of widgets. 0 means no limit
// Never show the widget to logged-in editors.
add_filter( 'plugixa_chat_should_render', function ( $render ) {
	return current_user_can( 'edit_posts' ) ? false : $render;
} );

Remember page caches when using plugixa_chat_should_render: the answer is baked into whatever page is cached. Use it for things that are true for every visitor of a page.

// Treat a failed "Signed in" check as not matching, so a members-only
// widget stays hidden when the check cannot be made.
add_filter( 'plugixa_chat_unevaluable_rule', function ( $show, $kind ) {
	return 'logged_in' === $kind ? false : $show;
}, 10, 2 );

The kinds are logged_in, referrer, schedule, country, language, role, visits, device and ab.

The widget’s data

The data a page’s widget reads is built in two stages. The first is cached for the whole site until something is saved. The second runs on every page view.

Filter Value Other arguments Stage
plugixa_chat_compile_widgets $widgets (array of widgets, each with id, appearance, channels, rules) None Cached. Internal
plugixa_chat_compile_channel $row (array): one channel as it will be sent $definition (the channel’s catalogue entry), $channel (the stored row) Cached
plugixa_chat_compile_channel_settings $data (array): a panel channel’s data $slug (string), $channel (array) Cached
plugixa_chat_channel_ready $ready (bool) $definition, $channel Cached. Whether a channel has what it needs to be shown
plugixa_chat_prepare_widget $widget (array) None Per page view, for each widget that passed its page rules
plugixa_chat_payload $payload (array): widgets, apiUrl, failMap, tokens, i18n, track None Per page view. Add keys; do not remove the existing ones

Anything that is the same for every visitor belongs in the cached stage. Anything that names the page belongs in the per-page stage. Work done in the per-page stage is paid on every page view.

Channels

plugixa_chat_channels

Filters the catalogue. Add an entry and it appears in the picker, in the builder and in the widget.

Key Meaning
slug A unique lower-case name. A slug that matches a built-in channel replaces it
label The channel’s name
group messaging, contact, location, booking, social or custom
color The brand colour, as six hex digits
input What the destination is: url, email, phone, username, id or none
link The link template. {value} is replaced with the destination and {message} with the pre-filled message
normalize How the destination is tidied: none, digits, tel, handle or messenger
placeholder, help Shown in the builder
pattern A regular expression the destination should match. The builder warns when it does not
supports A list. message offers the pre-filled message field; qr offers the QR code on computers
brand The name of a bundled brand logo
add_filter( 'plugixa_chat_channels', function ( $channels ) {
	$channels[] = array(
		'slug'        => 'helpdesk',
		'label'       => 'Help centre',
		'group'       => 'custom',
		'color'       => '#334155',
		'input'       => 'url',
		'link'        => '{value}',
		'placeholder' => 'https://help.example.com',
		'help'        => 'The address of your help centre.',
	);

	return $channels;
} );

Entries must be plain arrays of strings and lists. Do not put a closure in one.

Filter Value Purpose
plugixa_chat_channel_panels $slugs (array of strings) The slugs of channels that open a panel instead of a link. A channel with no link exists only when its slug is in this list. Internal
plugixa_chat_merge_tags $values (array, tag => value), with $post_id (int) The merge tags for the current page
add_filter( 'plugixa_chat_merge_tags', function ( $values, $post_id ) {
	$values['{author}'] = get_the_author_meta( 'display_name', (int) get_post_field( 'post_author', $post_id ) );

	return $values;
}, 10, 2 );

Keys include the braces. Values are treated as plain text.

Leads

Filter Value Other arguments Purpose
plugixa_chat_lead_errors $errors (array, field name => message) $fields (the cleaned submission), $settings (the form’s settings) Add or remove validation errors. A non-empty result refuses the message and shows each error under its field
plugixa_chat_lead_email_lines $lines (array of strings) $lead (array) Extra lines for the body of the notification email, placed after the message
plugixa_chat_lead_email $email (array with to, subject, body, headers) $lead (array) The whole notification email, just before it is sent
// Refuse one email domain.
add_filter( 'plugixa_chat_lead_errors', function ( $errors, $fields ) {
	if ( str_ends_with( strtolower( $fields['email'] ?? '' ), '@example.org' ) ) {
		$errors['email'] = 'Please use your work email address.';
	}

	return $errors;
}, 10, 2 );
// Send leads from one widget to a different inbox.
add_filter( 'plugixa_chat_lead_email', function ( $email, $lead ) {
	if ( 3 === (int) $lead['widget_id'] ) {
		$email['to'] = array( 'sales@example.com' );
	}

	return $email;
}, 10, 2 );

The field names are name, email, phone, message and consent.

The visitor

Filter Value Other arguments Purpose
plugixa_chat_visitor_country $country (string): a two-letter code in capitals, or empty $ip (string): the visitor’s address The visitor’s country, for Pro country rules
plugixa_chat_behind_proxy $behind_proxy (bool) None Whether to trust the proxy headers for the visitor’s address
add_filter( 'plugixa_chat_visitor_country', function ( $country, $ip ) {
	return '' !== $country ? $country : my_geoip_lookup( $ip );
}, 10, 2 );

By default the plugin uses the address of the connection itself. Behind a reverse proxy that is the proxy’s address, so every visitor shares one rate limit. When the site is behind a proxy you trust, switch the proxy headers on, either with the filter or with the constant below. The headers read are CF-Connecting-IP, True-Client-IP, X-Real-IP and X-Forwarded-For, in that order.

Do not switch this on for a site that visitors can reach directly, because then anyone can send those headers.

Permissions

Filter Value Other arguments Purpose
plugixa_chat_user_can $allowed (bool) $action (read, create, edit, delete, export or reply), $entity_type (string), $record (array or null), $user_id (int) The final say on whether a user may perform an action
plugixa_chat_capabilities $map (array, name => bool) None The permissions handed to the admin app, which uses them to hide controls. It does not grant anything by itself

Settings

Filter Value Purpose
plugixa_chat_settings_defaults $defaults (array) The default settings
plugixa_chat_settings_choices $choices (array) The lists the Settings screen offers. Internal

A key added to the defaults is read by PlugixaChat\Core\Settings::get(), but a value for it is stored from the Settings screen only if the plugin has a cleaner for it.

The admin app

All internal.

Filter Value Purpose
plugixa_chat_admin_config $config (array) The data printed for the admin app
plugixa_chat_config_settings_keys $keys (array of strings) Which settings are included in that data
plugixa_chat_admin_i18n_strings $strings (array, key => text) The admin app’s labels
plugixa_chat_modules $classes (array of class names) The parts of the plugin that are loaded

Data and REST

All internal.

Filter Value Other arguments Purpose
plugixa_chat_filter_output $data (mixed) $entity_type (string) The data of every successful REST response
plugixa_chat_query_clauses $wheres (array of SQL conditions) $table (string) The conditions of every list query. Return only fragments you wrote yourself, never request data
plugixa_chat_search_columns $columns (array of column references) $table (string) The columns a list’s search looks in

Browser events

The widget dispatches two DOM events. Both bubble, so you can listen on document.

Event When event.detail
plugixa_chat_channel_click A visitor presses a channel in the widget, a chat button in your content, or the product button widget (number), channel (string). For buttons outside the widget, also placement: inline or product
plugixa_chat_lead A contact form message has been accepted widget (number), channel (string)
document.addEventListener( 'plugixa_chat_channel_click', function ( event ) {
	console.log( event.detail.channel, event.detail.widget );
} );

Use plugixa_chat_channel_click when you want to run your own code on a press. A channel’s destination cannot be a javascript: link.

Constant

Constant Meaning
PLUGIXA_CHAT_BEHIND_PROXY Set to true in wp-config.php when the site is behind a reverse proxy you trust. It has the same effect as returning true from plugixa_chat_behind_proxy
define( 'PLUGIXA_CHAT_BEHIND_PROXY', true );

Scheduled hooks

These are WordPress cron hooks the plugin schedules. They are listed so you can recognise them in a cron manager, not as extension points.

Hook Schedule Edition
plugixa_chat_prune_leads Daily Free
plugixa_chat_prune_events Daily Free
plugixa_chat_webhook_deliver Once per delivery Pro PRO
plugixa_chat_crm_deliver Once per delivery Pro PRO

What to do next

  • Script the plugin over HTTP with the REST API.
  • Receive leads in another system without code, using Webhooks PRO.

Quick Links