使用Ruby on Rails基于间隔发送电子邮件

时间:2010-04-16 19:33:51

标签: ruby-on-rails email

我希望能够以确定的时间间隔向不同的收件人发送一串电子邮件。

我为每个联系人分配了一系列名为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。

注意:目的是个人可能需要在一致的基础上安排个人随访。而不是必须记住何时跟进哪个电子邮件与谁,它只会遵循预先确定的活动并发送给该人。

所以这不是“大宗邮件” - 它真正实现了个人通信跟进的自动化。

5 个答案:

答案 0 :(得分:14)

我会使用DelayedJob进行此操作(假设您每天不会发送大量电子邮件,即每天发送数千封电子邮件等)。

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完成。

email.rake目录中添加lib/tasks文件:

task :dispatch_emails => :environment do
  Email.dispatch_emails
end

将cron配置为定期执行rake dispatch_emails(在您的情况下<24小时)

答案 1 :(得分:6)

我会在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

然后我会每天凌晨3点使用cronjob来调用这个rake任务:

0 3 * * * app_user cd RAILS_APP_FOLDER && RAILS_ENV=production rake email:send

答案 2 :(得分:1)

我认为创建一个rake任务来发送电子邮件会更容易,更安全(您不必担心身份验证等)。此外,您不必担心可能需要很长时间运行的请求。只需创建一个文件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点发送电子邮件。

答案 3 :(得分:1)

我正在使用rufus-scheduler进行预定的电子邮件和Twitter更新。你应该检查一下。

答案 4 :(得分:0)