Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails ActionMailer attachments show up as garbled text

I'm trying to send pdf attachments in one of my rails applications, but the attachment comes through as text instead of as a proper pdf.

My mailer looks like this:

class Notifications < ActionMailer::Base
  def contact(email_params, sent_at = Time.now)
    subject "" << email_params[:subject]
    recipients "" << email_params[:client]
    from "#{email_params[:name]} <#{email_params[:address]}>"
    attachments['invoice.pdf'] = File.read("#{Rails.root.to_s}/public#{email_params[:attach]}") unless email_params[:attach].blank?
    sent_on sent_at
    body :message => email_params[:body], :sender_name => email_params[:name]
  end
end

And what I get in my mail inbox:

--
Date: Thu, 23 Feb 2012 13:50:58 -0800
Mime-Version: 1.0
Content-Type: text/plain;
charset=UTF-8
Content-Transfer-Encoding: 7bit
Content-ID: <[mailserver]>

Message Body

--
Date: Thu, 23 Feb 2012 13:50:58 -0800
Mime-Version: 1.0
Content-Type: application/pdf;
charset=UTF-8;
filename=invoice.pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename=invoice.pdf
Content-ID: <[mailserver]>

Followed by a very long string of ascii characters

Without any attachment, that header information is not sent, and I just get the "Message Body" part in my inbox. I suspect the File.read() part of the attachment line in my mailer.rb is somehow the culprit, but it is pointing to a valid pdf file on my server which I can access through my browser. Logs only say the mail was sent with the correct parameters, but it's being sent as what looks like decompiled text or something like if you opened a pdf in a plain text editor.

The mailer view, contact.html.erb, is simply: <%= @message %> If that helps.

Any idea what I might be doing wrong?

Thanks.

Update:

Apparently, I needed both contact.erb, as well as contact.html.erb in my views directory. Just copying the file, and renaming it worked. However, now the message body is blank. Only the attachment shows up.

like image 205
aperture Avatar asked Dec 22 '22 01:12

aperture


2 Answers

Just for reference, I had the same problem, and in my case the solution was to swap the attachment and mail lines. First attach, then call mail.

WRONG

def pdf_email(email, subject, pdfname, pdfpath)
  mail(:to => email, :subject => subject)
  attachments[pdfname] = File.read(pdfpath)
end

GOOD

def pdf_email(email, subject, pdfname, pdfpath)
  attachments[pdfname] = File.read(pdfpath)
  mail(:to => email, :subject => subject)
end
like image 75
Karolis Avatar answered Jan 08 '23 06:01

Karolis


Well, this finally ended up working:

class Notifications < ActionMailer::Base
  def contact(email_params, sent_at = Time.now)
    subject "" << email_params[:subject]
    recipients "" << email_params[:client]
    from "#{email_params[:name]} <#{email_params[:address]}>"

    part "text/plain" do |p|
      p.part :content_type => "text/plain", :body => render("contact.erb")
    end

    @message = email_params[:body]

    attachments['invoice.pdf'] = File.read("#{Rails.root.to_s}/public#{email_params[:attach]}") unless email_params[:attach].blank?   

    sent_on sent_at

    mail(:to => email_params[:client],
         :from => email_params[:address],
         :subject => email_params[:subject]) do |format|
      format.html { render 'contact' }
      format.text { render :text => email_params[:body] }
    end
  end
end

I'm sure there are extraneous lines, but it's working as is at the least. I also renamed the view file from contact.erb to contact.text.erb in addition to having already copied that file to contact.html.erb.

And I'm calling the method from my controller with:

  def send_mail
    Notifications.deliver_contact(params[:email])
    redirect_to "/mail/success"
    #Notifications.contact(params[:email]).deliver
  end
like image 29
aperture Avatar answered Jan 08 '23 06:01

aperture