Grow with us: Join Postmark's new referral partner program and start earning
x

Handling inbound emails in Rails using Postmark

It’s common to send emails from your Rails app, but what about receiving incoming emails? In this tutorial, you’ll learn how to receive emails in your Rails app using Postmark’s inbound email processing.

We’ll be creating a simple blog application that allows readers to post responses to articles using email.

Let’s get started.

Prerequisites #

You’ll need a Postmark account for this tutorial. If you don’t have one already, sign up for a free developer account now.

This tutorial assumes that you’re familiar with running a Rails app locally. The demo application we’ll be using is built to run on Rails 5 using Ruby 2.4.1.

If you don’t already have Ruby 2.4.1 installed, please install it using rvm before continuing.

rvm install 2.4.1

Setting up the demo application #

Start by downloading the demo application and unzipping the contents to your home folder.

Download demo application

Open up Terminal and cd into the inbound-demo-rails directory.

Install the project’s dependencies using Bundler.

gem install bundler
bundle install

Now you need to set up the database. We’ll be using an SQLite database in this demo for simplicity.

Start by creating the database:

bin/rails db:setup

This command will set up your database and populate it with some example articles you can use for testing.

Now your database is set up, and you’re ready to run the app. Head back to the terminal and start up the Rails server.

bin/rails s

Navigate to http://localhost:3000 in your web browser. You should see three test articles.

Test articles image example

Configuring Postmark’s inbound processing #

Now you’ve got the demo app up and running it’s time to configure Postmark to receive your emails.

Log in to your Postmark account and create a new server that will handle your app’s inbound emails.

Image of new server creation screen in Postmark

Head over to the Credentials tab and grab the inbound email address for this server. It should look something like huigh8923hg782ygh7348y734g8y@inbound.postmarkapp.com. This is the email address where readers will send their article responses.

If you want to use a custom email address for inbound emails, check out the inbound domain forwarding setup guide.

Open the config/initializers/postmark.rb file and input the hash from the start of your inbound email address. (Everything before the @ symbol.) Postmark uses this hash to determine which server inbound emails belong to.

Rails.application.config.postmark_inbound_email_hash = 'huigh8923hg782ygh7348y734g8y'

In order to test webhooks locally, you’re going to use a service called Ultrahook. Ultrahook will catch webhook payloads sent from Postmark and forward them to the Rails app running on your local machine.

If you haven’t used Ultrahook before, start by registering for an API key.

Once you’re done, add your Ultrahook API key to a .ultrahook file in your home folder.

echo "api_key: YOUR_ULTRAHOOK_API_KEY" > ~/.ultrahook

You’re now ready to start Ultrahook.

ultrahook inbound-demo 3000

Once Ultrahook starts running, you should see a URL output in the console.

Authenticated as YOUR_USER
Forwarding activated...
http://inbound-demo.YOUR_USER.ultrahook.com -> http://localhost:3000

Any requests sent to http://inbound-demo.YOUR_USER.ultrahook.com will now forward to http://localhost:3000 on your local machine.

Now that you have Ultrahook set up, the final step of this section is to tell Postmark about your Webhook URL.

Go to the inbound settings page for your server. (Settings → Inbound)

In the Webhook field, add your ultrahook URL followed by /responses. This path is for the endpoint that will process incoming inbound webhooks in your Rails app. (We’ll set that up shortly.)

http://inbound-demo.YOUR_USER.ultrahook.com/responses
Setting up Ultrahook as a Webhook in Postmark example

Make sure to come back and update the Webhook URL when you’re ready to launch your application into production.

Handling inbound webhooks from Postmark #

It’s time to create the endpoint in your Rails app that will handle inbound webhooks from Postmark.

Create the controller method #

Open the app/controllers/responses_controller.rb file in your favorite text editor.

Add a new create method. This will receive inbound webhook payloads from Postmark that contain the responses sent from readers.

def create
end

The first thing you need to do is parse the JSON payload sent by Postmark. Add the following to your new create method:

message = JSON.parse(request.body.read)

To identify which article a response should be associated with, we’re going to add the article’s ID to the inbound email address. We’ll do this using the + character. 

Anything after the + will be extracted by Postmark as the MailboxHash which is made available in the JSON request received by the Rails application.

huigh8923hg782ygh7348y734g8y+124@inbound.postmarkapp.com

In this example, Postmark would identify 124 as the MailboxHash.


Processing replies to your transactional emails #

A common use case for inbound email processing is to catch replies to transactional emails. For example, if a user replies to a comment notification email for a blog post they wrote, their reply should be added to the comments section of that blog post. To process replies to your transactional emails, add a Reply-To header on the emails your application sends out. This should be your inbound email address with a unique hash or ID which can be used to identify a database record that replies should be associated with.

Reply-To: Postmark<qwerty12345+myrandomhash@inbound.postmarkapp.com>


Back in the create method, retrieve the article ID from the webhook JSON.

article_id = message['MailboxHash']

Next, use this article_id variable to find the Article that the new response should be associated with.

You can now create the new response using the data from the reader’s email.

article.responses.create(
  name: message['FromName'],
  email: message['From'],
  body: message['TextBody']
)

Here we’re extracting the user’s name and email address as well as the body of the email and using it to create a new Response record.

Check out the Postmark documentation for a full list of properties available in the inbound webhook JSON.

Finally, return a 200 response code so that Postmark knows the inbound email was processed successfully.

render plain: 'Response Saved', status: 200

To recap, your full create method should now be:

def create
  # Parse the message
  message = JSON.parse(request.body.read)

  # Grab the Article ID from the message
  article_id = message['MailboxHash']

  # Find the article
  article = Article.find(article_id)

  # Create a new response
  article.responses.create(
    name: message['FromName'],
    email: message['From'],
    body: message['TextBody'] # Could also use message['HtmlBody']
  )

  # Return a 200 code so Postmark know’s the webhook was processed
  render plain: 'Response Saved', status: 200
end

By default, Rails comes with a security feature that requires POST requests to include an authenticity token to validate they were made from the app. As Postmark does not have access to this authenticity token, you’ll need to disable this feature for the create method.

Add the following above the create method definition to disable CSRF protection on the webhook endpoint.

protect_from_forgery except: :create

Set up a route #

Now your controller action is complete you just need to register a new route for it.

Add the following to your config/routes.rb file:

resources :responses, only: [:create]

Your app can now receive POST requests at /responses which will be handled by the create method on the ResponsesController.

Testing inbound processing #

Your app is now ready to start processing inbound emails!

Make sure both your local Rails server and Ultrahook are still running and navigate to http://localhost:3000/articles/1.

Scroll down to the bottom of the page and hit the Send a response button. This should launch your mail client.


Image of a test email example

Note that the email address includes the + symbol followed by the article ID, in this case, 1.

Type a quick message into the body of the email and hit send.

Wait a few seconds and then refresh the page. If everything is set up correctly, you should see your response at the bottom of the page.

Image of a successful email response on a test article

Now navigate to a different article and post a response their too.

Summary #

In this tutorial you’ve learned how to receive email in your Rails app using Postmark’s inbound email processing.

Now you’ve got the basics mastered, try tackling some more advanced topics like setting up a custom inbound email address or blocking inbound messages based on their spam score.

Be sure to let us know how you’re using inbound processing in your app.


Grab a copy of the completed code for the demo application on GitHub.

Matt West

Matt West

Product designer working on Postmark and DMARC Digests.