Before you attempt to handle images in the body of an email, you should first check if the email body is multipart or not:
# handle multipart message
body = mail.parts.present? ? mail.parts[0].body.decoded : mail.decoded
What does a multipart email look like? Something like this:
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--
Note that the Content-Type header of the email contains a boundary which is used to separate the email parts. Now that you can see how each part can be a different content type, you have the proper context to understand how to parse each part.
https://github.com/mikel/mail#reading-a-multipart-email
Rails uses the mail
gem, so you should reference their docs to understand full functionality. But in short, you can do the following:
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
To display the original content of the message, just save the part in its entirety. You'll have to either infer the content type store it alongside the message in your database.
Assuming you're saving an HTML message, you can use Nokogiri, which comes with Rails, to generate an HTML document.