I'm using the Mailman gem to process incoming email for my Rails app. My application looks for a YAML document in the plain-text email and then loads it into a Ruby object for further manipulation by the app.
However, I want to be able to plan ahead for email clients that might respond with a multi-part email. I need to get the plain-text part of the email and pass it into the YAML parser.
For some reason, it's still having problems parsing the YAML. I'm guessing because it's not really getting the plain text part here.
Is there a better way to get the text/plain part of an email with Mailman? Should I scrap Mailman and just get down and dirty with ActionMailer instead?
Mailman::Application.run do
default do
begin
message.parts.each do |part|
Mailman.logger.info part.content_type
if part.content_type == 'text/plain; charset=ISO-8859-1' # My poor way of getting the text part
the_yaml = part.body.decoded.scan(/(\-\-\-.*\.\.\.)/m).first.last # Find the YAML doc in the email and assign it to the_yaml
ruby_obj = YAML::load(the_yaml.sub(">", "")) # Remove any >'s automatically added by email clients
if ruby_obj['Jackpots']
ruby_obj['Jackpots'].each do |jackpot|
jp = Jackpot.find(jackpot['jackpot']['id'])
jp.prize = jackpot['jackpot']['prize']
jp.save
end
end
end
end
rescue Exception => e
Mailman.logger.error "Exception occurred while receiving message:\n#{message}"
Mailman.logger.error [e, *e.backtrace].join("\n")
end
end
end
I was able to find a little bit better way to handle getting the text part of the email.
Mailman::Application.run do
default do
begin
if message.multipart?
the_message = message.text_part.body.decoded
else
the_message = message.body.decoded
end
the_yaml = the_message.sub(">", "").scan(/(\-\-\-.*\.\.\.)/m).first.last
ruby_obj = YAML::load(the_yaml)
if ruby_obj['Jackpots']
ruby_obj['Jackpots'].each do |jackpot|
jp = Jackpot.find(jackpot['jackpot']['id'])
jp.prize = jackpot['jackpot']['prize']
jp.save
end
end
rescue Exception => e
Mailman.logger.error "Exception occurred while receiving message:\n#{message}"
Mailman.logger.error [e, *e.backtrace].join("\n")
end
end
end
And then after running it through the debugger and inspecting after the text part was successfully parsed. It would get hung up on the YAML loading. Turns out, a couple of my lines were too long, to the email client inserted a newline, breaking a comment in my YAML, and thus breaking the whole YAML document.