Plugins You can find out about all the publicly available Grails plugins.

Provides Mail support to a running Grails application Plugin Collection

66 votes

44% of Grails users

Dependency:
compile ":mail:1.0.7"

 Documentation  Source  Issues

Summary

This plug-in provides a MailService class as well as configuring the necessary beans withinthe Spring ApplicationContext.It also adds a "sendMail" method to all controller classes. A typical example usage is:sendMail { to "[email protected]","[email protected]" from "[email protected]" cc "[email protected]", "[email protected]" bcc "[email protected]" subject "Hello John" text "this is some text"}

Installation

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

grails install-plugin mail

Description

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.

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

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 "[email protected]"     
  subject "Hello Fred"     
  body 'How are you?' 
}

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

mailService.sendMail {
   to "[email protected]","[email protected]"
   from "[email protected]"
   cc "[email protected]", "[email protected]"
   bcc "[email protected]"
   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 "[email protected]"
  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 "[email protected]"
  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 "[email protected]"
  subject "Hello John"
  body( view:"/emailconfirmation/mail/confirmationRequest", 
      plugin:"email-confirmation", 
      model:[fromAddress:'[email protected]'])
}

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/plain so you must include this at the top of the GSP for a HTML email:

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

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.

This plugin also accepts emails in the form "Bill Gates<[email protected]>". This allows you to specify the sender display name in mail clients.

Multiple recipients

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

sendMail {
    to "[email protected]","[email protected]"
    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 .

Attachments

Since version 0.9 attachment support has been improved. It is possible to have both, email body and multiple attachments. In order to activate multipart support, the 'multipart true' must be the first element in the closure passed to the sendMail method, e.g.:

sendMail {
    multipart true
    to issue.watchers.email.toArray()
    subject "The issue you watch has been updated"
    body "Hello Watcher!"
    attachBytes "Some-File-Name.xml", "text/xml", contentOrder.getBytes("UTF-8")
    //To get started quickly, try the following
    //attachBytes './web-app/images/grails_logo.jpg','image/jpg', new File('./web-app/images/grails_logo.jpg').readBytes()
}

See also GRAILSPLUGINS-1175.

Asynchronous

The plugin can send mail asynchronously (the mail is sent on a different thread, and the sendMail message returns instantly, not waiting for the mail to be actually sent). In order to send asynchronously, 'async true' must be in the closure passed to the sendMail method, e.g.:

sendMail {
  async true
  to "[email protected]"
  subject "Hello John"
  html g.render(template:"myMailTemplate")
}

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 = "[email protected]"
     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"]

} }

And the configuration for sending via a Hotmail/Live account:

grails {
   mail {
     host = "smtp.live.com"
     port = 587
     username = "[email protected]"
     password = "yourpassword"
     props = ["mail.smtp.starttls.enable":"true", 
                  "mail.smtp.port":"587"]

} }

And the configuration for sending via a Yahoo account:

grails {
   mail {
      host = "smtp.correo.yahoo.es"
      port = 465
      username = "myuser"
      password = "mypassword"
      props = [ "mail.smtp.auth":"true",
                       "mail.smtp.socketFactory.port":"465",
                       "mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
                       "mail.smtp.socketFactory.fallback":"false"  ]
   }
}

If your mail session is provided via JNDI you can use the jndiName setting:

grails.mail.jndiName = "myMailSession"

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="[email protected]"

This will be used if no "from" is supplied in a mail. You can also disable mail delivery completely in certain environments by [email protected]@:

grails.mail.disabled=true

This is useful for certain environments where you don't want mails to be delivered such as during testing. Another useful setting often set per-enviroment is @grails.mail.overrideAddress@which lets you override the email address mails are sent to and from:

grails.mail.overrideAddress="[email protected]"

You can also adjust the size of the asynchronous mail sending thread pool. This size is the maximum number of threads that can send mail concurently. By default the value is 5 - so there could be 5 emails being sent asynchronously at the same time (if any more are sent, they will be queued). Note that is only used when sending mail asynchronously.

grails.mail.poolSize=5

CloudFoundry configuration using Sendgrid

You must bind the sendgrid service to the application and run the Sendgrid initial configuration wizard by going to the Sendgrid Dashboard via CloudFoundry.

Add these dependencies to BuildConfig.groovy

compile "org.springframework.cloud:spring-cloud-cloudfoundry-connector:1.1.1.RELEASE"
        compile "org.springframework.cloud:spring-cloud-spring-service-connector:1.1.1.RELEASE"

Configuration to Config.groovy

def cloud
try {
  cloud = Class.forName("org.springframework.cloud.CloudFactory").newInstance().cloud
} catch(e) {
}
if(cloud) {
  // configure sendgrid SMTP sender
  grails {
     mail {
  	   def smtpServiceInfo = cloud.getServiceInfos().find { it.class.name == "org.springframework.cloud.service.common.SmtpServiceInfo" }
       host = "smtp.sendgrid.net"
       port = 587
       username = smtpServiceInfo.userName
       password = smtpServiceInfo.password
       props = ["mail.smtp.starttls.enable":"true",
                "mail.smtp.port":"587]
     }
  }
}

TODO

  • Attachment support
  • Support for multiple parts
  • Support for MailSender artefact and sendMail(with: 'defaultSMTP') {..} for multiple smtp servers
  • Inline images
  • etc.

Troubleshooting

  • If an installation failed because of unresolved dependencies ...
    (like "javax.activation#activation;1.1: not found"
    … check if mavenCentral() is uncommented in your BuildConfig.groovy
  • 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