uspw_email_sent_result
Description
Fires after an email send attempt (success or failure), allowing developers to log results, implement retry logic, or trigger fallback notifications.
Hook Type: Action
Since: 1.0.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$email_sent | bool | Whether the email was sent successfully |
$data | array | Entry data |
$campaign_id | int | The ID of the spin wheel campaign |
Usage
add_action( 'uspw_email_sent_result', 'my_email_result_handler', 10, 3 );
function my_email_result_handler( $email_sent, $data, $campaign_id ) {
// Your custom logic here
}
Real-World Examples
Example 1: Log Email Delivery Status
Track email delivery success/failure rates for monitoring and debugging.
add_action( 'uspw_email_sent_result', 'log_email_delivery', 10, 3 );
function log_email_delivery( $email_sent, $data, $campaign_id ) {
global $wpdb;
$table_name = $wpdb->prefix . 'spin_email_log';
// Log the email attempt
$wpdb->insert( $table_name, [
'campaign_id' => $campaign_id,
'recipient_email' => $data['email'] ?? '',
'recipient_name' => $data['name'] ?? '',
'coupon_code' => $data['coupon_code'] ?? '',
'status' => $email_sent ? 'sent' : 'failed',
'sent_at' => current_time( 'mysql' ),
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '',
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? ''
] );
// Track failure rate
if ( ! $email_sent ) {
$failure_count = get_transient( 'spin_email_failures_' . $campaign_id ) ?: 0;
$failure_count++;
set_transient( 'spin_email_failures_' . $campaign_id, $failure_count, HOUR_IN_SECONDS );
// Alert admin if failure rate is high
if ( $failure_count >= 5 ) {
wp_mail(
get_option( 'admin_email' ),
'High Email Failure Rate Alert',
sprintf(
'Campaign %d has experienced %d email failures in the last hour. Please investigate.',
$campaign_id,
$failure_count
)
);
}
}
}
Example 2: Implement Retry Logic for Failed Emails
Automatically retry failed email sends with exponential backoff.
add_action( 'uspw_email_sent_result', 'retry_failed_emails', 10, 3 );
function retry_failed_emails( $email_sent, $data, $campaign_id ) {
if ( $email_sent ) {
return; // Email sent successfully, no retry needed
}
// Get retry count
$retry_key = 'spin_email_retry_' . md5( $data['email'] . $campaign_id );
$retry_count = get_transient( $retry_key ) ?: 0;
// Maximum 3 retries
if ( $retry_count < 3 ) {
$retry_count++;
set_transient( $retry_key, $retry_count, DAY_IN_SECONDS );
// Calculate delay with exponential backoff (5 min, 15 min, 45 min)
$delay = 300 * pow( 3, $retry_count - 1 ); // 5 * 3^(n-1) minutes
// Schedule retry
wp_schedule_single_event( time() + $delay, 'spin_wheel_retry_email', [
'data' => $data,
'campaign_id' => $campaign_id,
'retry_attempt' => $retry_count
] );
// Log retry attempt
error_log( sprintf(
'Spin Wheel: Scheduled email retry #%d for %s in %d seconds',
$retry_count,
$data['email'] ?? 'unknown',
$delay
) );
} else {
// Max retries reached, send admin notification
wp_mail(
get_option( 'admin_email' ),
'Email Delivery Failed After 3 Retries',
sprintf(
"Failed to send winner email after 3 attempts.\n\nRecipient: %s\nCampaign: %d\nCoupon: %s\n\nPlease contact the winner manually.",
$data['email'] ?? 'Unknown',
$campaign_id,
$data['coupon_code'] ?? 'N/A'
)
);
}
}
// Handler for retry attempts
add_action( 'spin_wheel_retry_email', 'handle_email_retry', 10, 1 );
function handle_email_retry( $args ) {
// Resend the email
$subject = sprintf( 'You Won %s!', $args['data']['coupon_title'] ?? 'a Prize' );
$message = sprintf(
'Congratulations! Your coupon code is: %s',
$args['data']['coupon_code'] ?? ''
);
$sent = wp_mail( $args['data']['email'], $subject, $message );
// Trigger the result hook again
do_action( 'uspw_email_sent_result', $sent, $args['data'], $args['campaign_id'] );
}
Example 3: Send SMS Fallback for Failed Emails
If email delivery fails, send the coupon code via SMS as a backup.
add_action( 'uspw_email_sent_result', 'sms_fallback_on_failure', 10, 3 );
function sms_fallback_on_failure( $email_sent, $data, $campaign_id ) {
// Only send SMS if email failed and phone number is available
if ( $email_sent || empty( $data['phone'] ) ) {
return;
}
$twilio_sid = get_option( 'twilio_account_sid' );
$twilio_token = get_option( 'twilio_auth_token' );
$twilio_from = get_option( 'twilio_phone_number' );
if ( ! $twilio_sid || ! $twilio_token || ! $twilio_from ) {
return;
}
// Prepare SMS message
$sms_message = sprintf(
"Congrats %s! You won %s. Your code: %s. Use it at %s",
$data['name'] ?? 'there',
$data['coupon_title'] ?? 'a prize',
$data['coupon_code'] ?? '',
home_url()
);
// Send via Twilio
$response = wp_remote_post( "https://api.twilio.com/2010-04-01/Accounts/{$twilio_sid}/Messages.json", [
'headers' => [
'Authorization' => 'Basic ' . base64_encode( "{$twilio_sid}:{$twilio_token}" )
],
'body' => [
'From' => $twilio_from,
'To' => $data['phone'],
'Body' => $sms_message
]
] );
if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) === 201 ) {
// Log successful SMS fallback
global $wpdb;
$table = $wpdb->prefix . 'spin_email_log';
$wpdb->insert( $table, [
'campaign_id' => $campaign_id,
'recipient_email' => $data['email'] ?? '',
'status' => 'sms_fallback_sent',
'sent_at' => current_time( 'mysql' ),
'notes' => 'Email failed, SMS sent successfully'
] );
}
}
Example 4: Track Email Performance Metrics
Monitor email open rates and click-through rates using tracking pixels and UTM parameters.
add_action( 'uspw_email_sent_result', 'track_email_metrics', 10, 3 );
function track_email_metrics( $email_sent, $data, $campaign_id ) {
if ( ! $email_sent ) {
return;
}
global $wpdb;
$table_name = $wpdb->prefix . 'spin_email_metrics';
// Generate unique tracking ID
$tracking_id = wp_generate_password( 32, false );
// Store tracking record
$wpdb->insert( $table_name, [
'tracking_id' => $tracking_id,
'campaign_id' => $campaign_id,
'recipient_email' => $data['email'] ?? '',
'coupon_code' => $data['coupon_code'] ?? '',
'sent_at' => current_time( 'mysql' ),
'opened' => 0,
'clicked' => 0,
'converted' => 0
] );
// Note: The tracking pixel and UTM links should be added in uspw_before_send_winner_email hook
// This hook just sets up the tracking infrastructure
// Schedule a check for opens/clicks after 24 hours
wp_schedule_single_event( time() + DAY_IN_SECONDS, 'spin_wheel_check_email_metrics', [
'tracking_id' => $tracking_id,
'campaign_id' => $campaign_id
] );
}
// Handler to check and report metrics
add_action( 'spin_wheel_check_email_metrics', 'check_email_performance', 10, 1 );
function check_email_performance( $args ) {
global $wpdb;
$table = $wpdb->prefix . 'spin_email_metrics';
$metrics = $wpdb->get_row( $wpdb->prepare(
"SELECT * FROM {$table} WHERE tracking_id = %s",
$args['tracking_id']
) );
if ( $metrics && ! $metrics->opened ) {
// Email not opened after 24 hours - potential deliverability issue
error_log( sprintf(
'Spin Wheel: Email not opened after 24h - Campaign %d, Email: %s',
$args['campaign_id'],
$metrics->recipient_email
) );
}
}
Example 5: Sync Email Status with CRM
Update CRM records with email delivery status for better lead tracking.
add_action( 'uspw_email_sent_result', 'sync_email_status_to_crm', 10, 3 );
function sync_email_status_to_crm( $email_sent, $data, $campaign_id ) {
$hubspot_api_key = get_option( 'hubspot_api_key' );
if ( ! $hubspot_api_key || empty( $data['email'] ) ) {
return;
}
// Prepare status update
$status = $email_sent ? 'Winner Email Sent' : 'Winner Email Failed';
$timestamp = current_time( 'timestamp' ) * 1000; // HubSpot uses milliseconds
$contact_data = [
'properties' => [
[
'property' => 'spin_wheel_email_status',
'value' => $status
],
[
'property' => 'spin_wheel_email_sent_date',
'value' => $timestamp
],
[
'property' => 'spin_wheel_coupon_delivered',
'value' => $email_sent ? 'Yes' : 'No'
]
]
];
// Add failure reason if email failed
if ( ! $email_sent ) {
$contact_data['properties'][] = [
'property' => 'spin_wheel_delivery_issue',
'value' => 'Email delivery failed - manual follow-up required'
];
// Create a task for sales team to follow up
$task_data = [
'engagement' => [
'type' => 'TASK',
'timestamp' => $timestamp
],
'associations' => [
'contactIds' => [] // Will be populated after finding contact
],
'metadata' => [
'subject' => 'Follow up on failed spin wheel email',
'body' => sprintf(
'Winner email failed to deliver for %s. Coupon code: %s. Please contact manually.',
$data['email'],
$data['coupon_code'] ?? 'N/A'
),
'status' => 'NOT_STARTED',
'priority' => 'HIGH'
]
];
// Send task creation request
wp_remote_post( 'https://api.hubapi.com/engagements/v1/engagements', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $hubspot_api_key
],
'body' => wp_json_encode( $task_data )
] );
}
// Update contact in HubSpot
$endpoint = 'https://api.hubapi.com/contacts/v1/contact/createOrUpdate/email/' . urlencode( $data['email'] );
wp_remote_post( $endpoint, [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $hubspot_api_key
],
'body' => wp_json_encode( $contact_data )
] );
}
Notes
- This hook fires immediately after
wp_mail()is called, with the boolean result. - The
$email_sentparameter indicates success/failure of thewp_mail()function, not actual delivery to inbox. - Perfect for logging, retry logic, fallback notifications, and CRM synchronization.
- For true delivery tracking, consider using transactional email services with webhooks (SendGrid, Mailgun, etc.).
- Failed emails don’t necessarily mean the email wasn’t delivered –
wp_mail()only confirms it was handed off to the mail server.