Grails - Mail Plugin

Mail Plug-in

The mail plug-in provides e-mail sending capabilities to a Grails application by configuring a Spring MailSender based on sensible defaults.

Also see http://grails.org/plugin/mail

There is a screencast showing how to use the basic features of the plugin (v0.4)

Installation

To install the mail plug-in just run the following command

grails install-plugin mail

Usage

The mail plug-in provides a MailService that can be used anywhere in your Grails application. The MailService provides a single method called sendMail that takes a closure. In addition the sendMail method is injected into all controllers to simplify access.

An example of the sendMail method can be seen below:

sendMail {     
  to "fred@g2one.com"     
  subject "Hello Fred"     
  body 'How are you?' 
}

Or if you're using the service directly you can use:

mailService.sendMail {
   to "fred@g2one.com","ginger@g2one.com"
   from "john@g2one.com"
   cc "marge@g2one.com", "ed@g2one.com"
   bcc "joe@g2one.com"
   subject "Hello John"
   body 'this is some text'
}

To send HTML mail you can use the html method instead of the body method:

sendMail {
  to "fred@g2one.com"
  subject "Hello John"
  html '<b>Hello</b> World'
}

If your HTML is contained within a GSP template you can use the render tag called as a method (available in controllers and tag libraries):

sendMail {
  to "john@g2one.com"
  subject "Hello John"
  html g.render(template:"myMailTemplate")
}

If you wish to render a mail body from a GSP view from anywhere in your application, including from services or jobs where there may or may not be a current request, you can use the new body method variant (v0.4):

sendMail {
  to "john@g2one.com"
  subject "Hello John"
  body( view:"/emailconfirmation/mail/confirmationRequest", 
      plugin:"email-confirmation", 
      model:[fromAddress:'bill@microsoft.com'])
}

The view is the absolute path (or relative if you have a current controller) to the GSP. The plugin parameter is optional - if you need to render a template that may exist in a plugin installed in your application, you must include the name here. The model parameter is a map representing the model the GSP will see for rendering data.

In this case the content type will be auto-sensed - use the GSP page contentType directive to set the content-type to use in the e-mail. The default is text/html so you must include this at the top of the GSP for a plain text email:

<%@ page contentType="text/plain"%>

Note however that due to a limitation of the underlying Spring APIs used, XHTML content type text/xhtml will not result in a correct XHTML email.

Multiple recipients

You can send mail to multiple recipients (in either of 'to', 'cc' or 'bcc') at once.

sendMail {
    to "fred@g2one.com","ginger@g2one.com"
    subject "Hello to mutliple recipients"
    body "Hello Fred! Hello Ginger!"
}

There is a pitfall when using a List for storing the recipients. You'll have to invoke toArray when providing it to the builder, like this:

sendMail {
    to issue.watchers.email.toArray()
    subject "The issue you watch has been updated"
    body "Hello Watcher!"
}

If you forget the call to toArray , Groovy will convert the list (even a list with a single entry) to a String (the same way it does on the interactive console). The result will be something that is not a valid email address and you'll face javax.mail.internet.AddressException .

Configuration

By default the plugin assumes an unsecured mail server configured at localhost on port 25. However you can change this via the grails-app/Config.groovy file. For example here is how you would configure the default sender to send with a Gmail account:

grails {
   mail {
     host = "smtp.gmail.com"
     port = 465
     username = "youracount@gmail.com"
     password = "yourpassword"
     props = ["mail.smtp.auth":"true", 					   
              "mail.smtp.socketFactory.port":"465",
              "mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
              "mail.smtp.socketFactory.fallback":"false"]

} }

You can also set the default "from" address to use for messages in Config using:

// Since 0.2-SNAPSHOT in SVN
grails.mail.default.from="server@yourhost.com"

This will be used if no "from" is supplied in a mail.

TODO

  • Attachment support
  • Support for multiple parts
  • Support for MailSender artefact and sendMail(with: 'defaultSMTP') {..} for multiple smtp servers
  • Inline images
  • Issue with content types if the charset is defined
  • etc.

Troubleshooting

  • If you face javax.mail.internet.AddressException errors referring to "Illegal address in string" or "Missing ']' in string", it could be that you try to send to a List of recipients, which is not supported by the plugin. See 'Multiple recipients' above for information how to deal with that.
  • If you call sendMail in a service class rendering a gsp template, you may realize that the plugin is rendering the template as text/plain instead of html. To solve this issue you have to put in your gsp <%@ page contentType="text/html" %> or <%@ page contentType="text/xhtml" %> without setting the encoding