Receiving Emails with Ruby and Mailgun

Example App Repo: https://github.com/feinbergscott/example_mailgun_ruby_app

Background:

While building an application that required receiving and parsing emails, I first had to figure out how to get the emails into my application to start with. Luckily most developer friendly email services provide some sort of incoming email parsing utility, so I didn’t have to look far.

My Requirements:

  1. Posts emails to an endpoint on my application
  2. Allows me to setup an email to route emails to
  3. Ideally, has a free tier for my modest usage

I first started using CloudMailin which provides an email address and posts it to an endpoint of your choosing. It is built very specifically for receiving emails, exactly the bare minimum of what I wanted. This worked, but it didn’t provide much more than a post to an endpoint, you have to do all the parsing of the message yourself. It was also limited to 200 messages/month which seemed on the edge of what I’d need, I used over 50 emails just doing tests! I switched to using Mailgun which has a 10K/mo free tier, and it worked like a charm. Not only does it post to the endpoint fully parsed, but it provides you with regular expression filters, multiple actions, header parsing, and email forwarding all through an easy to use interface. Mailgun took longer to setup, but in exchange I got to use my own domain and do a lot more with the actions.

Enough talk, let’s build something

First you need to setup an endpoint to receive the requests. I chose to build a simple Sinatra app that takes the email and sends us a text message with the subject of the email if the subject includes [IMPORTANT].

The pertinent Sinatra code is very simple, all we need to do is take in the request and name our route.

post '/new_email' do
  mail = params
  if mail['subject'].include? "[IMPORTANT]"
    notify("IMPORTANT EMAIL RECEIVED #{mail['subject']}")
  end
end

Six lines of code and our endpoint is built.  I did a quick Twilio Integration which I’ll be expanding on in later posts, which is what the notify method is doing. In order to test it out with Mailgun, you’ll have to put it on a public facing URL, so I’d recommend just pushing it up to Heroku. You will need a config.ru and a Procfile, both of which are included in the example repo.

Want to see all the parts of the email params? Use the sample webhook feature under Test your Routes with the following Sinatra route:


post '/show_parts' do
  mail = params
  puts mail.inspect
end

In your Heroku logs, you’ll see the fully parsed hash.

Mailgun

Head over to mailgun.com and signup for a free account.

Mailgun Homepage

You will want to have a domain available to test with, just add two MX records and once DNS has propagated, your emails will start going through Mailgun.  If you have a domain but just want to test things out, use a subdomain. For this example, I setup mailgun.sefindustries.com. If you don’t have a domain, Mailgun will provide one for you, just click “” and you’ll be able to send emails to <anything>@yourdomain.mailgun.org.

Set Domain Name

 

Once you’ve selected your domain, just create your account and you’ll be set to start using Mailgun. On your My Account page, you should see a list of Email Domains on the right hand side. This is probably going to be in red. Until you add the MX Records for sending emails, this will remain red signifying an issue with the DNS. We actually just have to add the MX Records for receiving emails, so this will always be red unless you decide to send emails too.

Click on the domain you’ll be using to receive emails and you should see an Email domain: <your domain> page.  Scroll down to DNS Records (receiving) and you should see something like this:

DNS Records

Head over to your DNS Service and add these records. If you’re using a subdomain, make sure you’re applying them to the subdomain and not to the root domain.

Mailgun should now be receiving all emails sent to the domain you’ve setup, so the next step is telling Mailgun what to do with the mail it receives. Click on the Routes Tab at the top. Here you’ll be able to create your routes, set their priority, test your regex, and even send a sample webhook to your application to see if it works instead of having to send an email each time to test.

Click on Create Route to setup our first route.

Create New Route

The route creation screen is pretty self-explanatory, all the fields autofill for you.

The following is the chart that Mailgun provides for understanding what’s possible for new routes.  The first section applies to the actual filtering of the incoming email, the second what to do when that filter matches the incoming email. For more information, check out their ample documentation.

Screen Shot 2013-09-08 at 9.58.25 AM

All the emails that I’m parsing are sent to a single email address, so I want to only forward the email if it matches that address.

match_recipient("email_parsing@&lt;yourdomain.com&gt;")

For the action, we’ll forward to the endpoint we setup previously.

forward("http://something.herokuapp.com/new_email")

And that’s all there is to it! Emails will come in and if they match that recipient, it’ll post the entirely parsed email to your endpoint, simple as that.

For a fully working version of the endpoint, check out the example repo and add the required ENV variables.

Questions? Comments? Feedback? Comment here or tweet me at @scottefein

One thought on “Receiving Emails with Ruby and Mailgun

Leave a Reply

Your email address will not be published. Required fields are marked *