Score:0

hook_mail_alter() doesn't remove the Return-Path, Sender, and Reply-To headers

us flag

I want to remove the Return-Path, Sender, and Reply-To headers from the sent emails. I am trying to achieve this using the following code, but the headers aren't removed from the email.

function mymodule_mail_alter(&$message) {
  unset($message['headers']['Return-Path']);
  unset($message['headers']['Sender']);
  unset($message['headers']['Reply-To']);
}

What am I doing wrong?

fr flag
So much left unsaid ... such as what @Mail plugin(s) you're using.
us flag
We are using default PHP mailer of Drupal 8 and the SMTP module . We are trying to fire the Test Mail via the SMTP module after entering credentials. But it seems we are not able to modify the headers from hook_mail_alter
imclean avatar
my flag
Why was my edit rejected? @secretsayan's comment above adds essential information which should be in the question. It narrows it down to the SMTP module rather than just Drupal core.
Score:1
us flag

Removing the values from $message['headers'] isn't sufficient, as the plugin used to send emails could also use $message['Return-Path'], $message['Sender'], or $message['Reply-To'] value to build the email headers. The class that is used as default plugin to send emails, PhpMail uses the following code, but other plugins could use different code.

$site_mail = $this->configFactory->get('system.site')->get('mail');
$additional_headers = isset($message['Return-Path']) && ($site_mail === $message['Return-Path'] || static::_isShellSafe($message['Return-Path'])) ? '-f' . $message['Return-Path'] : '';
$mail_result = @mail($message['to'], $mail_subject, $mail_body, $mail_headers, $additional_headers);

Since the email plugin is used to send the email after the hook_mail_alter() implementations are invoked, and since the email plugin can add one of those headers to its discretion, there isn't any warranty the email is sent without those headers. Assuming the email plugin adds only those headers when $message or $message['headers'] contains a value for them, the following code should work.

function mymodule_mail_alter(&$message) {
  unset($message['Return-Path']);
  unset($message['Sender']);
  unset($message['Reply-To']);
  unset($message['headers']['Return-Path']);
  unset($message['headers']['Sender']);
  unset($message['headers']['Reply-To']);
}
fr flag
I'd like to add that the RFC says headers are case insensitive, so for example "unset($message['headers']['Return-Path']);" is insufficient - the header key could be "return-Path", so your unset wouldn't do anything. Likewise, the @Mail plugin could be assuming a certain casing, so even if the plugin tried to respect your choice the case you use could trip it up. Bottom line is what apademo said above: "Since the email plugin is used to send the email after the hook_mail_alter() implementations are invoked ... there isn't any warranty the email is sent without those headers."
Score:0
my flag

The SMTP module always sets certain headers which cannot be unset. See the following lines from Drupal\smtp\Plugin\Mail\SMTPMailSystem:

$headers['Sender'] = $from;
$headers['Return-Path'] = $from;
$headers['Reply-To'] = $from;

This is to make it compatible with Drupal core which does the same from what I can tell.

For more control, you can use the module PHPMailer SMTP instead which explicitly unsets the Return-Path header to comply with RFC 5321.

It also makes no assumptions about which extra headers should be present (beyond the required ones) and only sets them if they are added elsewhere.

The following would work if the case of the headers match:

function mymodule_mail_alter(&$message) {
  unset($message['headers']['Sender']);
  unset($message['headers']['Reply-To']);
}

Alternatively, the following would unset headers regardless of case:

function mymodule_mail_alter(&$message) {
  $message['headers'] = array_change_key_case($message['headers']);
  unset($message['headers']['sender']);
  unset($message['headers']['reply-to']);
}

PHPMailer SMTP is for sending email only and does not do any HTML formatting so you'd also need to use a module such as MIME Mail for that purpose.

Disclaimer: I am the author of PHPMailer SMTP.

Score:-1
jp flag

Use function hook_mail($key, &$message, $params) instead. Also, you would need additional $key I believe to distinguish for which functionality is the mail being sent.

Then this hook would be triggered when sending the mail manually:

$send = true;
$mailManager = \Drupal::service('plugin.manager.mail');
$result = $mailManager->mail($module, $key, $to, $langcode, $params, null, $send);

I would suggest using Swiftmailer, it omits all of the manual work.

apaderno avatar
us flag
I take the OP wants to remove those headers from every email. `hook_mail()` would not help with that.
apaderno avatar
us flag
Even if the OP wanted to remove the Return-Path, Sender, and Reply-To headers from the email sent by a module the OP wrote, or by a specific module, this answer doesn't say how to achieve that.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.