Secondary Hooks

These hooks cover failure alerts, email controls, and log queries. They are lower-traffic extension points compared to mailers, tools, and dashboard widgets, but are high-value for Pro features such as per-recipient alert routing, WooCommerce-specific email toggles, and custom log queries.

Failure Alert Hooks

NimblyMail sends an email notification when mail delivery fails. Four hooks let a Pro add-on control who receives the alert, what it says, and react after it is sent.

nimbly_mail_alert_recipients

Filters the recipient list before the failure alert is sent.

Signature: apply_filters( 'nimbly_mail_alert_recipients', array $recipients, array $log )

  • $recipients — array with keys to, cc, bcc. Each is a string email address or empty string.
  • $log — the log row array for the failed email (same shape as a row from the email logs table).

Returns: array

@since 1.0.0

add_filter(
    'nimbly_mail_alert_recipients',
    function ( array $recipients, array $log ): array {
        // Route alerts for orders to the store manager instead of the site admin.
        if ( isset( $log['subject'] ) && str_contains( $log['subject'], 'New order' ) ) {
            $recipients['to'] = '[email protected]';
            $recipients['cc'] = '';
        }
        return $recipients;
    },
    10,
    2
);

nimbly_mail_alert_subject

Filters the failure alert subject line.

Signature: apply_filters( 'nimbly_mail_alert_subject', string $subject, array $log )

  • $subject — the default subject string.
  • $log — the log row array for the failed email.

Returns: string

@since 1.0.0

add_filter(
    'nimbly_mail_alert_subject',
    function ( string $subject, array $log ): string {
        $site = get_bloginfo( 'name' );
        return "[{$site}] Mail Failure — {$subject}";
    },
    10,
    2
);

nimbly_mail_alert_body

Filters the failure alert message body. Useful for appending diagnostic information or reformatting the alert for a ticketing system.

Signature: apply_filters( 'nimbly_mail_alert_body', string $body, array $log )

  • $body — the default HTML body string.
  • $log — the log row array for the failed email.

Returns: string

@since 1.0.0

add_filter(
    'nimbly_mail_alert_body',
    function ( string $body, array $log ): string {
        $ticket_link = sprintf(
            '<p><a href="https://support.example.com/new?subject=%s">Open support ticket</a></p>',
            rawurlencode( 'Mail failure on ' . get_bloginfo( 'name' ) )
        );
        return $body . $ticket_link;
    },
    10,
    2
);

nimbly_mail_alert_sent

Fires after the failure alert email has been sent. Use this for secondary logging, analytics, or triggering a webhook.

Signature: do_action( 'nimbly_mail_alert_sent', array $recipients, string $subject, array $log )

  • $recipients — the final recipients array (after nimbly_mail_alert_recipients was applied).
  • $subject — the final subject string.
  • $log — the log row array for the failed email.

@since 1.0.0

add_action(
    'nimbly_mail_alert_sent',
    function ( array $recipients, string $subject, array $log ): void {
        // Post to a Slack webhook.
        wp_remote_post(
            'https://hooks.slack.com/services/YOUR/WEBHOOK/URL',
            array(
                'body'        => wp_json_encode(
                    array( 'text' => "Mail failure alert sent: {$subject}" )
                ),
                'headers'     => array( 'Content-Type' => 'application/json' ),
                'timeout'     => 5,
                'blocking'    => false,
            )
        );
    },
    10,
    3
);

Email Controls

nimbly_mail_email_controls

Filters the map of WordPress notification toggles shown in Settings > Email Controls. Use this to add WooCommerce, Easy Digital Downloads, or other plugin-specific email toggles so site admins can suppress them from a single screen.

Signature: apply_filters( 'nimbly_mail_email_controls', array $controls )

  • $controls — nested associative array. Top-level keys are group labels; values are arrays of [ id, label, description ] control descriptors.

Returns: array

@since 1.0.0

add_filter(
    'nimbly_mail_email_controls',
    function ( array $controls ): array {
        $controls['WooCommerce'] = array(
            array(
                'id'          => 'woocommerce_new_order',
                'label'       => __( 'New Order', 'nimbly-mail-pro' ),
                'description' => __( 'Sent to the store admin when a new order is placed.', 'nimbly-mail-pro' ),
            ),
            array(
                'id'          => 'woocommerce_customer_processing_order',
                'label'       => __( 'Processing Order', 'nimbly-mail-pro' ),
                'description' => __( 'Sent to the customer when their order status changes to processing.', 'nimbly-mail-pro' ),
            ),
        );
        return $controls;
    }
);

Log Query Hooks

nimbly_mail_log_query_args

Filters the query arguments array before the log query is built. Use this to add custom WHERE clauses, change sort order, or inject additional filters from a Pro feature.

Signature: apply_filters( 'nimbly_mail_log_query_args', array $args )

  • $args — associative array of query arguments (e.g., status, search, date_from, date_to, per_page, page).

Returns: array

@since 1.0.0

add_filter(
    'nimbly_mail_log_query_args',
    function ( array $args ): array {
        // Limit log queries to the last 90 days when no date filter is set.
        if ( empty( $args['date_from'] ) ) {
            $args['date_from'] = gmdate( 'Y-m-d', strtotime( '-90 days' ) );
        }
        return $args;
    }
);

nimbly_mail_log_items

Filters the log rows array after the query executes. Use this to append, remove, or reformat rows — for example, to merge bounce data from an external source.

Signature: apply_filters( 'nimbly_mail_log_items', array $rows, array $args )

  • $rows — the raw rows returned from the database query.
  • $args — the final query arguments (after nimbly_mail_log_query_args was applied).

Returns: array

@since 1.0.0

add_filter(
    'nimbly_mail_log_items',
    function ( array $rows, array $args ): array {
        foreach ( $rows as &$row ) {
            // Annotate each row with bounce data from an external source.
            $row['bounce_info'] = nimbly_mail_pro_get_bounce_info( $row['recipient'] );
        }
        unset( $row );
        return $rows;
    },
    10,
    2
);

nimbly_mail_log_row

Filters a single log row just before it is included in the REST response. Use this to add computed fields, mask sensitive recipient data, or inject Pro-specific metadata per row.

Signature: apply_filters( 'nimbly_mail_log_row', array $row )

  • $row — the formatted row array as it will appear in the REST response.

Returns: array

@since 1.0.0

add_filter(
    'nimbly_mail_log_row',
    function ( array $row ): array {
        // Add a direct link to the Postmark message activity page.
        if ( ! empty( $row['message_id'] ) ) {
            $row['provider_url'] = 'https://account.postmarkapp.com/servers/activity?messageId=' . rawurlencode( $row['message_id'] );
        }
        return $row;
    }
);

Setup Wizard Steps

nimbly_mail_setup_wizard_steps

Not yet available — tracked as open question in spec 020.

The wizard’s step list currently lives in the Vue application. Surfacing it to PHP requires localizing the step array into window.nimblyMailApp first, which is a non-trivial restructuring of the wizard component. This filter was listed in the Phase 6 spec but was deferred because it is purely client-side. It will be added in a follow-up once the wizard architecture supports PHP-driven step injection.