使用Ruby on Rails基于间隔发送电子邮件
我希望能够以确定的间隔向不同的收件人发送一串电子邮件。
我为每个联系人分配了一系列名为Campaign的电子邮件,其中Campaign包含Email1,Email2等。每个联系人都有一个Contact.start_date。 每封电子邮件都有email.days,其中存储了联系人发送电子邮件的开始日期以来的天数。
例如:Email1.days = 5,Email2.days = 7,Email3.days = 11。
Contact1.start_date = 4/10/2010; contact2.start_date = 4/08/2010
如果今天是4/15,那么Contact1收到电子邮件1(4 / 15-4 / 10 = 5天)如果今天是4/15,那么Contact2收到电子邮件2(4/15 – 4/8 = 7天)。
使用cron作业每天运行的好动作是什么,然后遵循这些规则使用ActionMailer发送电子邮件?
注意:问题不在于使用ActionMailer。 它是关于做“数学”以及执行。 哪个电子邮件发送给谁? 我猜这与日期的某些版本有关 – 联系[x] .start_date,然后与电子邮件[x] .days进行比较,但我不清楚如何。 谢谢。
我想指导是否使用date.today与time.now。
注意:目的是个人可能需要在一致的基础上安排个人跟进。 它不是必须记住何时跟进哪个电子邮件,而是跟随预先确定的广告系列并发送给该人。
因此,它不是“批量邮件” – 它实际上是对个人通信的后续自动化。
我会使用DelayedJob (假设您不是每天发送大量电子邮件,即每天100个,等等)
class Email < ActiveRecord::Base belongs_to :campaign after_create :schedule_email_dispatch def schedule_email_dispatch send_at(campaign.created_at + self.days.days, :send_email) end def send_email end end
使用rake任务运行worker:
rake jobs:work
每次创建新的电子邮件对象时,都会将延迟的作业项添加到队列中。 在正确的时间间隔,电子邮件将由工作人员发送。
@campaign = Compaign.new(...) @campaign.emails.build(:days => 1) @campaign.emails.build(:days => 2) @campaign.save # now the delay
在上面的示例中,保存广告系列后将创建两个延迟的作业条目。 它们在广告系列创建日期后的1天和2天执行。
此解决方案可确保大约在预期的计划时间内发送电子邮件。 在基于cron作业的解决方案中,调度以cron间隔发生。 预定的调度时间和实际的调度时间之间可能有几个小时的延迟。
如果要使用cron方法,请执行以下操作:
class Email < ActiveRecord::Base def self.dispatch_emails # find the emails due for dispatch Email.all(:conditions => ["created_at <= DATE_SUB(?, INTERVAL days DAY)", Time.now]).each do |email| email.send_email end end end
在该解决方案中,大多数处理由DB完成。
在lib/tasks
目录中添加email.rake
文件:
task :dispatch_emails => :environment do Email.dispatch_emails end
配置cron定期执行rake dispatch_emails
(在你的情况下<24小时)
我会在RAILS_ROOT / lib / tasks / email.rake中创建一个rake任务
namespace :email do desc "send emails to contacts" task :send do Email.all.each do |email| # if start_date is a datetime or timestamp column contacts = Contact.all(:conditions => ["DATE(start_date) = ?", email.days.days.ago.to_date]) # if start_date is a date column contacts = Contact.all(:conditions => { :start_date => email.days.days.ago.to_date }) contacts.each do |contact| #code to send the email end end end end
然后我会使用cronjob每天凌晨3点调用这个rake任务:
0 3 * * * app_user cd RAILS_APP_FOLDER && RAILS_ENV=production rake email:send
我认为创建一个rake任务来发送电子邮件会更容易,更安全(你不必担心身份validation等)。 此外,您不必担心可能需要很长时间运行的请求。 只需创建一个文件RAILS_ROOT / lib / tasks / email.rake
namespace :email do desc "Sends scheduled emails" task :send_scheduled => :enviroment do Email.send_scheduled_emails end end
在RAILS_ROOT / app / email.rb中
class Email < ActiveRecord::Base # ... def self.send_scheduled_emails #send your emails ... end end
然后创建一个cron作业
0 0 * * * user cd /your/rails/app/ && RAILS_ENV=production rake emais:send_scheduled
每天晚上12点发送电子邮件。
我正在使用rufus-scheduler进行预定的电子邮件和Twitter更新。 你应该检查一下。