extending action_mailer

Recently a client wanted to use a web-based email system called JangoMail. JangoMail allows you to send emails, create distribution lists called groups, handle situations like bounces, etc. It also provides some reporting features for all your email statistics.

JangoMail has an API that supports SOAP and also simple HTTP POST/GET requests. I decided to go with the POST version.

Now I didn’t want to change all our email code from

Mailer.deliver_some_email @user

to

email = Mailer.createsomeemail @user JangoMail.sendmassemail email

Instead I wanted to extend ActionMailer to use JangoMail.

ActionMailer::Base#delivery_method is used to determine how to send an email. Currently it supports smtp, sendmail and test. The delivery method is set in your environment specific files:

config/environments/test.rb

config.action_mailer.delivery_method = :test

Now looking through ActionMailer::Base you find #deliver!. Here’s the portion of it we care about.

begin
  __send__("perform_delivery_#{delivery_method}", mail) if perform_deliveries
rescue Exception => e  # Net::SMTP errors or sendmail pipe errors
  raise e if raise_delivery_errors
end

It’s going to send the mail object to its method named after the delivery method. So in order to extend it we’re going to need to provide our own #peform_delivery_jango_mail method.

What I want is

config/environments/development.rb

config.action_mailer.delivery_method = :jango_mail

config/initializers/jangomail.rb_

require 'lib/jango_mail'

ActionMailer::Base.send :include, JangoMail
ActionMailer::Base.jango_mail_settings = {
  :username => "username",
  :password => "password",
  :url      => "http://api.jangomail.com/api.asmx"
}

lib/jangomail.rb_

module JangoMail

  def self.included(clazz)
    clazz.class_eval do
      cattr_accessor :jango_mail_settings
    end
  end

  def perform_delivery_jango_mail(mail)
    post_data = {
      "Username"      => jango_mail_settings[:username],
      "Password"      => jango_mail_settings[:password],
      "FromEmail"     => mail.from,
      "FromName"      => "",
      "ToGroups"      => "",
      "ToGroupFilter" => "",
      "ToOther"       => mail.to,
      "ToWebDatabase" => "",
      "Subject"       => mail.subject,
      "MessagePlain"  => mail.body,
      "MessageHTML"   => "",
      "Options"       => ""
    }
    uri = URI.parse "#{jango_mail_settings[:url]}/SendMassEmail"
    Net::HTTP.post_form uri, post_data
  end

end

SendMassEmail is the JangoMail API call for sending an email, all the parameters are required even if they’re not being used.

Jared Carroll
upcase

Sharpen your programming skills by completing coding exercises that are reviewed by other developers at Upcase today.