---
title: How To Send Transactional Emails from Rails With Mandrill
teaser: Remove the headache of styling and tweaking copy in system emails.
tags: web,rails
author: Jessie Young
published_on: 2015-05-28
---

There are many libraries and services out there that make sending and tracking
[transactional emails](http://blog.mailchimp.com/what-is-transactional-email/)
in your Rails app a breeze. I've used [Sendgrid](https://sendgrid.com) and
[Postmark](https://postmarkapp.com/); both make it possible to start sending
emails in a matter of minutes.

But the pain points of transactional emails have not been removed entirely.

## The pain points of transactional emails

The first pain point is styling. Tools like
[roadie](https://github.com/Mange/roadie) can automatically inline CSS in email
templates based on stylesheets and Rails 4.1 comes with the ability to [preview
emails in
development](http://api.rubyonrails.org/v4.1.8/classes/ActionMailer/Base.html#class-ActionMailer::Base-label-Previewing+emails)
out of the box, but determining whether those styles look right in different
email clients and devices is a lot of extra work. More than once, I've had
something look awesome in Gmail and then have a client show me the same email
looking completely broken in Outlook.

The second pain point is the need for regular copy changes. After setting up
an email template, the copy of an email template rarely stays the same for
long. Whether it's right away or a few days later, I almost always find myself
tweaking email copy on several occasions to meet client and other stakeholder
requests.

## Why use Mandrill?

A couple of years ago, my approach to the this problem was to set up an
`emails` table in my database with `name` and `content` fields. The `name`
would correspond with an email template name, and the `content` would be the
main chunk of copy for an email. I would set up [RailsAdmin](
https://github.com/sferik/rails_admin) as an interface for stakeholders to log
in and update individual `email` records, which would be used to populate the
copy for various transactional emails. While this system worked, it was very
brittle because it relied on certain records existing in the database in order
for the app to function and only allowed for email layouts with one big chunk
of copy. In addition, this did not address the issue of responsive email
styles.

So, I was very excited to discover [Mandrill](https://www.mandrill.com/),
Mailchimp's transactional email service. While Mandrill is about as easy to set
up as other services, it also addresses the two pain points that the others do
not. Because Mandrill is a Mailchimp product, you can easily import Mailchimp’s
[responsive
templates](http://templates.mailchimp.com/getting-started/using-mailchimp/)
into Mandrill to use in transactional emails. In addition, stakeholders can
edit email copy within Mailchimp's WYSIWYG and re-import to Mandrill with the
click of a button. This means that copy changes don't require developer time or
a new deploy. Awesome.

I've now implemented transactional emails with Mandrill for a handful of Rails
apps. It's pretty simple but much simpler once you've seen how it's done. Let's
go through how to send responsive emails with Mandrill and Rails, step-by-step.

## How to set up Mandrill in your Rails app

1. Sign up for Mailchimp / Mandrill

    You need both a Mandrill account and a Mailchimp account.

2. Connect your Mailchimp and Mandrill accounts

    Follow [these
    instructions](https://mandrill.zendesk.com/hc/en-us/articles/205583067-How-do-I-use-Mandrill-if-I-already-have-a-MailChimp-account-)
    for integrating your Mailchimp and Mandrill accounts

3. Set up a template in Mailchimp

    Create a basic template in Mailchimp. Don’t worry about nailing down the
    content, but make sure you give the template a good, clear name since you will
    be referencing that name in your code. I am creating a welcome email so I am
    going to name mine `welcome`.

    Also, if you already know which portions of your email are going to be
    dynamic, include merge variables for those elements. A merge variable is an
    element of an email that is dynamic; therefore, it's values must be set each
    time an email is sent out. A commonly used merge variable is `first_name`, since
    the name in an email changes depending on who the email is being sent to.
    Mailchimp's format for merge variables looks like this: `*|FIRST_NAME|*`. You
    can also set dynamic links by setting the `href` value of an `a` tag to a merge
    variable, like this: `<p>Update your account details <a href=“*|USER_URL|*"
    target="_blank">here</a></p>`

    Here's what my template looks like with basic merge variables:

    ![Preview of Mailchimp email template!](https://images.thoughtbot.com/mandrill-for-rails-transactional-emails/mailchimp_template_preview.png)

4.  Send the Mailchimp template to Mandrill

    Once you save and exit the template editing view in Mailchimp, you will be
    on a list of all templates. Find the template you just created, and click the
    dropdown option next to the `edit` button. You should see the option to "Send
    to Mandrill". Click on that link. A few seconds later, you should see a flash
    message saying that your template was sent to Mandrill. Note: as of right now,
    this flash message takes several seconds to appear, which can be a bit confusing.

5. Log into Mandrill and visit your [templates](https://mandrillapp.com/templates)

    You should see the template you just created. Make sure your template is set
    to "published" within Mandrill.

    Once a template is in Mandrill, there is no need to edit it. Editing is best
    done in Mailchimp and then sent to Mandrill using the "Send to Mandrill" link,
    since Mailchimp's templates are optimized for multi-client and multi-device
    compatibility.

6. Set up your Rails app to send mail with Mandrill

    Add `mandrill-api` to your Gemfile and bundle

    Set the following `ENV` vars in your Rails app:

    ```
    SMTP_ADDRESS=smtp.mandrillapp.com
    SMTP_DOMAIN=localhost
    SMTP_PASSWORD=mandrill_api_key
    SMTP_USERNAME=mandrill_username
    ```

    You need set up your SMTP settings for environments where you'd like to
    actually send emails via Mandrill (for most, this will be production and
    staging):

    ```ruby
    # config/environments/production.rb

    Rails.application.configure do
      ...
      config.action_mailer.smtp_settings = {
        address: ENV.fetch("SMTP_ADDRESS"),
        authentication: :plain
        domain: ENV.fetch("SMTP_DOMAIN"),
        enable_starttls_auto: true,
        password: ENV.fetch("SMTP_PASSWORD"),
        port: "587",
        user_name: ENV.fetch("SMTP_USERNAME")
      }
      config.action_mailer.default_url_options = { host: ENV["SMTP_DOMAIN"] }
      ...
    end
    ```

7. Set up your Rails app to send Mandrill templates

    Now that you've got the basic setup for Mandrill done, it's time to set up
    your mailer to use the template you created in Mailchimp and sent to Mandrill.
    In my experience, it's best to encapsulate this logic in a mailer class that all
    other mailer classes inherit from. Existing system emails that use SMTP but do
    not need Mandrill templates will still send properly via Mandrill, so no need to
    update those until you want to.

    ```ruby
    # app/mailers/base_mandrill_mailer.rb

    require "mandrill"

    class BaseMandrillMailer < ActionMailer::Base
      default(
        from: "hello@example.com",
        reply_to: "hello@example.com"
      )

      private

      def send_mail(email, subject, body)
        mail(to: email, subject: subject, body: body, content_type: "text/html")
      end

      def mandrill_template(template_name, attributes)
        mandrill = Mandrill::API.new(ENV["SMTP_PASSWORD"])

        merge_vars = attributes.map do |key, value|
          { name: key, content: value }
        end

        mandrill.templates.render(template_name, [], merge_vars)["html"]
      end
    end
    ```

    I set up my `UserMailer` to inherit from this class and use the private
    methods to simplify my `welcome` email logic. This is where it is important to
    make sure you are referencing the same template name and merge variables as you
    used when you set up your template in Mailchimp.

    ```ruby
    # app/mailers/user_mailer.rb

    class UserMailer < BaseMandrillMailer
      def welcome(user_id)
        user = User.find(user_id)
        subject = "Welcome to our awesome app!"
        merge_vars = {
          "FIRST_NAME" => user.first_name,
          "USER_URL" => user_url(user),
        }
        body = mandrill_template("welcome", merge_vars)

        send_mail(user.email, subject, body)
      end
    end
    ```

8. Iterate on email styles and copy to your heart's content

    You're done! Time to celebrate.

    From now on, anyone can go into Mailchimp to edit the template's style and
    content. All someone needs to do to update system emails for your Rails app is
    make updates in Mailchimp and click the "Send to Mandrill" link. Just make sure
    the template name and merge variables stay the same or you'll need to make
    changes on the Rails side, too.

    It's also easy to send test emails from within Mailchimp, which is great for
    sharing email content and iterations with stakeholders.

    Make sure your environment variables are set on staging and production and then
    get going. Mandrill lets you send up to 12k emails per month for free, so if you
    think you will go over that, make sure you add some payment information to your
    Mandrill account, too.
