thoughtbot / griddler

Simplify receiving email in Rails (deprecated)
http://griddler.io/
MIT License
1.38k stars 199 forks source link

Inline image content-id (cid) : filename mapping gets lost #306

Closed brentkearney closed 4 months ago

brentkearney commented 6 years ago

Hello,

I'm using Griddler to receive email for distribution to a mail list. I'm having trouble reconstructing the inline attachments data, because @email doesn't contain any filename:content-id mapping, as appears in the original message (in the "email_rfc822" param).

For example, an incoming email with an inline attachment has something like this in the original message body:

--Apple-Mail=_94A907EA-0BDD-4286-8C91-03AC6742495A\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: inline;\r\n\tfilename=foo.jpg\r\nContent-Type: image/jpeg;\r\n\tx-unix-mode=0644;\r\n\tname=\"foo.jpg\"\r\nContent-Id: <B8377B84-3982-40CD-9B98-A59F11BD2B18>\r\n

The Content-Id: number appears in the @email.raw_html as the <img src="cid..., but the filename is not mentioned in the tag. For example, the message above would have in @email.raw_html:

<img apple-inline="yes" id="D80464A6-0219-4BEB-8122-3AD0C36308BB" src="cid:B8377B84-3982-40CD-9B98-A59F11BD2B18" class="">

As a result, when I resend the message, the image placeholder icon appears inline, with the attachment at the bottom of the email. It would be great if @email.attachments had a field for the Content-Id. Then I could do something like this in my Mailer class:

message[:attachments].each do |ad|
  if ad.content_type.include?('image')
    attachments.inline[ad.original_filename] = {
       mime_type: ad.content_type,
       content: File.read(ad.tempfile),
       cid: ad.content_id
     }
  else
    attachments[ad.original_filename] = {
       mime_type: ad.content_type,
       content: File.read(ad.tempfile)
     }
   end
end

mail(to: recipient, from: from, subject: subject) do |format|
    format.html { render html: html_body.html_safe } unless html_body.blank?
    format.text { render text: text_body }
end

... and my mail service (SparkPost) would be able to map the attachment filename to Content-Id correctly, and the image would display inline.

Is there a known work-around for handling inline attachments?

Many thanks!

brentkearney commented 6 years ago

As it turns out, including a "cid:" parameter in the attachments.inline hash for sparkpost does not actually assign the content-id to the attachment. So I have more Sparkpost research to do; maybe inline images aren't possible in this context.

I was able to get the Content-Id's of inline images from the @email by doing a: params = @email.send(:params), and then parsing it out of params['_json'][0]['msys']['relay_message']['content']['email_rfc822']. Perhaps just including an . email_rfc822 method for @email would be cleaner.