如何使用deliver_later(sidekiq)检索邮件的message_id



我想要使用deliver_later(sidekiq)的邮件的SMTP message_id。

我能够在deliver_now的返回对象中获取id,但不能deliver_later。

Message_id 在 my_action_mailer 中 mail() 函数的返回值中也缺失

  • 当我使用-

sent_mail = some_mail().deliver_later

响应是一个 sidekiq 作业对象,如下所示-

#<ActionMailer::DeliveryJob:0x007fefa1454780 @arguments=["xxxxxxx", "xxxxxxx", "deliver_now", xxxxxxx], @job_id="69b13253-55f9-4db9-a10a-0e8e4b998584", @queue_name="mailers", @priority=nil, @executions=0, @provider_job_id="6f75131d0c485534322cd728">
  • 当我使用 - 发送邮件时 -

sent_mail = some_mail().deliver_now

响应是一个对象对象,如下所示-

<Mail::Message:xx, Multipart: true, Headers: <Date: xx>, <From: "xx" <xx@xx.com>>, <Reply-To: "xx" <xx@xx.com>>, <To: ["xx@xx.com"]>, <Message-ID: <5a7863381167a_ba183fdfebc3f928907cb@xx-xx-xx.xx.mail>>, <Subject: xx>, <Mime-Version: 1.0>, <Content-Type: multipart/mixed; boundary="--==_mimepart_xx"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>

如果你仔细看看上面的输出,返回类是Mail::Message它包含">消息 ID",这就是我需要的。

  • 另外,当我们在我的邮件类中调用mail()函数时,它也返回Mail::message对象,但这个obj dosent不包含从SMTP服务器返回的消息ID。

有什么方法可以使用deliver_later获取消息ID

这是处理这种情况的标准方法:

覆盖ActionMailer::DeliveryJob,如下所示:

class EmailDeliveryJob < ActionMailer::DeliveryJob
def perform(mailer, mail_method, delivery_method, *args)
response = mailer.constantize.public_send(mail_method, *args).send(delivery_method)
# Use response.message_id as you want
end
end

在您的邮件中,

class UserMailer < ApplicationMailer
self.delivery_job = EmailDeliveryJob
def welcome_email(user)
mail to: user.email, subject: "Welcome!"
end
end

我遇到了同样的问题,但我决定改用Mailgun HTTPS API,但在Sidekiq Job中。

所以我称这份工作为MailgunJob.perform_later(stuff_to_send)

在工作中

response = RestClient.post "https://mailgun_path", data
result = JSON.parse(response.body)
message_id = result['id']

你能不能用一个作业,在作业里面deliver_now

如果你找到了更好的解决方案,你能在这里写吗?

一种方法是使用 ActionMailer 观察器。

首先,使用标头或#metadata属性将记录 ID 添加到邮件中:

class YourMailer < ApplicationMailer
def your_email(record)
self.message['X-Your-Record-Id'] = record.id
# or metadata['record_id'] = record.id
...
end
end

创建观察器:

# app/models/custom_observer.rb
class CustomObserver
def self.delivered_email(m)
return unless m.delivered?
# Access m.message_id or any header you want e.g. m['X-Your-Record-Id']
Record.find(m['X-Your-Record-Id'].to_s).update_column(:message_id, m.message_id)
end
end

注册观察器:

# config/initializers/action_mailer.rb
ActionMailer::Base.register_observer(CustomObserver)

你很好去。与创建自定义ActionMailer::MailDeliveryJob(仅适用于#deliver_later)相比,这适用于#deliver#deliver_later

最新更新