Rails 3 send multipart email with premailer and have the option for using a template or not

I have the option to create an email wherein the contents can either be part of an HTML document or be an entire HTML document. If it's only a part, the Mailer should use a template for rendering. If it contains the <html> element (indicating it's an entire HTML document), it should not use the template file when sending. I have pretty much all of it set up and working except for the fact that the 'email parts' in the sent email are way out of order and duplicated in some cases. It screws up the rendering of the email. I think this has to do with my call to mail and what Premailer does on the deliver method but I'm not sure where to go from here.

EBlast.rb

def main(m, args={})
    # 'm' is an Email.rb object
    ready_email 'E-Blast', args # Don't worry about this
    assign_private_id_header # or this

    # Read the Template
    @variable_width = (@user.email =~ /@hotmail|@live|@windows/).nil?
    @page_title = m.subject
    m.prep_for_email # squeeze unnecessary whitespace and create 'quick-nav' links based on h1 tags

    # Read in attachments
    m.inline_attachments.each do |name, loc|
    attachments.inline[name] = File.read(loc)
    end
    m.external_attachments.each do |name, loc|
    attachments[name] = File.read(loc)
    end


    mail_object = mail(:to => @user.email, :subject => m.subject) do |format|
    format.text { render :text => 'placeholder' } # This should be replaced by Premailer html > text conversion upon deliver!

    if m.needs_template?
        # Use the main.html.erb template
        @email = m # Needed for helper methods in template view
        format.html 
    else
        # Use the content of the email as the entire HTML source
        format.html { render :text => m.content }
    end
    end
    # Apply Google Analytics tracking parameters to links pointing to this domain
    m.prep_for_sending mail_object
end

Email.rb

def prep_for_sending(mail_object)

    unless mail_object.html_part.nil?
    # Replace the content with the generated html
    self.content = mail_object.html_part.body.raw_source
    # Add Google analytics tracker info to links
    apply_url_tracker :source => "Eblast Generator", :medium => :email
    # Replace the html raw_source
    mail_object.html_part.body = content

    end

    # Return mail object so mailer can call deliver
    mail_object

end

UPDATE: After some workarounds (creating a blank template for 'non-template content') I've discovered another problem...one that I think really gets to the heart of what's happening. The multipart/mixed and multipart/related parts are not being generated when there is text, html and attachments (either just inline or both inline and external).

UPDATE 2: Partial success! Apparently I'm a magnet for strange errors. I have to use File.open(loc, 'rb') { |f| f.read } instead of File.read(loc) when reading attachments because I'm using windows for a dev machine. S.I.G.H. Is there a way to specify the 'rb' flag in File.read? I can't find documentation anywhere. I'm now going to try and get Premailer to work as I had to disable it to test this.

FINAL UPDATE: Looks like Premailer is screwing up the multipart layout. Is there a way of using Premailer without it hooking into deliver on it's own? I only need it to inline the CSS and generate the plain text part.

Upvotes: 0

Views: 732

Answers (1)

Confirmed that this is a bug with premailer-rails3 gem here. Used gem "premailer-rails3", :git => "git://github.com/tdgs/premailer-rails3.git" and it sends properly. There goes 6 hours :)

ADDENDUM: It seems Premailer may be suffering from the same problem I was having in this thread. It seems to also duplicate the html part and that probably ends up screwing with the whole email parsing. So really in the end it may be ActionMailer - or whichever class is responsible when assigning content to the body of a Mail part.

Upvotes: 1

Related Questions