Mailtime
Make sending mail great again.
Goal
For most projects, you want to know when you mailed a user, and what you mailed to them. Additionally, you don't want to have to do a push every time you want to change something in your mailer.
Installation
Add this line to your application's Gemfile:
gem 'mailtime'
Bundle.
$ bundle
And copy over the initializer and migration:
$ rails g mailtime:install
Migrate it.
$ rake db:migrate
Usage
Using Mailtime is simple. Just add acts_as_mailtime_loggable
to each class you want to associate a Mailtime::MailLog
to.
acts_as_mailtime_loggable options
class User < ActiveRecord::Base
acts_as_mailtime_loggable
will tell Mailtime::MailLog
to find an instance variable of class User
where attribute #email
(email
is default) that matches an ActionMailer#mail
's #to
(again, default) attribute.
Need to customize? Sure.
class User < ActiveRecord::Base
acts_as_mailtime_loggable :email_address, :fields => [:to, :cc, :bcc]
will tell Mailtime::MailLog
to find an instance variable of class User
where attribute email_address
matches an ActionMailer#mail
's #to
, #cc
, or #bcc
attribute.
Configuration
The default initializer that's installed when you run rails g mailtime:install
is self-documented.
How it works
Mailtime hooks into ActionMailer#mail
. It injects a some methods in order to extract metadata, such as the mailer class (like UserMailer
) and the action
(like password_reset
). Once it knows what it's working with, it looks to the database for the corresponding MailTemplate
.
If it finds the MailTemplate
, it renders the template against the mail and merges the result with some of the mail's attributes (like body
).
It then logs the mail and sends it away.
Mailtime aims to be highly flexible and tries not to dictate your setup. For example, you can render a MailTemplate
's contents however you want. Just specify in the initializer what renderer
you want to use. And because Mailtime simply hooks into ActionMailer
, it doesn't care how you're delivering mail (via config.action_mailer.delivery_method
).
Additional Setup
Mailtime
doesn't ship with views. You want views.
MailTemplate
You'll want somewhere to view your logs and manage your templates. Basic scaffolding will do just fine.
def index
@mail_templates = Mailtime::MailTemplate.all
end
For MailTemplate
, you'll want to permit the params klass
, action
, subject
, mail_layout_id
, format
, extension
, and content
Here's an example using SimpleForm:
simple_form_for @mail_template do |f|
f.input :action, :as => :select, :collection => MailTemplate.mail_actions, :onchange => '$("#mail_template_klass").val($("#mail_template_action option:selected").closest("optgroup").attr("label"));'
f.input :klass, :as => :hidden
f.input :subject
f.input :mail_layout
f.input :format, :as => :select, :collection => Mailtime.configuration.valid_formats
f.input :extension, :as => :select, :collection => Mailtime.configuration.valid_extensions
f.input :content, :as => :text
f.submit
end
MailTemplate.mail_actions
is an array of mailer classes and their public instance methods, e.g. ['UserMailer' => ['password_reset_email']]
Note: If subject
is present, it will override the mail's subject.
MailLog
A MailLog
stores the MailTemplate
, action
(from the mailer), klass
(from the mailer), field
(such as to
, cc
, bcc
), loggable
(from acts_as_mailtime_loggable
), headers
(from ActionMailer#mail
), and scope
(the instance variables defined in the action)
You'll probably want somewhere to look at these.
MailLayout
Has a name
, content
, format
, and extension
. format
should be one of Mailtime.configuration.valid_formats
, and extension
should be one of Mailtime.configuration.valid_extensions
Todo
- Tests. Like, way better tests.
- Attachments
- Support MySQL (uses jsonb as datatypes for storing things right now)
Maybe todo
- Dump for production?
- Versioning for templates?
- A hell of a lot better rake import task.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/joshmn/mailtime