Download IMAP attachments directly to Amazon S3

One of our companies, We&Co, makes it easy for restaurants to recruit and find new folks to work for them. One way we do this is share their jobs posts with Indeed. Indeed in turn allows people to apply to these jobs and shares the resumes with us via email. No API. No nice and tidy bundled transfer. Nope, we get an email for each applicant. Which on most days now is hundreds of people.

We handle this volume of emails with the Ruby IMAP class. I've done this sort of thing in a bunch of languages so trust me when I say that Ruby implements this pretty well.

One thing however that I didn't see a lot of documentation on was how to handle attachments. We want to save all of the resumes we grab to Amazon S3. Below is some code on how we incorporate IMAP and S3.

The code below can be found here: https://github.com/codeisstandard/standard_imap_s3

First we need to use IMAP to access our mailbox:
 

imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
imap.login("email@email.com", "password")
imap.select('Inbox')

Now that we're connected we need to loop through our messages. This is one part of the IMAP API that's still clunky in my opinion. Searching and navigating messages still feels like some arcane shit from 1988. Oh well.

# loop through our emails
imap.search(["NOT", "SEEN"]).each do |message_id|

There's some more code you can do at this point that I'll skip for now (it's in the repo above though). Here's the code to actually save an attachment to S3:

def handle_attachments(msg)
mail = Mail.new(msg)
unless mail.attachments.blank?
mail.attachments.each do |attachment|
file = StringIO.new(attachment.body.decoded)
# just to make it work
user_id = 4
attachment = attachment.save_attachment(user_id, file)
end
end
end


There you have it.

TJ
Feb. 22 2015