benecaster_email_queue_before_send
Fires immediately before a queued email is handed to wp_mail(), carrying the message exactly as wp_mail() will receive it plus the row’s email type, show and recipient.
This is the only Benecaster hook that fires inside the request that actually sends an email, and that is what it is for. Benecaster emails are enqueued in one PHP request and sent later by WP-Cron in a different one. benecaster_email_headers fires at enqueue time, so anything it stashes in a static property, a global or any other request-scoped variable is gone by the time wp_mail() runs. If your code needs to act in the same request as the send — most commonly to bridge Benecaster’s per-email context into a mail plugin’s own outgoing-payload filter — this action is the seam to use.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
$message |
array |
— | The message as `wp_mail()` will receive it: `to`, `subject`, `body_html`, `headers`. |
$email_type |
string |
— | Email type slug for the queued row (e.g. 'welcome', 'broadcast'). |
$show_id |
int |
— | ID of the show the email belongs to. |
$recipient_user_id |
int |
— | WordPress user ID of the recipient, or `0` when the address belongs to no account (an email-change verification, a donor's confirmation). Read the address from `$message['to']`, never by looking this ID up. |
Examples
Log every outgoing queued email
add_action(
'benecaster_email_queue_before_send',
function ( array $message, string $email_type, int $show_id, int $recipient_user_id ): void {
error_log( sprintf(
'[my-addon] sending %s to user %d for show %d: %s',
$email_type,
$recipient_user_id,
$show_id,
$message['subject']
) );
},
10,
4
);
Add a header to one email type at send time
// The action cannot change the message. Register a wp_mail filter from
// inside it, and unhook it again so it applies to this email only.
add_action(
'benecaster_email_queue_before_send',
function ( array $message, string $email_type ): void {
if ( 'broadcast' !== $email_type ) {
return;
}
$add_header = static function ( array $args ) use ( &$add_header ): array {
$args['headers'] = (array) ( $args['headers'] ?? [] );
$args['headers'][] = 'X-My-Addon-Broadcast: 1';
remove_filter( 'wp_mail', $add_header );
return $args;
};
add_filter( 'wp_mail', $add_header );
},
10,
2
);
Notes
It fires once per row, and one cron tick sends many rows. Context captured here is per-email, not request-global — each send re-populates it immediately before its own wp_mail() call. Anything you stash must be consumed and cleared within that one send, or row N's data will leak onto row N+1.
It is an action, not a filter. Returning a modified $message does nothing. To change the outgoing mail, register a wp_mail filter from inside the action, as in the second example above.
It is queue-only. benecaster_mail() is a direct send that never touches the queue and does not fire this action. Mail you want covered by a listener here has to go through benecaster_send_email().
The worked example embedded above carries an email's type, show and recipient into WP Mail SMTP's SendGrid API body filter — something benecaster_email_headers cannot do, because it runs in the wrong request.
Need this built rather than just documented? See our services →