For developers
How the module works
Section titled “How the module works”The module redirects WooCommerce emails to the Action Scheduler queue using the woocommerce_mail_callback filter:
add_filter( 'woocommerce_mail_callback', function() { return [ $this, 'add_job_to_queue' ];} );Sending process
Section titled “Sending process”- Email capture - The module captures the
wp_mail()call - Save to queue - Parameters are saved to
wp_options - Schedule action - Action Scheduler schedules immediate sending
- Asynchronous sending - Cron triggers the sending
Action Scheduler
Section titled “Action Scheduler”Action for sending
Section titled “Action for sending”// Action triggered when sending emaildo_action( 'wpify_send_email', $hash );Monitoring the queue
Section titled “Monitoring the queue”You can monitor the email queue in Tools → Scheduled Actions:
- Action:
wpify_send_email - Status: Pending / Complete / Failed
Data structure
Section titled “Data structure”Saving email parameters
Section titled “Saving email parameters”// Parameters are saved as an option with a hash key$args = [ $to, $subject, $message, $headers, $attachments ];$hash = md5( json_encode( $args ) );update_option( $hash, $args );Loading and deletion
Section titled “Loading and deletion”// When sending$args = get_option( $hash );delete_option( $hash ); // After successful loadingExample: Tracking sent emails
Section titled “Example: Tracking sent emails”add_action( 'wpify_send_email', function( $hash ) { $args = get_option( $hash );
if ( $args ) { error_log( sprintf( 'Sending email to: %s, Subject: %s', $args[0], // to $args[1] // subject ) ); }}, 5 ); // Priority before moduleExample: Custom processing
Section titled “Example: Custom processing”add_action( 'wpify_send_email', function( $hash ) { $args = get_option( $hash );
if ( ! $args ) { return; }
// Custom logic before sending list( $to, $subject, $message, $headers, $attachments ) = $args;
// For example, logging to a custom table global $wpdb; $wpdb->insert( $wpdb->prefix . 'email_log', [ 'to_email' => $to, 'subject' => $subject, 'sent_at' => current_time( 'mysql' ), ] );}, 5 );External cron
Section titled “External cron”If you use DISABLE_WP_CRON, set up an external cron:
# Every minute* * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1Or using WP-CLI:
* * * * * cd /path/to/wordpress && wp cron event run --due-now > /dev/null 2>&1Action Scheduler vs WP Cron
Section titled “Action Scheduler vs WP Cron”The module uses Action Scheduler (part of WooCommerce), which is more reliable than standard WP Cron:
| Feature | WP Cron | Action Scheduler |
|---|---|---|
| Triggering | On page visit | On visit + CLI |
| Logging | No | Yes |
| Management | Limited | Full |
| Scalability | Low | High |