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_channelandwidget_rulerows 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 |