Spin Wheel

⌘K
  1. Home
  2. Spin Wheel
  3. Hooks & Filters (Deve...
  4. After email send attempt (uspw_email_sent_result)

After email send attempt (uspw_email_sent_result)

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

ParameterTypeDescription
$email_sentboolWhether the email was sent successfully
$dataarrayEntry data
$campaign_idintThe 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_sent parameter indicates success/failure of the wp_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.

How can we help?