Having production data in a staging environment makes it easier to catch bugs.
But when testing a feature, there's always that tiny moment of hesitation when you hit the "Send Email" button.
Will this actually go out to a real user?
I'm sure most of you have been there.
For local development, we usually install the excellent letter_opener gem. But what about staging?
Safely sending emails in staging
Rails 7.1+ introduced a new before_deliver
callback for Action Mailers, which
is perfect for overriding recipients before emails are actually sent.
Here's how to use it:
class ApplicationMailer < ActionMailer::Base
before_deliver :override_recipients
private
def override_recipients
return unless Rails.env.staging?
sandbox_emails = ENV.fetch("SANDBOX_EMAILS")
message.to = sandbox_emails
message.cc = sandbox_emails
message.bcc = sandbox_emails
end
end
Just make sure you have the SANDBOX_EMAILS
environment variable set. Or pull
it from Rails credentials if you prefer.
If you're on an older version of Rails (< 7.1), you can use interceptor
to
accomplish the same thing:
# app/mailers/sandbox_email_interceptor.rb
class SandboxEmailInterceptor
def self.delivering_email(message)
sandbox_emails = ENV.fetch("SANDBOX_EMAILS")
message.to = sandbox_emails
message.cc = sandbox_emails
message.bcc = sandbox_emails
end
end
The interceptor needs to be registered using the interceptors
option of
action_mailer
.
# config/initializers/mail_interceptors.rb
Rails.application.configure do
if Rails.env.staging?
config.action_mailer.interceptors = %w[SandboxEmailInterceptor]
end
end
That's it, no more heart attacks before pressing "Send Email".