Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Rails Mail background sender
module BackgroundSender
def self.serialize_mail(mail)
s = ""
# Mail#encoded strips bcc so we must add it manually
s << "Bcc: #{mail.bcc.join(", ")}\r\n" if mail.bcc.present?
s << mail.encoded
s
end
def self.deserialize_mail(serialized_mail)
Mail.new(serialized_mail)
end
class DeliveryMethod
attr_accessor :settings
def initialize(options = {})
self.settings = options
end
def deliver!(mail)
Rails.logger.info "BackgroundSender#deliver! => #{mail}"
serialized_mail = BackgroundSender.serialize_mail(mail)
SendEmailJob.new(serialized_mail).enqueue
end
end
end
class SendEmailJob
# executed when the job is popped off the queue
def perform(serialized_mail)
mail = BackgroundSender.deserialize_mail(serialized_mail)
logger.info "Sending mail: #{mail}"
deliver_mail(mail)
rescue => e
logger.error "Failed sending mail: #{serialized_mail}, error: #{e.inspect}"
end
private
def deliver_mail(mail)
mail.delivery_method(:smtp, self.class.smtp_settings)
mail.deliver
end
def self.smtp_settings
@smtp_settings ||= Rails.configuration.action_mailer.smtp_settings || {}
end
end
# in an initializer
mailer_config = Rails.application.config.action_mailer
mailer_config.add_delivery_method(:async_smtp, BackgroundSender::DeliveryMethod)
ActionMailer::Base.add_delivery_method(:async_smtp, BackgroundSender::DeliveryMethod)
# in an environments file
Rails.application.configure do
config.action_mailer.delivery_method = :async_smtp
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.