Using the Mandrill API with Action Mailer in Rails
Mandrill is a popular transactional email service created by the folks over at Mailchimp. There are a number of Mandrill community gems for Rails, but several motivations exist for wrapping the Mandrill API with Action Mailer, primarily if you envision possibly swapping out email providers in the future (i.e. quota limits and costs, different template preferences, etc.), or you want more control customizing the actual content and design of your emails beyond the Mandrill templates and templating language.
We’ll walkthrough how to customize Action Mailer to use Mandrill, while attempting to keep our code modular and straightforward:
- Set up the Mandrill API and credentials
- Create our Mailer and actions to populate the Mail object and render our message views
- Create our Mandrill delivery model to send our object via the mandrill-api gem
- Configure Action Mailer to use our custom Mailer
The Mandrill API Gem And Credentials
Sign up for a Mandrill account to receive your API key. Mandrill has a test sandbox with a separate API key I recommended using in your development environment. I typically keep my keys in my .zshrc / .bashrc file, and access it as an environmental variable (ENV[‘MANDRILL_APIKEY’]) when using them in my application. Then stick “gem mandrill-api” in your Gemfile and “bundle install”.
Basic Mailer Overview
Action Mailer can be divided into two conceptual components:
Mailer [/mailers/NotificationMailer.rb]: analogous to a Rails Controller, the Mailer populates a Mail object that stores our e-mail data; content, addresses, etc. We setup the Mailer as e-mail “actions” that render the appropriate view. In this case, our Mailer is for generic “notifications”, so we’ll call it notification_mailer. We’ll set it to “respond” to sign-up and order notifications and render the appropriate message content.
Delivery method [/models/MandrillDelivery.rb]: contains calls to the Mandrill API and related sending operations. While this modular setup is more work than quickly using a community gem, we are separating the content and behavior of our emails from the service we use to send them. We can easily have multiple Mailers, rendering different e-mail content, while selectively switching among transactional e-mail providers; perhaps Mandrill for all, or only a select handful of our emails.
Creating The Mailer
We’ll create the Mailer, and the appropriate view. Note the subscriber parameter that we’ll pass in later.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
We have our notification mailer creating a Mail object given different scenarios / actions. These may be triggered by a background worker (or even in the controller itself, although less than ideal.) Now we create the appropriate views for each mail action.
Similar to a Controller, we access instance variables in the mailer’s associated views to provide the data we need when rendering. The examples are simplistic, but hopefully illustrative.
Creating our Delivery Method
We’ll create a mandrill_delivery model with our deliver! method. It’ll be in charge of a) setting up a Mandrill message hash with appropriate meta-data, and then b) sending the message via the API.
In this particular example we’re using a template already set up on Mandrill. It will take our rendered sign-up confirmation message and insert it in the appropriate section of the template before sending.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
Configure Your Custom Action Mailer
Lastly, a pretty straightforward configuration addition to link everything together. Create a mailer.rb file with the following in you Rails application directory config/initializers/.
We use our newly assigned delivery method “mandrill_delivery” in our environmental configuration, choosing our dev or production environments accordingly.
1 2 3 4 5 6 7 8
Likely the most confusing part about setting up a custom Mailer lies in the fact that the class never gets instantiated – we configure our application to use our new delivery method (mandrill_delivery) and, like controllers and views, Rails takes care of rendering the message appropriately. A background job or even a rake task calling NotificationMailer.sign_up_notification(subscriber).deliver will trigger the whole procedure.
While the examples are simple, hopefully this provides a clear picture of customize Action Mailer with Mandrill.