Wednesday 23 May 2012

Send email via SendGrid on Heroku using Play! 2.0 with Scala

If you have a Play! framework 2.0 application that you want to send email from, here are a few tips.

These tips assumes you deploy to Heroku, but other platforms should work similarly. The examples here are using Scala, but Java should work along similar lines. Finally the specifics are for the SendGrid add-on for Heroku, but other mail server providers should be fine.


First add the free option of the SendGrid add-on to your Heroku app by typing in:
heroku addons:add sendgrid:starter

Then configure your Play! app to use the mail plugin provided by Typesafe:

Add to your dependencies in the project/Build.scala file: (all on one line)
"com.typesafe" %% "play-plugins-mailer" % "2.0.2"
Then create and add these to a conf/play.plugins file: (all on one line)
1500:com.typesafe.plugin.CommonsMailerPlugin

Next configure the mail server settings. You can either add these directly to your conf/application.conf file, but I prefer to share my projects' source code, so my production settings are set via environment variables so that my username/password are not publicly available.

However for the plugin to run smpt.host  must be present. Open conf/application.conf and add:
smtp.host=mock

On Heroku I append the settings to the Heroku's propriatory Procfile file. I append these settings to the Procfile to use SendGrid's servers: (all on one line)
-Dsmtp.host=smtp.sendgrid.net -Dsmtp.port=587 -Dsmtp.ssl=yes -Dsmtp.user=$SENDGRID_USERNAME -Dsmtp.password=$SENDGRID_PASSWORD
You may already have other settings in the Procfile, e.g. database URL, so be aware of the 255 char limit, and use a custom properties file instead.
web: target/start -Dhttp.port=${PORT} 
-Dconfig.resource=heroku-prod.conf

The SendGrid add-on should create the environment SENDGRID_USERNAME and SENDGRID_PASSWORD variables for you.
You can verify this with:
heroku config

Finally we then create our actual application code to send email:
package notifiers
import com.typesafe.plugin._
import play.api.Play.current
import play.api.Play
import play.Logger
object EmailNotifier {
  def sendMail {
    val mail = use[MailerPlugin].email
    mail.setSubject("Mail test")
    mail.addRecipient("Joe Smith  <joe@example.com>","sue@example.com")
    mail.addFrom("Jon Doe <joe@example.com>")
    mail.send( "Test email" )
  }
  def sendTestMail {
    if(Play.current.mode == Mode.Prod){
      Play.current.configuration.getString("smtp.host") match {
        case None => Logger.debug("Email mock")
        case Some("mock") => 
Logger.debug("Email mock")   
        case _ => sendMail(participant)

    }
  } else {
    Logger.debug("Email mock")}
  }
}
(In case of this posts cant parse tags replace &lt;  and &gt; with less than and greater than tags;)




This should be all that is needed.


Play! 1.x did have a handy mock email interface for development and testing. I will try and find a suitable replacement for 2.0 and update this post when I do.




For more information