AnApprentice
AnApprentice

Reputation: 110940

Rails, how keep a db table log every time an email is sent out

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

Answers (2)

Dorian
Dorian

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

Chris Heald
Chris Heald

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

Related Questions