Glu Blog

Migrating from Mandrill to SendGrid

This morning I got an email from Heroku telling me the Mandrill add-on is shutting down 😭.

I've got a bunch of apps affected! But most pressing is updating ContentFocus which I'm in the midsts of trying to launch.

So here's the missing guide on how to update your ruby apps to use SendGrid.

Install the add-on

Do it, now! You'll want it on your apps before you deploy the code changes.

1
$ heroku addons:create sendgrid

Configure SendGrid

You'll need to setup a bunch of things to verify your new account and maximise your email deliverability. And you don't want any of these things impacting your app after you've switched over.

1
$ heroku addons:open sendgrid

Confirm your email address. And then move straight on to "Whitelabels" in the menu on the left. Add a new domain, and set it up to be a new subdomain on whatever your domain is (i.e., for me it's em+contentfocus.io). I set it to be the "default whitelabel" and turned on "automated security" so that SendGrid can manage my SPF & DKIM settings for me.

Update DNS

You'll need to setup 3 CNAME records in your DNS. The confirmation page from the whitelabel settings will give you the aliases and values you need to use. Once they're setup click the "Validate Record" button to make sure it's all worked. It took less than 10 seconds for mine to come live. DNS being what it is it could take a few hours though. Your mileage may vary.

Update your app

I've accumulated these apps over a number of years. It's unlikely they're all configured the same way, and there's no way I can remember all the different approaches. Actually I can't even remember the last approach!

1
2
3
4
$ ack MANDRILL_APP
models/email.rb
186:        user_name: ENV['MANDRILL_USERNAME'],
187:        password: ENV['MANDRILL_APIKEY'],

Oh thank you naming conventions on add-on environment variables! And for me nicely encapsulating things within a single class 😄. I'll just rinse-and-repeat that search across all my apps to find out what else needs to change and where.

Looking at the larger snippet of code involved I'd moved all of the options into a method on the Email class with I pass into Pony:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  def self.default_smtp_options
    {
      from: "Glenn @ ContentFocus <team@contentfocus.io>",
      via: :smtp,
      via_options: {
        address: 'smtp.mandrillapp.com',
        port: '587',
        enable_starttls_auto: true,
        user_name: ENV['MANDRILL_USERNAME'],
        password: ENV['MANDRILL_APIKEY'],
        domain: 'contentfocus.io',
        authentication: 'login'
      }
    }

So MANDRILL_USERNAME needs to become SENDGRID_USERNAME, MANDRILL_APIKEY becomes SENDGRID_PASSWORD, and I'll need to change the address to point to 'smtp.sendgrid.net'.

And after a quick check of the SendGrid documentation I realised that authentication had to change to :plain too. So the updated values look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  def self.default_smtp_options
    {
      from: "Glenn @ ContentFocus <team@contentfocus.io>",
      via: :smtp,
      via_options: {
        address: 'smtp.sendgrid.net',
        port: '587',
        enable_starttls_auto: true,
        user_name: ENV['SENDGRID_USERNAME'],
        password: ENV['SENDGRID_PASSWORD'],
        domain: 'contentfocus.io',
        authentication: :plain
      }
    }

Ship it!

We're done. Run the tests, commit the changes, git push heroku master. Tail the logs and watch your exception tracker just to make sure it's all working fine.

And once you're happy you can say goodbye to Mandrill 👋

1
$ heroku addons:destroy mandrill

Glenn Gillen

I'm the founder of Glu. I'm also an investor and advisor to early-stage tech startups. Previously worked at Heroku on the Add-ons Marketplace.

We're currently accepting a limited number of new users for our first product, ContentFocus.