Drupal 7

Once you have created a message type for notification the message can be created (see Creating Message Instances) with the addition of a call to the message_notify_send_message function.

/*
 * Implements hook_node_insert().
 */
function foo_node_insert($node) {

  $message = message_create('foo_message_type', array('uid' => $node->uid));

  $wrapper = entity_metadata_wrapper('message', $message);
  $wrapper->field_node_ref->set($node);
  //$wrapper->save();  <-  don't need - message_notify_send_message does this

  message_notify_send_message($message);
}

And here is the resulting email:

The Message Notify module comes with an example module that provides a more elaborate version of the simplified example above. Note that you will need to disable the Locale module if you try out the Message Notify Example module because it doesn't come with message text definitions for specific languages.

In the Message Notify Example module, two additional fields are added to the message type included with the module. These two fields field_rendered_subject and field_rendered_body act as placeholders for the markup that is rendered by the Message Notify module before it is emailed to a recipient. If you look at the hook_comment_insert() used in the Message Notify Example module, you will see that an options array is passed to the message_notify_send_message function. This array tells the email notifier that the rendered markup from the message_notify_email_subject view mode should be saved in the field_rendered_subject and the rendered markup from the message_notify_email_body view mode should be saved in the field_rendered_body.

/*
 * Implements hook_node_insert().
 */
function foo_node_insert($node) {

  $message = message_create('foo_message_type', array('uid' => $node->uid));

  $wrapper = entity_metadata_wrapper('message', $message);
  $wrapper->field_node_ref->set($node);

  $options = array(
     'rendered fields' => array(
       'message_notify_email_subject' => 'field_rendered_subject',
       'message_notify_email_body' => 'field_rendered_body',
     ),
  );

  message_notify_send_message($message, $options);
}

An example view is included with the Message Notify Example module that illustrates how the rendered text can be presented for each message sent by the system.

Drupal 8

In D8, there is no longer a message_notify_send_message function, so the code to use a message notifier would look like this instead:

    $message = \Drupal::entityTypeManager()->getStorage('message')->create([
      'template' => 'my_message_template',
    ]);
    $message->setOwner($recipient);
    $notifier = \Drupal::service('message_notify.sender');
    $notifier->send($message);

The use of a rendered fields array is optional, but if you do use it then its keys should match the display modes, so for D8:

  $options = array(
     'rendered fields' => array(
       'mail_subject' => 'field_rendered_subject',
       'mail_body' => 'field_rendered_body',
     ),
  );

By default the notification will be sent to the message owner, but this can be overridden in the default Email notifier. For example if you have a list of email addresses to notify, it is not necessary to create an individual message for each recipient, but you can send notifications in a loop:

    $message = \Drupal::entityTypeManager()->getStorage('message')->create([
      'template' => 'my_message_template',
    ]);
    $notifier = \Drupal::service('message_notify.sender');
    foreach ($emails as $email) {
      $options = ['mail' => $email];
      $notifier->send($message, $options);
    }

Comments

DanielZ123’s picture

To render the content of 'field_rendered_subject' and 'field_rendered_body' with Views you have to apply this patch: Entity language info missing (if you use Version 7.x-1.9 or below of Message module)

Moreover you have to enable 'text filter' instead of plain text in both field settings.
Otherwise Views renders the content as plain text, what means that all < p >-, < a >-, < img >-tags and so on in your messages are visible or not working.

admirernepali’s picture

When I use this

$options = array(
     'rendered fields' => array(
       'mail_subject' => 'field_rendered_subject',
       'mail_body' => 'field_rendered_body',
     ),
  );

getting this error:

Drupal\Core\Entity\EntityStorageException: Field "field_rendered_subject"" does not exist. in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 777 of /home/nepaliex/public_html/complaincity.com/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

However, message do gets delivered (email) but token renderer is not working. Email is sent as is: [comment:author] added following comment. [comment:body].

Any suggestions? I am using Drupal 8.x

johnreytanquinco’s picture

With Drupal 8, in what file should I add the code so the notification will be sent?

    $notifier = \Drupal::service('message_notify.sender');
    $notifier->send($message, $options);

I noticed a Message Notify Test added in /modules/message_notify/tests/modules/message_notify_test but cannot be enable from the /admin/modules in the browser.

Is that the same module the documentation referring on Message Notify Example module?

Thanks!

tepelena’s picture

Can this documentation be improved, please? Personally, I am new to Drupal, and it seems that some of the steps are missing on how to set this up.

griz’s picture

Typically you would write an event subscriber in a custom module. In that event subscriber:

Generate a message

$message = Message::create(['template' => "$template_id", 'uid' => $user_id]);

save it

$message->save();

then send it.

$notifier->send($message, $options);

You can also set arguments that will be replaced in the message text, similarly to tokens. The difference is that arguments are replaced before the message is saved, so if the value changes later (a field value or URL for example) the message will contain the old value. Tokens are replaced when the message is displayed.

If you want the code you've written to be reused elsewhere, you might create a service instead.

eahonet’s picture

I'm still struggling to send emails to everyone that's subscribed, but using

$notifier = \Drupal::service('message_notify.sender');
  $notifier->send($message);

Does seem to send one message (to the owner). I don't use the $options var, though. Instead, I go to /admin/structure/message and create a message there. I use the machine name in (example below is for "custom_update_node" machine name)
$message = Message::create(['template' => 'custom_update_node', 'uid' => $node->get('uid')]);
Then in /admin/structure/message > Edit "custom_update_node", I can "add another item" below the text area. Those two areas create "partial 0" and "partial 1" that I use /admin/structure/message/manage/custom_update_node/display/mail_body and /mail_subject . I am using the Display Suite (ds). So I set partial 0 to be my subject and partial 1 to be my body and then use tokens in those to generate content.

Now if I can just get it to send to those that subscribed....