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.create_some_email @user
JangoMail.send_mass_email email
Instead I wanted to extend ActionMailer
to use JangoMail
.
The 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:
In 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
In: config/environments/development.rb
:
config.action_mailer.delivery_method = :jango_mail
In: config/initializers/jango_mail.rb
:
require 'lib/jango_mail'
ActionMailer::Base.send :include, JangoMail
ActionMailer::Base.jango_mail_settings = {
:username => "username",
:password => "password",
:url => "https://api.jangomail.com/api.asmx"
}
In: lib/jango_mail.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.