Intercept Emails in Rails

On any project where emails get sent automatically testing can become a problem. Ideally you want to be able to see the emails that get generated, but avoid sending test emails to real services or users. On the other hand, you still need to send emails to the real services and users in your production environment.

One way to accomplish this in Rails is to use an interceptor.

First off, create the interceptor class (this is a plain Ruby object).

class PreProductionMailInterceptor
  def self.delivering_email(message)
    message.subject = "[#{message.to}] #{message.subject}"
    message.to = ENV['NOTIFICATIONS_EMAIL']
  end
end

I want all emails to be sent to an address which I specify through an environment variable. I like using an environment variable for this since it allows each developer to specify their own address for email interception. We use Foreman as the development server which allows us to easily specify environment variables in Rails.

To indicate who the email was originally sent to I prepend the original to field in the subject line. A handy tip here is to use a plus alias (so something like yourmail+projectname@provider.com) as the specified interception address. You can then setup an automatic filter for the alias.

Right, we’ve created the interceptor class, but we’re not using it anywhere. Now we simply configure the interceptor in an initializer (for example, config/initializers/mail.rb):

unless Rails.env.test? || Rails.env.production?
  ActionMailer::Base.register_interceptor(PreProductionMailInterceptor)
end

Now all pre-production emails will be routed to the email specified in your environment variable. Happy coding.