在尝试处理电子邮件正文中的图像之前,您应该首先检查电子邮件正文是否是多部分的:
# handle multipart message
body = mail.parts.present? ? mail.parts[0].body.decoded : mail.decoded
多部分电子邮件是什么样的?像这样的东西:
MIME-Version: 1.0
Date: Mon, 8 Nov 2021 19:43:58 +0100
References: <....mail>
In-Reply-To: <....mail>
Message-ID: <...@mail.gmail.com>
Subject: Re: Howdy
From: You <you@example.com>
To: Me <me@example.com>
Content-Type: multipart/alternative; boundary="000000000000376c4305d04b60e2"
--000000000000376c4305d04b60e2
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Here is my reply to an original message.
--000000000000376c4305d04b60e2
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div>
<img src=3D"https://placeholder.img" />
<img src=3D"https://placeholder.img" />
</div>
--000000000000376c4305d04b60e2--
请注意,电子邮件的 Content-Type 标头包含用于分隔电子邮件部分的边界。既然您可以看到每个部分如何成为不同的内容类型,那么您就有了正确的上下文来了解如何解析每个部分。
https://github.com/mikel/mail#reading-a-multipart-email
Rails 使用mail
gem,所以你应该参考他们的文档来了解完整的功能。但简而言之,您可以执行以下操作:
if mail.parts.present? && mail.parts[0].content_type == 'text/html'
sanitized = Rails::Html::WhiteListSanitizer.new.sanitize(mail.parts[0], tags: ['img'])
# => "\n <img src=\"https://placeholder.img\">\n <img src=\"https://placeholder.img\">\n\n"
html_doc = Nokogiri::HTML(sanitized)
html_doc.to_s
# => "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body>\n<img src=\"https://placeholder.img\">\n <img src=\"https://placeholder.img\">\n</body></html>\n"
end
要显示消息的原始内容,只需完整保存该部分即可。您必须推断内容类型将其与数据库中的消息一起存储。
假设您正在保存 HTML 消息,您可以使用 Rails 附带的 Nokogiri 来生成 HTML 文档。