I am using the code below and the mail gets sent but without the body of the message, but the subject is correct am I sending the body in thee wrong parameter?

 function mailMessage($msg){
 $mailManager = \Drupal::service('plugin.manager.mail');
 $module = "mymodule";
 $key = 'uploaded files';
 //$to = \Drupal::currentUser()->getEmail();
 $to="[email protected]";
 $params['message'] = "THIS IS my body of the message";
 $params['node_title'] = "File Upload Report";
 $params['subject'] = "File Upload Report";
 $langcode ="en";
 $send = true;
 $result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send);
 if ($result['result'] !== true) {
   drupal_set_message(t('There was a problem sending your message and it was not sent.'), 'error');
 else {
   drupal_set_message(t('Your message has been sent.'));
  • Where is your hook_mail($key, &$message, $params) { code ?
    – No Sssweat
    Apr 28, 2017 at 23:30

2 Answers 2


The body of the message is set by the implementation of hook_mail() done from the module sending the message. The code invoking that hook is the following one. (See MailManager::doMail(), the method called from MailManager::mail().)

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

  // Build the 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',
  // 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;
  $headers['From'] = $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);

As you see, $message['body'] is set to an empty array before passing it to hook_mail(). If your module doesn't implement hook_mail(), $message['body'] will stay an empty array, if there aren't other module that implement hook_mail_alter().
The comment before the code invoking hook_mail() is also explicit about what expecting from that hook: get subject and body, allow additional headers.

As usual, that is the default implementation of the mail manager. It could be a different mail manager sets the message body to a more significant value, but a module should not depend on the mail manager doing it.

As side note, Drupal doesn't use $message['message'] as your code does.

  • do I still have to put this in somewhere ? $mailManager = \Drupal::service('plugin.manager.mail');
    – Diana
    Apr 29, 2017 at 21:31
  • 1
    To make it clearer: You need to use the service responsible of sending emails and implement hook_mail().
    – apaderno
    Apr 30, 2017 at 4:06

You need to add a hook_mail code

As this line $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send); behind the scenes will invoke this hook_mail function.

something like this:

* Implements hook_mail().
function <module_name>_mail($key, &$message, $params) {

 $options = array(
   'langcode' => $message['langcode'],

 switch ($key) {
   case 'uploaded files':
     $message['from'] = \Drupal::config('system.site')->get('mail');
     $message['subject'] = t('@title', array('@title' => $params['node_title']), $options);
     $message['body'][] = $params['message'];
  • why do i have to add that ? i mean my mail is going out with the code I have and the subject is correct, its just the body of the message that is not being populated correctly
    – Diana
    Apr 28, 2017 at 23:41
  • @Diana I am not sure why, but just know that this is the proper way to do it.
    – No Sssweat
    Apr 29, 2017 at 0:00
  • 1
    Because that's how system mail works in Drupal @Diana. Messages are keyed and structured in such a way that they can be targeted and altered by other modules like everything else. If you're not happy with it you can use the mail() function, phpmailer, whatever you like. Using the API is just recommended, it's not mandatory
    – Clive
    Apr 29, 2017 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.