How to modify actionmailer email html_part before sending

雨燕双飞 提交于 2019-12-22 17:46:10

问题


I have everything at the point where I'm about to send out the email but I need to modify all links to include Google Analytics attributes. The problem is that if I try and read/write the html_part.body of the email, the entire html string somehow becomes encoded and doesn't display the email properly (i.e. <html> becomes &lt;html&gt;). I have logged the html_part.body.raw_source in the logger and it shows as proper unencoded HTML, it's only when the email is actually sent does the encoding occur.

EBlast.rb (ActionMailer)

def main(m, args={})

    # Parse content attachment references (they don't use helpers like the layout does)
    # and modify HTML in other ways
    m.prep_for_email self

    @email = m # Needed for helper methods in view
    mail_args = {
    :to => @user.email,
    :subject => m.subject,
    :template_path => 'e_blast',
    :template_name => 'no_template'
    }
    mail_args[:template_name] = 'main' if m.needs_template?

    m.prep_for_sending mail(mail_args)
end

Email.rb

def prep_for_sending(mail_object)

    if mail_object.html_part

    # If I simply do a 'return mail_object', the email sends just fine...
    # but the url trackers aren't applied.

    # Replace the content with the entire generated html
    self.content = mail_object.html_part.body.decoded

    # Add Google analytics tracker info to links in content
    apply_url_tracker :source => "Eblast Generator", :medium => :email

    # Replace the html_part contents
    mail_object.html_part.body = content

    # At this point, mail_object.html_part.body contains the entire
    # HTML string, unencoded. But when I send the email, it gets its
    # entities converted and the email is screwed.

    end

    # Send off email
    mail_object

end

回答1:


Looks like I'm answering my own question again - I'm on a roll this week.

Apparently setting the body directly creates some odd attribute called 'body_raw' instead of replacing the raw_contents of the html_part. So basically I ended up having a duplicate part embedded in the mail object (I don't know why it does this). Creating a separate Mail::Part and assigning it to html_part just added another part instead of replacing html_part! WTF?!

New Edit: Scratch my last remark about String.replace. It looked like it was working but when I went to another computer and tested it, the same problem of duplication occurred.

Another Edit: Finally?

Before I executed the apply_url_tracker method I had reset the content of the email (for the purposes of changing all the links in the rendered view). I don't have any idea why that screws with the Mail object considering the message should already have been rendered but changing my methodology to the following has fixed the duplication of email parts and their subsequent 'reencoding'. I no longer change the content attribute, I only change the html_part:

def prep_for_sending(message)

    if message.html_part
    # Replace the html raw_source
    message.html_part.body.raw_source.replace apply_url_tracker(message.html_part.body.decoded, :source => "Eblast Generator", :medium => :email)
    end

    message

end

Clarification: Even though the call to mail() produces a Mail object with fully rendered HTML/Text parts (i.e., fully rendered views), changing the attribute that is USED by those views (in my case, the 'content' attribute) screws up the final send. Don't modify your model before sending, JUST MODIFY THE MAIL PART DIRECTLY.



来源:https://stackoverflow.com/questions/15044010/how-to-modify-actionmailer-email-html-part-before-sending

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!