Home > Blockchain >  How to add arbitrary inline images in Rails Mailer?
How to add arbitrary inline images in Rails Mailer?

Time:07-14

I'm working on a Rails app that sends emails with arbitrary HTML content. In the mailer, we have:

class YeetMailer < ActionMailer::Base
  def welcome_email(html)
    
    # custom method that returns string[] where each string is an image src attribute
    @images = get_images_for_yeet_email(html)

    # add image attachments / Content-ID headers
    @images.map { |i|
      attachments.inline[i] = URI.open(i).read
    }

    # pass the html to the view
    @html = html
  end
end

Then in the view yeet_mailer/welcome_email.slim:

= @html

All of the guides I've seen (e.g. this Rails guide) suggest one should use <%= image_tag attachments['image_name.jpg'].url %> to get the images with cid content to render in the email, but I haven't yet figured out how to do so in the case of an arbitrary number of images.

I thought I could do:

@images.map { |i|
  attachments.inline[i] = URI.open(i).read
  html = html.sub(i, attachments.inline[i])
}

To make the replacements, but this throws no implicit conversion of Mail::Part into String. I added a byebug line to get into a debugger inside the welcome_email method and puts(attachments.first) gave some insight (here's the output), so I'm getting closer...

Anyone know how I should proceed? Any pointers would be very helpful!

CodePudding user response:

Turns out you can:

   @images.each_with_index { |i, idx|
      attachments.inline[i] = URI.open(i).read
      cid = attachments[idx].header.find { |h| h.name == 'Content-ID' }.field.value
      html = html.sub(i, "cid:#{cid}")
   }
  • Related