“Information is the oil of the 21st century, and analytics is the combustion engine.”
Since Amazon SES and some other email service providers don’t
store show you the email content and history, you are left hanging if you want to some historical email performance and analytics. Keep track of outbound emails for Logging, Analytics and Audit purposes by following this simple setup.
First and foremost, setup paperclip gem, it is an awesome gem for attachment management. https://github.com/thoughtbot/paperclip
To begin, first, we will create a model for our emails. We will record the email-id and raw email content with timestamps.
rails g model OutboundEmail email:string content:attachment
This should create a migration that looks something like this:
class CreateOutboundEmails < ActiveRecord::Migration[5.0] def change create_table :outbound_emails do |t| t.string :email, index: true t.attachment :content t.timestamps end end end
Add an index on email column. Then we need to declare that our model has an attachment by adding
class OutboundEmail < ApplicationRecord has_attached_file :content, storage: :s3, s3_permissions: :private, path: "outbound/:year/:month/:day/:email/:id.email" ... end
This will upload the file in your S3 bucket with object path something like this, “email@example.com/1.email”
Note: As per AWS, ‘@’ in object key can create some issues while accessing S3 in certain browsers.
Read: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html. I didn’t face any issues in any of the Standard browsers.
The symbols :year, :month, :date have to be interpolated by paperclip
# config/initializers/paperclip.rb Paperclip.interpolates :year do |attachment, style| attachment.instance.created_at.year end Paperclip.interpolates :month do |attachment, style| attachment.instance.created_at.month end Paperclip.interpolates :day do |attachment, style| attachment.instance.created_at.day end
Now add an Mail Observer and create records for all outbound emails.
class MailObserver def self.delivered_email(message) file = Tempfile.new file.write(message.content) OutboundEmail.create(email: message.to, content: file) end end
Register this observer in after_initialize block
# config/environments/production.rb Rails.application.configure do ... config.after_initialize do ActionMailer::Base.register_observer(MailObserver) end ... end
All your emails will now be stored in encoded format on S3. 🎉 😎
The email content can be easily decoded back to a Mail object using mail gem.
For further reading on Mail Observers and Interceptors read this great article by Leigh Halliday on https://www.leighhalliday.com/mail-interceptors-and-observers