Mail Gem: Render received email in browser / Full

2019-09-02 10:23发布

问题:

I am working with the Mail Gem to receive emails in my Rails 4 application. The mails are grabbed via POP from a mailbox, every 10 minutes or so, via the Gem.

I need to render these emails - mostly in HTML format - and am having trouble saving the body in HTML, not to mention working with things like embedded images. I'm probably missing something here- looked all over StackOverflow but haven't seen an answer to related questions yet.

I have been working with

message.body.decoded

and also looked at the html_part v. text_part - but I don't see a method to get to just the enclosed HTML. Looks like I need to strip the headers, which the Mail Gem seems to leave in the body- then also deal with any inline attachments. Surely a gem for this must exist..? Or an approach...? Your advice is valued.

I did find the Mailcatcher Gem - but that is really its own Sinatra app. I might just try adapting this gem but that appears to be a lot of work. Surely someone else has already dealt with this problem..?

I would also value a suggestion on how to best store the message body in MySQL - am thinking large text or blob type.

Thank you!

回答1:

I use letter opener It works fine... And if you are using vagrant as the main development machine you you can use this Letter opener web



回答2:

I worked on that last days and I think that I found a solution.

In the first place you have to find out if mail is multipart,

mail.multipart?

If mail isn't multipart, you can get body like that,

mail.body.decoded

If mail is multipart, you have to choose if you want to store html or text part. But of course you can store both parts, it's on you.

#for html part

html_decoded_body = nil

mail.parts.each do |part|
  if part.content_type.include?('html')
    html_decoded_body = part.body.decoded
  end
end

 #for text part

 text_decoded_body = nil

 mail.parts.each do |part|
  if part.content_type.include?('text')
    text_decoded_body = part.body.decoded
  end
end

Then you need to force encoding before saving this body in your database.

(html_decoded_body || text_decoded_body).force_encoding('UTF-8')

In this point you're ready to save email body in your database but later, when you'll try to render this html, you'll find out that you can still see some weird stuff and your links and images won't work. The reason is very simple. Emails are using some weird coding (read this article for more information https://en.wikipedia.org/wiki/Quoted-printable) and you have decode their body one more time. I'm using for that this JS library: https://github.com/mathiasbynens/quoted-printable.

So last code is in javascript.

quotedPrintable.decode(email_body)

And wuaala.