Blazzzing fast transactional emails using Play Framework 2.3, MandrillApp & ZURB in 1 day
MandrillApp has created a transactional email service and it is so amazing! Pair that with Play Framework and ZURB and you'll be unstoppable!
Last weekend I started using it for my side project Itemize to send notifications when shared items changed, were restored, were deleted, etc. Most ESPs I’ve worked with in the past have been very bulky so I was dreading working on this at all. BUT, Mandrill was quite a nice surprise. I layered it in using a Scala trait by providing my Play controller a sendMessage api. I created a trait called EmailService
Hold on hold on! Let’s take a step back and talk about Mandrill for a second… They offer a transactional email service free of charge for up to 12K emails/month with an hourly quota, which makes it ideal for small projects. Integrating them in a side project is super easy since their API is fully RESTful and the documentation is beautiful. Once you create an account you can setup a couple of API keys for different environments. I created one for prod and dev environments each. Emails sent from the dev environment are not actually sent out, though their sandbox tool allows you to view the content as it would be sent. As you can see in the snippet above, I just put this key in the Play config and imported it and the API url into my service layer. That’s it! Mandrill ready-to-use…
Creating Templates using Twirl
Originally, I wanted to have the sendMessage method accept a typed template instead of a String. Twirl templates are of type BaseScalaTemplate[...] with TemplateX[...]. The ‘X’ signifies the number of parameters the template accepts (and being a case class it maxes out at 22). The idea was to generic-ify the signature of sendMessage (a work-in-progress) to maintain type-safety yet keeping things flexible, but I wasn’t able to do that easily. In the mean time, it made sense to keep EmailService simple stupid and have it accept the rendered template as a String.
As with most software, the key to moving fast with email templates is to use a framework that provides well tested responsive templates. Thankfully this is where Zurb’s Email Templates came into the picture. Zurb offers 5 template types (I just picked the Basic template and customized it a little) along with tons of resources to make your templates work on different email clients. This saved me a whole lot of time and effort. Thanks Zurb team!!!!
Just to elaborate, since I’m using Play templates, I easily separated out the Zurb template markup and styling into different files (email_layout.scala.html & email_styling.scala.html), with the former importing the latter since email template styling has to be inline. In addition, creating different emails was super easy since I just pass in a HTML content variable into the layout @()(content: Html) ... for each email.
Play WS Client
After configuring Mandrill and setting up the EmailMessage api plus the template I leveraged Play’s WS API to make API calls.
The first step was to use the Play WS client to setup a method that would send json (note: the communication format was set to json using the .json at the end of the url and the Content-Type header) requests to Mandrill endpoints. Next, I hooked in my sendMessage method.
Notice that I use EmailPacket, EmailMessage, EmailRecipient and SendResponse case-classes to handle sending and receiving data from Mandrill. Along with the classes, I wrote Play’s Writes[T] to convert each of them to json using Play’s Json library. One thing to note here is that I didn’t account for failure responses from Mandrill, but those could be baked in a very similar fashion as above and I leave that up to you.
Parting Thoughts
It’s been such a pleasure to work on this using the tri-fecta of Mandrill, Play and ZURB. I was so excited because these tools make it so much easier to build features that were much more tedious to build even 5 years ago. In fact, I built all this in 1 day! I hope you are able to leverage some (if not all) of these tools to build your next email service quickly too!














