1

我想在预约到来前一小时触发邮件发送。我正在使用@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

4 回答 4

1

我建议查看诸如 Sidekiq 或 Sucker Punch 之类的后台处理系统,它们可以配置为“稍后”执行作业。

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

于 2015-02-26T21:45:02.730 回答
0

您可以使用无论何时按计划运行代码块。比如说,每隔 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

")

于 2015-02-27T03:03:16.140 回答
0

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

于 2015-02-26T23:06:03.973 回答
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

最后,您可以使用everyge gem 配置您的日程安排。因为我想在整个星期四早上 9 点发送邮件,所以我只是说:

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

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

就这样。

于 2019-01-03T04:06:07.077 回答