Using Mailgun and Python to parse email for your applications
In case you didn't hear, Rackspace recently acquired Mailgun, a YCombinator startup that makes it really easy to integrate email into your application. Mailgun does the simple things like sending password confirmations and shipping notifications, but it also makes it A LOT easier to build some really good stuff.
Figuring out how to make email work with the cloud is one of the biggest questions that we get at Rackspace, so we're publishing some code samples that show you how to build some really cool things with Mailgun. Mailgun has a free plan that will let you try all these things and send up to 200 emails per day for free. Then they've got plans starting at only $20 a month. So, onto the cool stuff!
Parsing and posting email messages to your app using Mailgun Routes
Have you ever gotten an email from a social application to notify you of a comment on a thread you're watching, then you had to login to the app to reply? That is totally unnecessary.
Here's how to integrate email communications into your app seamlessly. Some of the code in this example is written in Python for a Django app, but the same thing is possible in your favorite language (check out the Mailgun user manual for full documentation on parsing and posting emails to your app using Mailgun).
First, you need to decide if you want to filter the emails coming into your app so you only do something for certain incoming emails. Maybe it’s only one kind of email that you want to do something with, like emails asking for support, or emails from a particular person or domain. You can match based on things like recipient or any field in the MIME header of the email. Here are some examples:
|match_recipient("email@example.com")||Returns true if the incoming message is going to firstname.lastname@example.org.|
|match_recipient(".*@myapp.com")||Returns true if the incoming message is going to any user at @myapp.com.|
|match_header("subject", "hello")||Returns true if the subject of the message contains word ‘hello.’|
|catch_all()||Returns true if no other route matched, to implement catch-all behavior.|
After matching, you need to decide what you want to do. Maybe you don't want to do anything. Or maybe you want to post the email and its contents to your app. These actions are called "routes" (think, I'm routing this email somewhere). There are three actions that you can take based on a match.
|forward(“http://myapp/post”)||Parses the message and forwards it to a given URL.|
|forward(“email@example.com”)||Forwards the message to a given email address.|
|stop()||Stops and doesn’t look at any other routes.|
These actions are where the really cool things start to happen. When you forward the email to your app, e.g. forward("firstname.lastname@example.org"), you can post to HTTP. You can post two ways:
Fully parsed: Mailgun will parse the message, process attachments and attempt to separate quoted parts from the actual message. This is the preferred option.
Raw MIME: message is posted as-is. In this case you are responsible for parsing MIME. To receive raw MIME messages, the destination URL must end with mime (e.g. http://myhost/post_mime)
You can then take these difference parts of the parsed message and update your app with the data. The Python code below shows an example of what you would need to do in your Django app to handle the incoming messages:
Mailgun routes are very powerful. For example, you can use regular expression captures and refer to captured values in your destination. With routes, you can also create email addresses (even on the fly) for every user or object or ID in your app to enable very granular behavior. To learn more about Routes, check out the Routes section of the User Manual or contact Mailgun support. The Mailgunners also wrote a blog post on routes a while ago that has some good additional information. Over the next few weeks we’ll post additional how-tos and sample code, so let us know if there is anything you're wondering how to do!