Wordpress - How to add headers to outgoing email?

Thanks to the above, I've realized my central mistake -- I didn't quite realize that the arguments being passed in were a multi-dimensional array.

For now, I've re-implemented the function thus:

function ws_add_site_header($email) {
    $email['headers'][] = 'X-WU-Site: ' . parse_url(get_site_url(), PHP_URL_HOST) ;
    return $email;               
}

My reading of the wp_mail() source (see: https://core.trac.wordpress.org/browser/tags/4.4.2/src/wp-includes/pluggable.php#L235) leads me to believe that the headers component can be an array, or a big string, or possibly some horrific mish-mash of the two, but that using an array is probably the safer/more correct option.

I do like the various phpmailer answers, but it just seems a bit cleaner to try to do things using WordPress' built-ins.


Here's an alternative using directly the AddCustomHeader method of the PHPMailer instance:

/**
 * Add a custom header.
 * $name value can be overloaded to contain
 * both header name and value (name:value)
 * @access public
 * @param string $name Custom header name
 * @param string $value Header value
 * @return void
 */
public function addCustomHeader($name, $value = null)
{
    if ($value === null) {
        // Value passed in as name:value
        $this->CustomHeader[] = explode(':', $name, 2);
    } else {
        $this->CustomHeader[] = array($name, $value);
    }
}

Here we can see that there are two ways to use it:

Example #1:

Here we only pass the header information in the $name input string, that's seperated with :

add_action( 'phpmailer_init', function( $phpmailer )
{   
    $phpmailer->AddCustomHeader( 
       'X-WU-Site: ' . parse_url( get_site_url(), PHP_URL_HOST ) 
    );  
} );

Example #2:

Here are both $name and $value non-empty:

add_action( 'phpmailer_init', function( $phpmailer )
{   
    $phpmailer->AddCustomHeader( 
       'X-WU-Site', parse_url( get_site_url(), PHP_URL_HOST ) 
    );  
} );

PHP headers are strings. You can not parse them as array. You need to add you additional header as string with \r\n to make sure it is added in next line.

Example:

add_filter('wp_mail', 'ws_add_site_header', 99);
function ws_add_site_header($args) {
    $args['headers'] .= !empty($args['headers']) ? "\r\n" : '';
    $args['headers'] .= 'X-WU-Site: ' . parse_url(get_site_url(), PHP_URL_HOST);
    return $args;
}

Also please note add you additional headers at last with priority 99 so no other plugin can replace it if it is not checking that headers already present. If needed make it 999.