Arthur Chang

Entrepreneur, Software Engineer, and Photographer
« Back to blog
Apr 22
Views

Rails and processing inbound emails

The TMail library is now included in the latest Rails, and handles inbound emails amazingly well.  No need to go into parsing MIME/SMIME for different email clients anymore, this does it all for you.  I found a lot of resources through searches on the subject, but they were slightly outdated and a bit confusing.  The quick and dirty of it is:

  1. Create a mailer
    • ruby script/generate mailer SomeNameMail
  2. def a receive method that accepts a TMail object - the email parameter is the TMail object in the example below:
    • def receive(email)
      ... # handle mail here (see next step) ...
      end

  3. Retrieve to, from, subject, attachments at more with very simple commands.  Note that email.to and email.from returns arrays in the case that there's more than one person being sent or recieved from, so make sure you grab all of them or just the first one:
    • @to = email.to.first
      @from = email.from.first

  4. And to get the body of the email with the 'text/html' content-type (meaning it comes with all the nice html tags) you need to do a little extra below:
    • @body = body_html(email)
      ...
      def body_html(email)
      result = nil
              if email.multipart?
                  email.parts.each do |part|
                      if part.multipart?
                          part.parts.each do |part2|
                              result = part2.unquoted_body if part2.content_type =~ /html/i
                          end
                      elsif !email.attachment?(part)
                          result = part.unquoted_body if part.content_type =~ /html/i
                      end
                  end
              else
                  result = email.unquoted_body if email.content_type =~ /html/i
              end
              result = email.body if result.nil?
              return result.strip
          end

TMail RDOC: http://tmail.rubyforge.org/rdoc/index.html

To get mail into the receive action is another story.  Read #46 in the Advanced Rails Recipes book for more information on how to do this.  The basics of it is to run a daemon that fetches mail from an inbox and feeds it as TMail to your mailer.  The mail_fetcher script mentioned in the Advanced Rails Recipes does a good job of it.

Attachments are also very simple, just email.attachments returns the array of attachments, which you can then save off to something like Paperclip or filecolumn.

Cheers!