Reputation: 110940
My app has a UserMailer with several mailer methods the majority of which are sent out via delayed job.
What I'd like to have is a DB Table the creates a record every time a mail is sent out. The app uses sendgrid for sending but I don't trust sendgrid 100% and would like to keep a record on the app for debugging.
Is there a high-level way to globally capture when a mail is sent out and record it in the DB and not be forced to add logic to ever mailer method?
Thanks
Upvotes: 4
Views: 2573
Reputation: 9045
I used an emails
table and an observer:
# frozen_string_literal: true
class CreateEmailObserver
def self.delivered_email(message)
list = message["X-Socializus-List"].to_s
user_id = message["X-Socializus-User-Id"].to_s
user = user_id.present? ? User.find_by!(id: user_id) : nil
Email.create!(
user: user,
list: list,
from: message.from.first,
to: message.to.first,
subject: message.subject,
html_body: message.html_part.body.to_s,
text_body: message.text_part.body.to_s
)
end
end
see https://guides.rubyonrails.org/action_mailer_basics.html#observing-emails
Upvotes: 0
Reputation: 62638
I solve this by using an Email model, with "to" and "guid" string fields.
def self.deliver(which, to, guid, *args)
transaction do
if self.where(:email => to, :guid => guid).first.nil?
if record = Email.create(:email => to, :guid => guid, :template => which) and !record.new_record?
Mailer.send("deliver_#{which}", to, *args)
end
end
end
end
This is for the Rails 2.3 mailer, so the invocation will be a little different for Rails 3, but the core concept holds. Instead of invoking the mailer directly, you'll invoke:
Email.deliver(email_name, receipient, some_guid_you_generate_for_this_email, *args_to_be_sent_to_mailer)
This'll check the database to ensure that you don't re-send the same email to a given address, and will keep a record of all sent emails that you can check in the future.
Upvotes: 1