Question

I am trying to send an email with HTML content. But Drupal is always scrapping my HTML tags.

I see drupal formatting the message in this function:

//Class: \Drupal\Core\Mail\MailManager

// Format the message body.
//$message = $system->format($message);
public function doMail($module, $key, $to, $langcode, $params = [], $reply = NULL, $send = TRUE) {
    $site_config = $this->configFactory->get('system.site');
    $site_mail = $site_config->get('mail');
    if (empty($site_mail)) {
      $site_mail = ini_get('sendmail_from');
    }

    // Bundle up the variables into a structured array for altering.
    $message = [
      'id' => $module . '_' . $key,
      'module' => $module,
      'key' => $key,
      'to' => $to,
      'from' => $site_mail,
      'reply-to' => $reply,
      'langcode' => $langcode,
      'params' => $params,
      'send' => TRUE,
      'subject' => '',
      'body' => [],
    ];

    // Build the default headers.
    $headers = [
      'MIME-Version' => '1.0',
      'Content-Type' => 'text/plain; charset=UTF-8; format=flowed; delsp=yes',
      'Content-Transfer-Encoding' => '8Bit',
      'X-Mailer' => 'Drupal',
    ];
    // To prevent email from looking like spam, the addresses in the Sender and
    // Return-Path headers should have a domain authorized to use the
    // originating SMTP server.
    $headers['Sender'] = $headers['Return-Path'] = $site_mail;
    // Make sure the site-name is a RFC-2822 compliant 'display-name'.
    $headers['From'] = MailHelper::formatDisplayName($site_config->get('name')) . ' <' . $site_mail . '>';
    if ($reply) {
      $headers['Reply-to'] = $reply;
    }
    $message['headers'] = $headers;

    // Build the email (get subject and body, allow additional headers) by
    // invoking hook_mail() on this module. We cannot use
    // moduleHandler()->invoke() as we need to have $message by reference in
    // hook_mail().
    if (function_exists($function = $module . '_mail')) {
      $function($key, $message, $params);
    }

    // Invoke hook_mail_alter() to allow all modules to alter the resulting
    // email.
    $this->moduleHandler->alter('mail', $message);

    // Retrieve the responsible implementation for this message.
    $system = $this->getInstance(['module' => $module, 'key' => $key]);

    // Attempt to convert relative URLs to absolute.
    foreach ($message['body'] as &$body_part) {
      if ($body_part instanceof MarkupInterface) {
        $body_part = Markup::create(Html::transformRootRelativeUrlsToAbsolute((string) $body_part, \Drupal::request()->getSchemeAndHttpHost()));
      }
    }

    // Format the message body.
    $message = $system->format($message);

    // Optionally send email.
    if ($send) {
      // The original caller requested sending. Sending was canceled by one or
      // more hook_mail_alter() implementations. We set 'result' to NULL,
      // because FALSE indicates an error in sending.
      if (empty($message['send'])) {
        $message['result'] = NULL;
      }
      // Sending was originally requested and was not canceled.
      else {
        // Ensure that subject is plain text. By default translated and
        // formatted strings are prepared for the HTML context and email
        // subjects are plain strings.
        if ($message['subject']) {
          $message['subject'] = PlainTextOutput::renderFromHtml($message['subject']);
        }
        $message['result'] = $system->mail($message);
        // Log errors.
        if (!$message['result']) {
          $this->loggerFactory->get('mail')
            ->error('Error sending email (from %from to %to with reply-to %reply).', [
            '%from' => $message['from'],
            '%to' => $message['to'],
            '%reply' => $message['reply-to'] ? $message['reply-to'] : $this->t('not set'),
          ]);
          $error_message = $params['_error_message'] ?? $this->t('Unable to send email. Contact the site administrator if the problem persists.');
          if ($error_message) {
            $this->messenger()->addError($error_message);
          }
        }
      }
    }

    return $message;
  }

How do I avoid this? I do not want Drupal formatting the content.

My headers:

$headers = [
    'MIME-Version' => '1.0',
    'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
    'Content-Transfer-Encoding' => '8Bit',
    'X-Mailer' => 'Drupal',
];
Was it helpful?

Solution

Use the Mime Mail module

The Mime Mail module gives Drupal core and other Drupal modules the ability to send HTML email messages. This is an all-Drupal solution that does not require external third-party libraries.

Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange
scroll top