28
I just had two tough days…
One of our clients needed a monthly newsletter.
After some Google searching the only solutions for email queueing I could find were:
- ar_mailer gem (http://blog.segment7.net/articles/2006/08/15/ar_mailer)
- backgroundrb (http://www.infoq.com/articles/BackgrounDRb)
- ActiveMessaging (http://code.google.com/p/activemessaging/)
- mail queue (http://code.google.com/p/mail-queue/)
I started testing and reading reviews but none seemed to do the job.
Then I remembered that I’ve already developed a mail queue system for one of my past projects (back when using ASP.NET 2.0). There, the solution was to store in a table the sender, recipient, body and the subject. On RoR mail queue does this but I was still getting a strange error that i couldn`t handle.
Finally… I said “why store the e-mail in a table instead of the arguments and build the mail from those arguments before sending it”. So here are the steps to do it.
Create a model named “QueuedMail“:
#in the migration
create_table :queued_mails do |t|
t.column :mailer , :string
t.column :mailer_method, :string
t.column :args, :text
t.column :priority, :integer, :default=> 0
end
In QueuedMail.rb:
class QueuedMail < ActiveRecord::Base
serialize :args
def self.send
find(:all, :order=> "priority desc, id desc", :limit=>10).each do |mail|
mailer_class = mail.mailer.constantize
mailer_method = ("deliver_" + mail.mailer_method).to_sym
mailer_class.send(mailer_method, mail.arguments)
mail.destroy
end
true
end
def self.add(mailer, method, args, priority)
create(:mailer=>mailer.to_s, :mailer_method=>method.to_s, :args => args, :priority=> priority)
end
end
Now, if you want to send a mail instead of sending with ActionMailer you call QueuedMail.add and it saves the params into the database.
Example:
You have the ActionMailer class named “Mail” and the method “account_created” that recives the params “to”.
Instead of Mail.deliver_account_created(to) you need to code QueuedMail.add(Mail,”account_created”, { :to => “mail@mail.com” }, 0 }
If you have an important email that needs to be sent before others you just set a higher priority.
How to send them?
By using a cron job!
script/runner "DelayedMail.send" -e production

RECENT COMMENTS