Sending email on behalf of users – Part 2 – Patching ActionMailer

Our application was developed using Ruby on Rails, and leveraged RoR’s ActionMailer class to send emails. If you’re not using Rails, you can easily ignore the following.

Unfortunately, when using rails, perform_deliver_smtp of ActionMailer simply use mail.from as the envelope-from when setting the SMTP header. As mentioned earlier, we would like to take into consideration mail.sender if it exists. So I had to patch up the ActionMailer base class to specify the envelope-from as well as the Message sender header:

Once these changes were made, and I restarted our mongrel instance, I was able to set both the message and envelope sender.

Here’s the diff file of the changes to the base class that were needed:

Index: lib/action_mailer/base.rb

===================================================================

— lib/action_mailer/base.rb (revision 6287)

+++ lib/action_mailer/base.rb (working copy)

@@ -36,6 +36,7 @@

# * from – Who the email you are sending is from. Sets the From: header.

# * cc – Takes one or more email addresses. These addresses will receive a carbon copy of your email. Sets the Cc: header.

# * bcc – Takes one or more email address. These addresses will receive a blind carbon copy of your email. Sets the Bcc header.

+ # * sender – Takes just one email address. This address will be used to envelope-from of SMTP and appear in Sender: header.

# * sent_on – The date on which the message was sent. If not set, the header wil be set by the delivery agent.

# * content_type – Specify the content type of the message. Defaults to text/plain.

# * headers – Specify additional headers to be set for the message, e.g. headers 'X-Mail-Count' => 107370.

@@ -315,6 +316,9 @@

# header will be set by the delivery agent.

adv_attr_accessor :sent_on

+ # Specify the Sender address for the message

+ adv_attr_accessor :sender

+

# Specify the subject of the message.

adv_attr_accessor :subject

@@ -513,6 +517,7 @@

m.to, m.from = quote_any_address_if_necessary(charset, recipients, from)

m.bcc = quote_address_if_necessary(bcc, charset) unless bcc.nil?

m.cc = quote_address_if_necessary(cc, charset) unless cc.nil?

+ m.sender = sender unless sender.nil?

m.mime_version = mime_version unless mime_version.nil?

m.date = sent_on.to_time rescue sent_on if sent_on

@@ -548,16 +553,19 @@

def perform_delivery_smtp(mail)

destinations = mail.destinations

+ sender = mail.sender(nil) || mail.from

mail.ready_to_send

Net::SMTP.start(smtp_settings[:address], smtp_settings[:port], smtp_settings[:domain],

smtp_settings[:user_name], smtp_settings[:password], smtp_settings[:authentication]) do |smtp|

smtp.sendmail(mail.encoded, mail.from, destinations)

+ smtp.sendmail(mail.encoded, sender, destinations)

end

end

def perform_delivery_sendmail(mail)

IO.popen(“#{sendmail_settings[:location]} #{sendmail_settings[:arguments]}”,”w+”) do |sm|

+ arguments = sendmail_settings[:arguments].dup

+ arguments += ” -f#{mail.sender(nil)}” if mail.sender(nil)

+ IO.popen(“#{sendmail_settings[:location]} #{arguments}”,”w+”) do |sm|

sm.print(mail.encoded.gsub(/\r/, ”))

sm.flush

end

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s