Multipart HTML Emails With Drupal

Mail clients can receive both HTML and text-only emails. Emails formatted in HTML are much more attractive and generally sought after by most clients. However, many users do not accept HTML emails, believing these emails to be more vulnerable to attack.

The solution is to send a multi-part email, which includes both text and HTML versions of the message. In such case, people who do accept HTML e-mails will see a pretty version and the rest will see a text-based version.

Let's look at a quick example:

$subject = 'iPhone 3G is out!';
$destination = 'bill@gates.com, steve@apple.com';
$mailer_app = 'Drupal Mailer';
$boundary = '----=_NextPart_'.md5(uniqid());

$body_html = "
<style> 
label { font-weight: bold; margin: .5em;}
</style>

<H2>Check-out the new iPhone 3G!</H2>
<label>requires:</label> good taste
<label>evangelized by:</label> Steve Jobs
";

//make sure original HTML had nice line breaks 
$body_text = preg_replace('/<style>.+?<\/style>/ims', 
             '', $body_html); 
$body_text = strip_tags( $body_text ); 
$multi_body  = "

This is a multi-part message in MIME format.

--$boundary
Content-Type: text/plain; charset=UTF-8; format=flowed; 
Content-Transfer-Encoding: 8bit

$body_text

--$boundary
Content-Type: text/html; charset=UTF-8; format=flowed; 
Content-Transfer-Encoding: 8bit

$body_html

";

$from = null; // Will use Drupal's site-wide settings

//Make sure the Content-type parameter's value is all on one line!!!
$params = array(
 'MIME-Version' => '1.0',
 'Content-Type' => 'multipart/alternative; boundary="'.$boundary.'"',
 'Content-Transfer-Encoding' => '8Bit',
 'X-Mailer' => $mailer_app);

$mailsent = drupal_mail( 
           'example_module', //curr module's name
           $destination,
           $subject, $multi_body, $from, $params );

Disclaimer This code sample is for Drupal5. The "drupal_mail" function is different in Drupal6. Please, refer to Drupal documentation for the differences. But the main principle should still work.

Caution: In multi-part e-mail syntax every space and caret return counts. It's very fragile to anything extra or missing, so we highly recommend that you use $multi_body and $params variables EXACTLY the way it is in this sample. Do not indent text for "code formatting".

* * *
irakli

No bio, just a tagline: ‘Sure, you can get code written in exchange for a bottle of vodka in Russia, but then you get vodka code. And not even Stoli.’


Although this code si pretty straightforward, wasn’t this the very purpose of the MIME Mail module?

Correct, in more advanced cases Mime Mail is probably the way to go. For simpler cases, if you need it in Drupal 6 (no Mime Mail there, yet), for people who are concerned about installing 200+ modules in a Drupal site or simply for those who like to get their hands dirty, this would work, too, though.

cheers

Why md5(uniqid())? It seems a bit redundant. You could just use uniqid().

md5() converts the output of uniqid() into a 32 alpha-numeric identifier (a 128 bit hex number).

For instance, raw uniqid output could be: “487e131aaea70”, with md5() it becomes: “265ef71c4716b20c4e0b673edcb760c0”.

It’s not crucial, but makes code slightly more reliable and the e-mail’s source prettier. Code would work in most cases even if you inserted a constant there, but this is a little better.