How do I get the text part only from Mailman email?

859 views Asked by At

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
1

There are 1 answers

0
RFC1337 On BEST ANSWER

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.