Created
August 28, 2011 04:14
Customizing ActionMailer delivery methods
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Resque job to do the true outbound sending | |
class DeliverEmailJob | |
include ProjectName::Job::Logging | |
@queue = :mail_queue | |
def self.perform(args) | |
message = QueuedEmail.get!(args["message_id"]) | |
logger.info("Delivering (%s) to %s" % [message.subject, message.formatted_recipient]) | |
# This is the important bit, QueueDeliveryMailer rebuilds the email, but overrides the delivery method (see file) | |
# Again, using delayed_job, this could be simplified as you could just receive the original Mail::Message | |
QueueDeliveryMailer.original_email(message).deliver | |
logger.info("Mail delivered to %s" % [message.formatted_recipient]) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# in config/initializers/mailer.rb, add a custom delivery_method to ActionMailer | |
ActionMailer::Base.add_delivery_method :queued, ProjectName::QueuedDeliveryMethod |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# in config/environments/production.rb (or other environment) | |
config.action_mailer.delivery_method = :queued # make the default delivery_method your queue | |
config.mail_queue_outbound_delivery_method = :smtp # define new config option that specifies how to really deliver mail (used later) | |
config.action_mailer.smtp_settings = { # set the settings for whatever outbound delivery method you're going to use | |
:address => "smtp.sendgrid.net", | |
:port => 25, | |
:domain => "site.com", | |
:user_name => "sendgrid@site.com", | |
:password => "smtp-password" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class QueueDeliveryMailer < ActionMailer::Base | |
# override the delivery method with the outbound delivery method you config'd earlier | |
self.delivery_method = Rails.application.config.mail_queue_outbound_delivery_method | |
layout nil | |
def original_email(email) | |
# This is just creating the same email from the DB record that was saved for queueing | |
mail(:from => email.formatted_sender, | |
:to => email.formatted_recipient, | |
:reply_to => email.formatted_reply_to, | |
:subject => email.subject) do |format| | |
format.text { render :text => email.body } | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ProjectName | |
class QueuedDeliveryMethod | |
def deliver!(mail) | |
# we're actually tracking the mail in the DB, but you can store it anywhere ready for passing to Resque | |
# if you don't care about analyzing your sent email data, and you're using delayed_job, this would be simpler | |
message = QueuedEmail.create( | |
:subject => mail.subject, | |
:body => mail.body, | |
:recipient_address => mail.to.first, | |
:recipient_name => mail[:to].display_names.first, | |
:sender_address => mail.from.first, | |
:sender_name => mail[:from].display_names.first, | |
:reply_to_address => mail.reply_to ? mail.reply_to.first : nil, | |
:reply_to_name => mail.reply_to ? mail[:reply_to].display_names.first : nil | |
) | |
# once it's written somewhere internal to the app, tell Resque to process the sending in the background | |
Resque.enqueue(DeliverEmailJob, :message_id => message.id) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment