1
votes

I have an email client in my Rails 3.2 app that stores emails in the database. The content of the email is saved using tinyMCE with the attachments saved using Paperclip. These emails are sent using the Mailer that I created, shown below:

class MessageMailer < ActionMailer::Base   
  def messaging_message(msg)
    begin
      Message.transaction do
        @msg = msg

        msg.attached_files.each do |attached_file|
          attachments[attached_file.file_file_name] = File.read("#{Rails.root.to_s}/public/attachments/messaging/messages/#{msg.id}/#{attached_file.id}/#{attached_file.file_file_name}")
        end

        mail_msg = mail(
          to:           Message.convert_to_mail_addresses(msg.to_recipients), # This converts the list of Recipient objects into "[email protected]; [email protected]" format
          cc:           Message.convert_to_mail_addresses(msg.cc_recipients),
          bcc:          Message.convert_to_mail_addresses(msg.bcc_recipients),
          from:         msg.access_department.email,
          subject:      msg.subject,
          body:         msg.body,
          content_type: "text/html"
        )

        # Sets the user_name, password and domain based on the FROM address the user selected in the app
        mail_msg.delivery_method.settings.merge!(msg.access_department.mail_settings)
      end
    rescue Exception => e
      Rails.logger.error "MODEL: '#{class_name}' - METHOD: '#{method_name}'"
      Rails.logger.error " -> ERROR: #{e}"
      Rails.logger.error "BACKTRACE:"
      Rails.logger.error "#{e.backtrace.join("\n ")}"
      return false
    else
      return true
    end
  end
end

I then run this action with the following code:

msg = Message.find(20)
MessageMailer.messaging_message(m).deliver

Without attachments this works like a charm. However, when I have attachments, they appear in the body of the email as a long string of characters, i.e. a text version of the mime type. Here is an example:

----==_mimepart_54be256d7d18_13ad78fe74390bc Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit

Lorem ipsum dolor sit amet, per quot antiopam elaboraret cu, ei epicuri perfecto has. Ut utinam discere legimus vis, an quidam habemus menandri nec. Eam dolores suavitate dissentias in, wisi vitae at his. Qui et augue conclusionemque, ut sea doctus impetus inermis. Vitae semper molestiae id mea, est corpora prodesset referrentur ex. In mel diceret expetendis. Mea te impetus vivendum interesset, erroribus referrentur mea ex.

Possit ornatus labores te eos. Per id unum mucius insolens, ne quo elitr ludus nusquam. Amet possit persius eam cu. Pro no nostro nominati. Ut zril persecuti eum, eu ius graece tempor, an agam mediocrem disputationi est.

My Personal Signature

----==_mimepart_54be256d7d18_13ad78fe74390bc Content-Type: image/jpeg; charset=UTF-8; filename=Side_rolling_bulk_vessels_Klein.jpg Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=Side_rolling_bulk_vessels_Klein.jpg Content-ID: <[email protected]> /9j/4AAQSkZJRgABAgEASABIAAD/4RZ1RXhpZgAATU0AKgAAAAgABwESAAMA AAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAABAAAAagEoAAMAAAABAAIAAAEx AAIAAAAbAAAAcgEyAAIAAAAUAAAAjYdpAAQAAAABAAAApAAAANAAAABIAAAA AQAAAEgAAAABQWRvYmUgUGhvdG9zaG9wIENTIFdpbmRvd3MAMjAwOTowMzoy NCAxMDo0NDo1OAAAAAAAA6ABAAMAAAAB//8AAKACAAQAAAABAAABVKADAAQA AAABAAAB4wAAAAAAAAAGAQMAAwAAAAEABgAAARoABQAAAAEAAAEeARsABQAA AAEAAAEmASgAAwAAAAEAAgAAAgEABAAAAAEAAAEuAgIABAAAAAEAABU/AAAA AAAAAEgAAAABAAAASAAAAAH/2P/gABBKRklGAAECAQBIAEgAAP/tAAxBZG9i ZV9DTQAC/+4ADkFkb2JlAGSAAAAAAf/bAIQADAgICAkIDAkJDBELCgsRFQ8M DA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM DAENCwsNDg0QDg4QFA4ODhQUDg4ODh........

I have tried reordering my code, rewriting it in the format shown here in the Mail gem, as well as explicitly adding the attachments with their mime type and encoding the myself, yet I still get the same result.

Can anyone please explain where I'm going wrong?

2

2 Answers

3
votes

I faced the same issue like above.

Just remove the line content_type: "text/html" from your code.

Rails will automatically send a multipart email with an attachment, properly nested with the top level being multipart/mixed and the first part being a multipart/alternative containing the plain text and HTML email messages.

For more info, see Rails - Sending Emails with Attachments

1
votes

After many hours of searching and trial & error, I managed to find what was wrong with my code.

The problem wasn't in the way that I was adding the attachments, but in the way that I was adding the body of the email. An email is structured in the following way (this is very simplistic):

  • multipart/mixed
    • multipart/alternative
      • text/html
      • text/plain
    • image/png
    • application/pdf
    • ....

I'm not sure why, but I'm guessing that by adding the content_type of the email directly, I was overriding some defaults in the creation of this email. In addition, the msg.contents returned HTML.

Since I had a feeling that my issue was with the content_type, I tried creating a view for my contents. So I now had the following:

mailers/message_mailer.rb

class MessageMailer < ActionMailer::Base   
  def messaging_message(msg)
    begin
      Message.transaction do
        @msg = msg

        msg.attached_files.each do |attached_file|
          attachments[attached_file.file_file_name] = File.read("#{Rails.root.to_s}/public/attachments/messaging/messages/#{msg.id}/#{attached_file.id}/#{attached_file.file_file_name}")
        end

        mail_msg = mail(
          to:       Message.convert_to_mail_addresses(msg.to_recipients), # This converts the list of Recipient objects into "[email protected]; [email protected]" format
          cc:       Message.convert_to_mail_addresses(msg.cc_recipients),
          bcc:      Message.convert_to_mail_addresses(msg.bcc_recipients),
          from:     msg.access_department.email,
          subject:  msg.subject
        )

        # Sets the user_name, password and domain based on the FROM address the user selected in the app
        mail_msg.delivery_method.settings.merge!(msg.access_department.mail_settings)
      end
    rescue Exception => e
      Rails.logger.error "MODEL: '#{class_name}' - METHOD: '#{method_name}'"
      Rails.logger.error " -> ERROR: #{e}"
      Rails.logger.error "BACKTRACE:"
      Rails.logger.error "#{e.backtrace.join("\n ")}"
      return false
    else
      return true
    end
  end
end


app/vies/message_mailer/messaging_message.html.haml

!!!
%html
  %head
    %meta{content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}
  %body
    = @msg.contents.html_safe


Now when I ran the following:

msg = Message.find(20)
MessageMailer.messaging_message(m).deliver

it all worked, and I got an email with downloadable attachments!

What I'm guessing happened is that now I let the Mail gem deal with the creation of my Email rather than setting content types myself.

Hope this helps others that encounter the same issue, as I found very little help with this exact problem.