From The Blog

ActionMailer quicktips: receiving and parsing mail

I was working on a fix for a mail_receiver model that implemented ActionMailer’s receive method. I was seeing a problem while it was trying to...

I was working on a fix for a mail_receiver model that implemented ActionMailer’s receive method. I was seeing a problem while it was trying to parse out sub-parts from a mime multitype message, where it wasn’t capturing the content correctly for multipart/alternative. The existing code was pulling the message text as so:

def get_multipart_body(mail)  
  types =  mail.parts.collect(&:content_type)
  if types.include?("multipart/alternative")
    body = mail.parts.find { 
      |m| m.content_type == "multipart/alternative" 
    }.body
  end
end

What fixed it was this:

def get_multipart_body(mail)
  types = mail.parts.collect(&:content_type)
  if types.include?("multipart/alternative")
    # we need to dig down a level to get the sub-parts
    m_part =  mail.parts.find { 
      |m| m.content_type == "multipart/alternative" 
    }
    sub_types = m_part.parts.collect(&:content_type)
    if sub_types.include?("text/plain")
      body = get_text_plain(m_part)
    else
      body = get_text_html(m_part)
    end
  end
end

So with ‘mail’ being a TMail object (which ActionMailer uses to parse email into its constituent parts), the sub-parts can be retrieved by calling mail.parts.find to get the sub-parts of the message.

Now technically, there can be an unlimited number of nestings within parts (check out RFC 2046 for the nitty-gritty details). The fix above only goes one level down. I considered doing a little recursive method for handling it, but ran out of time. Still, I’ll keep that idea as an exercise for future interest.

Other Posts That Might Interest You

  1. Nuts, I forgot to attach that file, again…
  2. Custom Form Validations Without ActiveRecord
  3. Managers: Be Present

Tags: 

blog comments powered by Disqus