-
-
Save sowenjub/9917305b2b551a31df9f9ed0ec34d242 to your computer and use it in GitHub Desktop.
# mailboxes/concerns/mail_params.rb | |
module MailParams | |
extend ActiveSupport::Concern | |
def mail_params | |
attachments = build_attachments | |
body = build_rich_body(attachments) | |
{ subject: mail.subject, body: body, attachments: attachments.map { |a| a[:blob] } } | |
end | |
def build_attachments | |
mail.attachments.map do |attachment| | |
blob = ActiveStorage::Blob.create_after_upload!( | |
io: StringIO.new(attachment.decoded), | |
filename: attachment.filename, | |
content_type: attachment.content_type, | |
) | |
{ original: attachment, blob: blob } | |
end | |
end | |
def build_rich_body(attachments) | |
if mail.multipart? && mail.html_part | |
document = Nokogiri::HTML(mail.html_part.body.decoded) | |
attachments.map do |attachment_hash| | |
attachment = attachment_hash[:original] | |
blob = attachment_hash[:blob] | |
if attachment.content_id.present? | |
# Remove the beginning and end < > | |
content_id = attachment.content_id[1...-1] | |
element = document.at_css "img[src='cid:#{content_id}']" | |
element.replace "<action-text-attachment sgid=\"#{blob.attachable_sgid}\" content-type=\"#{attachment.content_type}\" filename=\"#{attachment.filename}\"></action-text-attachment>" | |
end | |
end | |
document.at_css("body").inner_html.encode("utf-8") | |
elsif mail.multipart? && mail.text_part | |
mail.text_part.body.decoded | |
else | |
mail.decoded | |
end | |
end | |
end | |
# models/post.rb | |
class Post < ApplicationRecord | |
has_rich_text :body | |
has_many_attached :attachments | |
end | |
# mailboxes/posts_mailbox.rb | |
class PostsMailbox < ApplicationMailbox | |
include MailParams | |
def process | |
Post.create mail_params | |
end | |
end |
Thank you for the gist !
FYI, I tested with a gmail inbound email, I got an error line 33 : element can be nil and element.replace
fails.
You can add a next unless element
line 34 to fix it.
@jumichot Interesting, but then your text content won't feature the attachment. We could simply append the action-text-attachment
. But maybe that content_id appears inside another HTML tag?
What does the mail.html_part.body.decoded
look like?
My test case : 2 attachments
- one embedded direclty in the email body (via drag and dropping an image in gmail interface), the attachment is present in the html via an image tag
- and one another regular attachment that doesn't appear in the html body (that cause the problem)
Both attachments have content_ids
The body looks like that :
<div dir=3D"ltr"><div><div dir=3D"ltr" class=3D"gmail_signature" data-smart=
mail=3D"gmail_signature"><div dir=3D"ltr"><div><div dir=3D"ltr"><div dir=3D=
"ltr"><div><br></div></div></div></div></div></div></div><div class=3D"gmai=
l_quote"><br><div dir=3D"ltr">Bonjour Julien,<div><br></div><div>Ceci est u=
n test, pouvez-vous intervenir au plus vite =C3=A0 l'adresse indiqu=C3=
=A9e ci dessous ?</div><div><br></div><div>Merci d'avance<img src=3D"ci=
d:ii_kncy5jja0" alt=3D"Screenshot 2021-04-10 at 10.33.18.png" width=3D"543"=
height=3D"126" style=3D"margin-right:0px"><br><div><div dir=3D"ltr" data-s=
martmail=3D"gmail_signature"><div dir=3D"ltr"><div><div dir=3D"ltr"><div di=
r=3D"ltr"><div>Cordialement,=C2=A0</div><div><br></div><div>--</div><div><b=
>Julien</b></div><div><br></div><div><br></div><br></div></div></div=
></div></div></div></div></div>
</div></div>
and my .mail.attachments.map(&:content_id)
looks like that ["<ii_kncy5jja0>", "<f_kncy6vaw1>"]
The attachment with the content id f_kncy6vaw1 is not present in the HTML and raise an error.
Alright, then I guess we need to append the attachment.
Also, we may want to delete the signature.
I'll revisit that sometime later, this feature is on pause for a couple of days.
The original
PostsMailbox
is here: https://github.com/gorails-screencasts/action-mailbox-action-text/blob/master/app/mailboxes/posts_mailbox.rb