2

The wp_mail() function is not running when scheduled in a cron function. I have added the following function:

add_filter( 'cron_schedules', 'isa_add_every_one_minutes' );
function isa_add_every_one_minutes( $schedules ) {
    $schedules['every_sixty_seconds'] = array(
            'interval'  => 60,
            'display'   => __( 'Every 1 Minutes', 'textdomain' )
    );
    return $schedules;
}

// Schedule an action if it's not already scheduled
if ( ! wp_next_scheduled( 'isa_add_every_one_minutes' ) ) {
    wp_schedule_event( time(), 'every_sixty_seconds', 'isa_add_every_one_minutes' );
}

// Hook into that action that'll fire every three minutes
add_action( 'isa_add_every_one_minutes', 'only_debug_admin' );


function only_debug_admin(){
    $message = "Test message";

wp_mail( 'email@example.com', $message, $message );

update_option('default_role','customer');   
    }

When I run the cron manually via wp-control plugin, I receive a mail and wp-mail works fine. However, when the cron job is run. To debug, I add this line below the mail function:

update_option('default_role','customer'); 

I set the default role to subscriber in WordPress settings. On cron run, the setting gets updated to 'customer' but the mail is not received. On manually running the function, the mail is received. Any idea why this is happening?

2 Answers 2

1

This one is a bit of a puzzler. I was originally going to say you need to determine if there's something wrong after the mail is sent since you're getting the hit in the next operation. But then I re-read it and caught the part about the email being received when it's run manually.

What you need to do is find out if there's an error occurring. Since it's not a manual process, that's not quite straight forward; but there are ways to do it. This answer won't specifically solve the problem you're having, but it should give you way to determine what that issue actually is.

I would set up to catch any errors and then log them. You can do that by making sure WP is set up for debugging and to log any errors. Make sure the following is in your wp-config.php:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );

Now you can use WP's error_log() function to write any errors to the log file.

wp_mail() returns a true|false boolean when run. If there are any errors, it will return false. So we can write to the log depending on the result.

So in your function, write the to the error log based on the returned result.

function only_debug_admin(){
    $message = "Test message";

    $wp_mail_result = wp_mail( 'email@example.com', $message, $message );

    if ( true === $wp_mail_result ) {
        error_log( 'wp_mail returned true!' );
    } else {
        error_log( 'wp_mail had an error!' );
    }
}

If wp_mail() errors (returns false), then you want to be able to capture any errors in phpMailer to see if that gives you any insight as to why.

add_action( 'phpmailer_init', 'my_log_phpmailer_init' );
function my_log_phpmailer_init( $phpmailer ) {
    error_log( print_r( $phpmailer, true ) );
}

Now when the cron runs, you can check the error log (/wp-content/debug.log) for what happened. If wp_mail() returned true, the issue is an email issue with either the sending host or the receiver (outside of WP). If it was false, review the errors from phpMailer (which should also be in the log).

This doesn't solve your problem, but it gets you on track to figure out what it actually is.

1
  • This helped me. I got this error SERVER_NAME in /var/www/.../wp-includes/pluggable.php on line 330. I realized that as I ran my cron using crontab (and turned of the 'page visit cron' of wordpress) that the crontab uses the CLI php, which might be different. When I changed that to calling the wp-cron.php with wget, the problem was solved. Feb 20, 2020 at 3:13
0

This is really common when using CLI to run cron jobs (preferred). Wordpress uses PHPMailer and it tries to get SERVER_NAME from $_SERVER variable which is not defined and then it tries few callbacks, resulting in not valid email address. Easiest hacky fix I can think of, define it for example in your wp-config.php

if(empty($_SERVER['SERVER_NAME'])) $_SERVER['SERVER_NAME']='www.yourdomain.tld';
1
  • That feels like it's something your CLI cron job runner should fix then. What are you using, wp-cli?
    – Rup
    Jan 12 at 22:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.