在Rails中的特定时间发送电子邮件

时间:2015-02-26 20:46:03

标签: ruby-on-rails ruby ruby-on-rails-4 actionmailer ruby-on-rails-4.2

我希望在约会开始前一小时触发邮件。我正在使用@appointment实例变量中的at字段。

class AppointmentController < ApplicationController

  def create
    if DateTime.now + 1.hour > @appointment.at
      AppointmentReminder.send_appointment_email(@appointment).deliver_now
    end
  end

end

如果约会是在一小时内创建的,但是如果约会是在将来创建的......那么我们的不良客户就不会得到通知。是否存在Rails可以在合适的时间自动发送电子邮件的机制?我不想使用cronjob或rake任务。

4 个答案:

答案 0 :(得分:1)

我建议您查看Sidekiq或Sucker Punch等后台处理系统,这些系统可配置为“稍后”执行作业。

这样,在创建约会时,您可以安排作业在正确的时间执行。您需要添加检查以确保作业最终运行时仍然合法,等等。

答案 1 :(得分:0)

当您将问题标记为与rails 4.2相关时,然后Active Job正是您需要的。

答案 2 :(得分:0)

您可以使用whenever按计划运行代码块。比如说,只需5分钟,就会查找在下一个小时内开始的约会并发送电子邮件。

为防止多台服务器发送电子邮件,您可以在约会上获得状态,以便跟踪电子邮件是否已发送。

然后,使用postgres,您可以使用此SQL来获取要发送的记录,并使用数据库来决定将哪个服务器发送出特定的电子邮件:

Email.find_by_sql("WITH updated AS (
  UPDATE emails SET status = 'processing' where lower(status) = 'new' RETURNING id 
  ) 
  SELECT * 
  FROM emails 
  WHERE id IN (SELECT id FROM updated) 
  order by id asc

&#34)

答案 3 :(得分:0)

我将分享我的工作方式。效果很好。

首先,每当gem都安装一次。

您应该有您的邮件。这是我的:

class WeeklyDigestMailer < ApplicationMailer
  default :from => "bla@bla.org"
  # Subject can be set in your I18n file at config/locales/en.yml
  # with the following lookup:
  #
  #   en.weekly_digest_mailer.weekly_promos.subject
  #
  helper ApplicationHelper

  def weekly_promos(suscriptor, promos)
      @promos = promos
      mail(:to => "<#{suscriptor.email}>", :subject => "Mercadillo digital semanal")
  end
end

当然,您需要设置视图样式。

然后,创建一个rake任务(在lib / tasks中)。就是这样:

desc 'send digest email'
task send_weekly_email: :environment  do

  @promociones = Promo.where("validez > ?", Time.zone.now).order("created_at DESC")
  if (@promociones.count > 0)
    @suscriptors = Suscriptor.where(email_confirmation: true)
    @suscriptors.each do |suscriptor|
        WeeklyDigestMailer.weekly_promos(suscriptor, @promociones).deliver_now
    end
  end

end

最后,您可以使用gem来配置时间表。我想在整个星期四上午9点发送邮件,所以我只说了:

every :thursday, at: '9:00 am' do # Use any day of the week or :weekend, :weekday
  rake "send_weekly_email"
end

重要的一点:由于您正在使用rake任务,因此请使用delivery_now而不是delivery_later,因为如果任务在所有电子邮件发送之前完成,其余部分将无法发送。

仅此而已。