Drupal 5.x to 6.x Mail changes
Here is a typical code snippet of mail sending before the changes:
<?php
system_send_email_action($object, $context) {
$variables['%site_name'] = variable_get('site_name', 'Drupal');
$variables = array_merge($variables, array(
'%term_name' => $object->name,
'%term_description' => $object->description,
'%term_id' => $object->tid,
'%vocabulary_name' => $vocabulary->name,
'%vocabulary_description' => $vocabulary->description,
'%vocabulary_id' => $vocabulary->vid,
)
);
$from = variable_get('site_mail', ini_get('sendmail_from'));
$recipient = $context['recipient'];
$variables['%username'] = $account->name;
$subject = strtr($context['subject'], $variables);
$subject = str_replace(array("\r", "\n"), '', $subject);
$message = strtr($context['message'], $variables);
$body = drupal_html_to_text($message);
drupal_mail('action_send_email', $recipient, $subject, $body, $from );
}
?>As you can see, some variables are set up and then we use strtr to replace these variables in the templates for their values. The new system moves this process into a separate hook (this is a vastly simplified version of system_mail):
<?php
function system_mail($key, &$message, $params) {
$variables = array(
'%site_name' => variable_get('site_name', 'Drupal'),
'%username' => $account->name,
);
$variables += array(
'%term_name' => $object->name,
'%term_description' => $object->description,
'%term_id' => $object->tid,
'%vocabulary_name' => $vocabulary->name,
'%vocabulary_description' => $vocabulary->description,
'%vocabulary_id' => $vocabulary->vid,
);
$subject = strtr($context['subject'], $variables);
$body = strtr($context['message'], $variables);
$message['subject'] .= str_replace(array("\r", "\n"), '', $subject);
$message['body'][] = drupal_html_to_text($body);
}
?>and then the mail sending is:
<?php
function system_send_email_action($object, $context) {
$language = user_preferred_language($account);
$params = array('account' => $account, 'object' => $object, 'context' => $context);
drupal_mail('system', 'action_send_email', $recipient, $language, $params);
}
?>So all you need to do is to move the variables setup and string replace commands into the hook_mail implementation and then call drupal_mail with the name of the module which contains this implementation, the mailkey, the recipient, the language of the user the mail goes to and some arbitrary parameters.

Just to clarify something
If, like me, you had a module that bunched up a load of stuff and then submitted it to drupal_mail, you're probably wondering how on earth to get it to work in Drupal 6.
Well a solution (which may not be the most elegant) is the following:
<?php
{
function mymodule_send_mail($edit)
globals $language;
...
$headers['Message-Id'] = $msgid;
// Ensure emails are treated as mailing list posts, not junk
$headers['Precedence'] = "list";
...
// send email
$params = array(
'body' => $body,
'subject' => $subject,
'headers' => $headers
);
$ok = drupal_mail('mymodule', 'mail', $to, $language, $params, $from);
...
}
/**
* Implements hook_mail
*/
function mymodule_mail($key, &$message, $params) {
$message['subject'] = $params['subject'];
$message['body'][] = $params['body'];
$message['headers'] = array_merge($message['headers'], $params['headers']);
}
?>
You 'simply' put the body, subject and headers (if needed) into the $params array and the put them into the email using mymodule_mail.
Don't forget to set $to and $from (!).