How does the emailing system (drupal_mail) work in Drupal 6?

| | 2 min read

Drupal uses a reasonably powerful mechanism to create, prepare and send emails generated within the system. We maintain two modules related to emails in Drupal - Mail Merge and MailQ (Mail Queue) - and get the opportunity to work with the mail subsystem in Drupal. Here is a brief write-up on how the mail system works in Drupal.

The workflow when sending a mail with drupal_mail

1) Module calls drupal_mail

drupal_mail($module, $key, $to, $language, $params = array(), $from = NULL, $send = TRUE)

The params array should have all the necessary information related to the mail that is to be sent. Do note that the mail is yet to be prepared and that will happen only during hook_mail calls.

2) drupal_mail then calls

2.a) hook_mail of the module calling drupal_mail

hook_mail is to be used by the module to copy parameters to $message.

The following parameters are already mapped back into $message from drupal_mail

  $message = array(
    'id'       => $module .'_'. $key,
    'to'       => $to,
    'from'     => isset($from) ? $from : $default_from,
    'language' => $language,
    'params'   => $params,
    'subject'  => '',
    'body'     => array()
  );

Drupal mail also sets the following as default headers

  $headers = array(
    'MIME-Version'              => '1.0',
    'Content-Type'              => 'text/plain; charset=UTF-8; format=flowed; delsp=yes',
    'Content-Transfer-Encoding' => '8Bit',
    'X-Mailer'                  => 'Drupal'
  );

If default_from is present it is used to set the following headers as well. default_from is either the site_mail if set or from php.ini sendmail_from parameter

  $headers['From'] = $headers['Sender'] = $headers['Return-Path'] = $headers['Errors-To'] = $default_from;
  $message['headers'] = $headers;

2.b) hook_mail_alter across all modules

Other modules can then alter $message as required via the hook_mail_alter call.

3) If $send parameter of drupal_mail is not set to FALSE drupal_mail will call drupal_mail_send

3.a) drupal_mail_send calls drupal_mail_wrapper($message) if smtp_library is set and the module is present. This is how the different modules like mimemail or smtp mail hooks into the mailing system in Drupal.

drupal_mail_wrapper is expected to send out the mail and if smpt_library is not set then drupal_mail_send will try to send out the mail using the php mail function.

How MailQ works in Drupal by plugging into drupal_mail

MailQ is a module designed to allow drupal sites hosted on shared hosting servers distribute the email loads on the system across time to work around the hourly email limits typically set by the hosting providers.

MailQ is designed to catch all mails sent by drupal by setting up a drupal_mail_wrapper which will queue all mails during non-cron regular site operations and which will send them out during cron runs. MailQ sets the smtp_library to itself forcing drupal_mail_send to call the drupal_mail_wrapper from mailq during normal operations. Mailq drupal_mail_wrapper will then store all the messages into the database queue and then process these in batches during cron runs by calling drupal_mail_send