Rails Email Protips
CSS inlining
For the best HTML e-mail delivery results, CSS should be inline. This is a huge pain and a simple newsletter becomes un-managable very quickly. Inline email CSS automatically with premailer-rails or roadie-rails
UTM tracking
Append UTM params with email identifier to all the links in the emails:
# Gemfile
gem 'addressable'
# app/mailer_interceptors/utm_mailer_interceptor.rb
class UtmMailerInterceptor
URL_RE = /\b((https?):\/\/\w+\.[-A-Z0-9+&@#\/%?=~_|$!:,.;]*)/i
URL_IN_HREF_RE=/href=["']#{URL_RE}["']/i
MIME_TYPES = %w(text/plain text/html application/xhtml+xml)
class << self
def delivering_email(message)
[message, message.all_parts].flatten.compact.each do |part|
if MIME_TYPES.include?(part.mime_type)
part.body = part.body.decoded.gsub(URL_IN_HREF_RE) do |href, a|
url = $1
if url !~ /\.(jpg|png|gif)(\?|$)/
%Q(href="#{append_utm message, url}")
else
href
end
end
end
end
end
private
def append_utm(message, url)
params = {
utm_source: 'App Emails',
utm_medium: 'email',
utm_campaign: message.header['X-APP-EMAIL-ID'].value,
utm_content: message.subject
}
append_params url, params
end
def append_params(url, params)
uri = Addressable::URI.parse(url)
uri.query_values = (uri.query_values || {}).merge(params)
uri.to_s
end
end
end
# config/initializers/configure_mailers.rb
ActionMailer::Base.register_interceptor UtmMailerInterceptor
ActionMailer::Base.class_eval do
def mail(headers = {}, &block)
# Set identifier for the email being rendered
headers['X-APP-EMAIL-ID'] ||= "#{self.class.name.underscore}-#{caller[0][/`.*'/][1..-2]}"
super(headers, &block)
end
end
[rep-screenshot]: https://raw.github.com/glebm/rails_email_preview/master/doc/img/rep-show.png "Rails Email Preview Screenshot"
Email Preview
For rapid development you might want to be able to preview emails and test deliveries easily, using a gem such as REP.
![screenshot][rep-screenshot]
Written by Gleb Mazovetskiy
Related protips
3 Responses
Cheers Gleb, some nice tips!
Another invaluable tool I've found recently is MailCatcher - A super simple SMTP server which catches emails with preview functionality. It's great for testing email deliveries and eliminates the risk of mails being sent to live customer addresses.
Thanks Steve! I found MailCatcher useful but having to trigger the email delivery inconvenient. REP instead provides a UI for previewing all the emails that the application can send:
Saves the time to figure out where and how the email is sent whenever something needs changing.
You cannot call super when using classeval because you are overwriting it. A working solution is to use aliasmethod and to replace super.
...
aliasmethod :oldmail, :mail
...
old_mail(headers, &block)