Developer Reference: Filters & Actions
Super Speedy Emails exposes a set of WordPress filters and actions so you can extend its behaviour from your own plugin, mu-plugin, or theme without modifying the plugin. This page is the complete reference for those hooks. For the database schema, PHP classes, and the sse_send() API, see the main Developer Reference.
Table of Contents
Quick reference
| Hook | Type | Purpose |
|---|---|---|
sse_send() | function | Queue a single email from your own code. |
sse_should_send_support_email | filter | Per-product: is there news to send? (default true) |
sse_support_email_subject | filter | Override the support email subject (optional). |
sse_support_email_content | filter | The body of a support email (returns { body, name }). |
sse_support_email_should_send_to_user | filter | Per-owner: should this person receive it? |
sse_support_email_sent | action | Fires per queued support email (real sends only). |
sse_changelog_product_map | filter | (Companion plugin) map product IDs to plugin slugs. |
sse_support_assets_dir | filter | (Companion plugin) where the changelog reader looks for files. |
sse_templates_registry | filter | Add or override email templates. |
sse_confirmation_ttl_days | filter | Double opt-in link lifetime. |
sse_automation_triggers | filter | Register custom automation trigger types. |
The sse_send() function
The public entry point for sending a single email from another plugin. It runs the suppression gate, creates a log entry, and queues the message for delivery.
$result = sse_send( array(
'email' => 'customer@example.com',
'subject' => 'Your licence expires soon',
'body_text' => "Hi {{first_name}},
Your licence expires in 7 days...",
'category' => 'product_marketing', // governs the suppression rules
'unsubscribe_url' => $your_unsubscribe_url, // optional; sets List-Unsubscribe
'source_plugin' => 'my-renewals-plugin',
'source_reference' => 'renewal:order:12345', // your own tag for dedup/audit
) );
if ( is_wp_error( $result ) ) {
// Blocked by a suppression, or an invalid address.
} else {
// $result is the email log row ID.
}
It returns the log row ID on success, or a WP_Error if the address is invalid or suppressed for that category. Full argument documentation is in the Developer Reference. The hooks below are mostly about the automated support-email system, which is the main extension surface.
Support-email hooks
These power the Automated Support & Changelog Emails feature. The engine is generic; these hooks supply the policy. Every callback receives the running value plus a single SSE_Support_Context $context — see the Developer Guide for the full object. $context->product_id is always set; $context->subscriber is null in the per-product probe and set per recipient at send; $context->is_preview is true during the admin Preview (your filters must be side-effect-free then).
There is no
sse_support_email_product_idsfilter — the products a support email covers are the admin’s checklist on the Support Email record.
sse_should_send_support_email (filter) — per product
Runs once per product, before owners are loaded. Return true if there’s news worth sending. Default true. Guard any state write with $context->is_preview.
add_filter( 'sse_should_send_support_email', function ( $should, $context ) {
// $context->product_id set; $context->is_preview true during Preview
return $should; // false → skip this product (no owners loaded)
}, 10, 2 );
sse_support_email_subject (filter) — optional
Runs per product (and per recipient at send). Return a string to override the GUI subject. Most implementations skip this and set the subject in the GUI with a {product_name} token.
add_filter( 'sse_support_email_subject', function ( $subject, $context ) {
return $subject;
}, 10, 2 );
sse_support_email_content (filter) — per product
Runs per product (and per recipient at send). Return { body, name }. The incoming $content holds the GUI defaults — return it to keep them; an empty body sends nothing for that product.
add_filter( 'sse_support_email_content', function ( $content, $context ) {
return array(
'body' => "Hi {first_name},
Here's what changed...
- Faster cache warmup",
'name' => 'Scalability Pro', // human name for the footer
);
}, 10, 2 );
Per-recipient tokens ({first_name}, {unsubscribe_url}, {manage_url}, {product_name}, {email}, {site_name}, {site_url}) are filled by the engine (double-brace {{...}} is also accepted for back-compat). A subject key here is honoured only as a fallback. There is no reference key — repeat behaviour is handled by the per-day guard (below).
sse_support_email_should_send_to_user (filter) — per owner
Runs once per owner, after the per-day guard, the suppression gate and the admin’s recency rules. Return false to skip this individual. Default true. $context->subscriber, ->matching_product and ->all_products are set.
add_filter( 'sse_support_email_should_send_to_user', function ( $send, $context ) {
// e.g. skip bundle-only owners:
if ( $context->matching_product && ! $context->matching_product->direct ) {
return false;
}
return $send;
}, 10, 2 );
People excluded here appear under Will NOT receive in the Preview. You don’t check unsubscribes/bounces here — the gate already removed them.
sse_support_email_sent (action)
Fires once per successfully-queued support email, on real sends only (never during Preview). The changelog companion uses it to advance its stored “last sent version” — after a successful send, never inside the decision filter, so a failure can’t skip a release.
add_action( 'sse_support_email_sent', function ( $context ) {
// $context->product_id, $context->subscriber, $context->name, ...
} );
Repeat behaviour (no reference in core)
There is no version/reference dedup in core. Repeats are governed by two things: the per-day guard (at most one email per support-email + product + customer per calendar day) and your sse_should_send_support_email filter (which decides when there’s news). “Send again tomorrow because the version changed” = your filter returns true again on a new day.
Changelog-reader hooks
These belong to the companion plugin (Super Speedy Plugins — Changelog Emails), the worked-example consumer of the support-email filters above. They are not part of the core plugin.
sse_changelog_product_map (filter)
Maps a WooCommerce product ID to a plugin slug, so the reader knows which readme.txt / metadata to read for that product. Ships pre-filled with the Super Speedy Plugins catalogue.
add_filter( 'sse_changelog_product_map', function ( $map ) {
$map[12345] = 'my-plugin-slug';
return $map;
} );
sse_support_assets_dir (filter)
Overrides the local directory the changelog reader looks in for each plugin’s readme.txt and metadata file. Useful in development, or if your assets live somewhere non-standard.
add_filter( 'sse_support_assets_dir', function ( $dir ) {
return '/path/to/your/plugin/assets';
} );
Template hooks
sse_templates_registry (filter)
Adds new editable email templates, or overrides the defaults of existing ones. The registry defines each template’s label, default subject/body, and the list of supported {{tokens}}. See Editing Email Templates.
add_filter( 'sse_templates_registry', function ( $registry ) {
$registry['my_template'] = array(
'label' => 'My custom email',
'has_subject' => true,
'subject' => 'Hello {{first_name}}',
'body' => "Hi {{first_name}},
...",
'placeholders' => array(
'{{first_name}}' => "Recipient's first name",
),
);
return $registry;
} );
Render a registered template in your own code with SSE_Templates::subject( $key, $vars ) and SSE_Templates::body( $key, $vars ) — only the tokens you pass are replaced, so unknown tokens are left intact for a later pass.
Other hooks
sse_confirmation_ttl_days (filter)
How long a double opt-in confirmation link stays valid, in days (default 7). See Double Opt-in.
add_filter( 'sse_confirmation_ttl_days', function ( $days ) {
return 14;
} );
sse_automation_triggers (filter)
Registers additional automation trigger types beyond the built-in ones, so your code can start an automation sequence from a custom event. See Automations & Drips.
add_filter( 'sse_automation_triggers', function ( $triggers ) {
$triggers['my_custom_event'] = array(
'label' => 'My custom event',
);
return $triggers;
} );
Where to put this code
Hook code belongs in a small plugin or mu-plugin (recommended, so it’s version-controlled and survives theme changes), or your theme’s functions.php. For the support-email filters specifically, a dedicated mu-plugin keeps your sending policy in one auditable place.
- Developer Reference — classes, schema, REST API, and the full
sse_send()argument list. - Automated Support & Changelog Emails — the feature these support-email hooks drive, with the decide-who / decide-what model explained in full.
- Editing Email Templates — the template system behind
sse_templates_registry.