The uspw_before_send_winner_email Filter
The uspw_before_send_winner_email filter runs in Ultimate Spin Wheel just before a winner’s coupon email is handed to wp_mail(). It lets you rewrite the subject, replace the message body, add headers, reroute the message through an external service, or skip the default send entirely. Because it is a filter, your callback must return the (possibly modified) $email_args array.
Important: this hook is (Pro). In the free plugin the filter line is wrapped in apply_filters( 'ultimate_spin_wheel_pro_init', false ), so it only fires when the separate Ultimate Spin Wheel Pro plugin is active. On a free-only install the callback is never called.
- Hook type: Filter — return the array.
- Since: 1.0.0
- Availability: (Pro) — gated behind
ultimate_spin_wheel_pro_init.
When It Fires
The winner email is only assembled when all of these are true, so the filter fires under the same conditions:
- The spin result status is
won, and the entry has both an email address and a resolved coupon code. - Email delivery is enabled for the campaign — the Behavior tab’s prize-delivery “email the coupon” option (
emailDelivery) is set toyes. - Ultimate Spin Wheel Pro is active.
Parameters
$email_args(array) — the email payload with exactly four keys:to,subject,message, andheaders. This is the value you return.$data(array) — the entry data. Reliable keys arename,email,phone,campaign_id,campaign_title,campaign_type, anduser_data(a JSON string holdingip_address,device_id, anduser_agent).$campaign_id(int) — the ID of the spin wheel campaign.
Note on the coupon: the winning coupon title and code are not passed as separate keys in $data — they are already rendered into $email_args['message'] by the default email template. To change how the coupon appears, edit $email_args['message'] (or supply your own custom HTML email via the Pro uspw_custom_email_template filter). There is no country or prize_value field in $data.
Basic Usage
Register the filter with three accepted arguments and return the array:
add_filter( 'uspw_before_send_winner_email', 'my_email_customization', 10, 3 );function my_email_customization( $email_args, $data, $campaign_id ) { // Modify $email_args as needed. return $email_args;}
Example 1: Customize the Subject and Sender
Personalize the subject line with the winner’s name and add a custom From header:
add_filter( 'uspw_before_send_winner_email', 'uspw_custom_subject', 10, 3 );function uspw_custom_subject( $email_args, $data, $campaign_id ) { $name = $data['name'] ?? ''; $email_args['subject'] = trim( $name ) !== '' ? sprintf( 'Congratulations %s, your reward is inside!', $name ) : $email_args['subject']; $email_args['headers'][] = 'From: Rewards Team <[email protected]>'; return $email_args;}
Example 2: Append Content to the Message Body
Because the coupon is already inside $email_args['message'], add extra content (an expiry note, a call to action) by appending to that string:
add_filter( 'uspw_before_send_winner_email', 'uspw_add_expiry_note', 10, 3 );function uspw_add_expiry_note( $email_args, $data, $campaign_id ) { $expires = date_i18n( 'F j, Y', strtotime( '+7 days' ) ); $email_args['message'] .= sprintf( '<p style="text-align:center;color:#856404;">Redeem before <strong>%s</strong>.</p>', esc_html( $expires ) ); return $email_args;}
Example 3: Route Through an External Email Service
Send the message through a transactional provider, then return an empty to so the plugin skips its own wp_mail() call:
add_filter( 'uspw_before_send_winner_email', 'uspw_route_external', 10, 3 );function uspw_route_external( $email_args, $data, $campaign_id ) { $api_key = get_option( 'my_esp_api_key' ); if ( ! $api_key ) { return $email_args; // Fall back to wp_mail(). } $response = wp_remote_post( 'https://api.example.com/v3/send', [ 'headers' => [ 'Authorization' => 'Bearer ' . $api_key, 'Content-Type' => 'application/json' ], 'body' => wp_json_encode( [ 'to' => $email_args['to'], 'subject' => $email_args['subject'], 'html' => $email_args['message'], ] ), ] ); if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) < 300 ) { $email_args['to'] = ''; // Skip the built-in wp_mail() send. } return $email_args;}
Example 4: A/B Test the Subject Line
Split winners into two consistent variants based on their email and rewrite the subject for each:
add_filter( 'uspw_before_send_winner_email', 'uspw_ab_subject', 10, 3 );function uspw_ab_subject( $email_args, $data, $campaign_id ) { $variant = ( hexdec( substr( md5( $email_args['to'] ), 0, 1 ) ) % 2 === 0 ) ? 'A' : 'B'; $email_args['subject'] = ( $variant === 'A' ) ? 'Your reward is ready to claim' : 'You won! Grab your prize now'; return $email_args;}
Skipping the Default Send
To stop the plugin from sending its own email — for example when you have delivered it yourself — set $email_args['to'] to an empty string and return the array. The plugin checks for a non-empty to before calling wp_mail(), so an empty value cleanly skips the send.
Notes
- This is a filter — always
return $email_args. Do not rely on modifying it by reference. - The
headerskey is an array (it defaults toContent-Type: text/html; charset=UTF-8). Append to it rather than overwriting if you want to keep the HTML content type. - A companion (Pro) hook,
uspw_email_sent_result, fires right after the send attempt with the boolean result, the entry data, and the campaign ID — useful for logging or retries. - For a fully custom HTML email body, use the (Pro)
uspw_custom_email_templatefilter, which replaces the default template before this hook runs.
Related Documentation
- Hooks & Filters Reference: The full list of action and filter hooks available in Ultimate Spin Wheel.
- Win Probabilities: How the server picks the winning slice before the email is generated.
Conclusion
The uspw_before_send_winner_email filter is the (Pro) hook for shaping the winner’s coupon email — rewrite the subject, extend the body, add headers, or reroute through an external service, then return $email_args. Remember that it only runs when Pro is active and the campaign’s email delivery is enabled, and that the coupon itself lives inside the message body rather than as a separate $data field. If you need help, visit the wowDevs support center.