Redirect Emails in Staging Environments
In a staging environment, or any environment other than production, it is imperative that emails are never sent to end users.
Rails has a built-in feature that allows you to intercept emails. Couple this with an environment variable containing a list of comma-separated emails, and you have an simple, environment-based switch that allows your team to verify the staging server is in fact triggering email deliveries, and also ensures that your customers are not receiving email spam outside of production.
Set the following variables in your staging server’s environment.
HOSTNAME="yourapp.com"
REDIRECT_ALL_OUTGOING_EMAIL_TO="rahul@eg.com, rich@eg.com, riki@eg.com, jackie@eg.com"
Configure your Rails application to use the appropriate hostname when creating links within emails, as well as to redirect emails to a CSV list of addresses, when defined.
# config/initializers/action_mailer.rb
module YourApp
class Application < Rails::Application
# use the appropriate url based on the environment
config.action_mailer.default_url_options = { host: ENV["HOSTNAME"] }
# store emails in the ActionMailer::Base.deliveries array when testing
if Rails.env.test?
config.action_mailer.delivery_method = :test
end
# set REDIRECT_ALL_OUTGOING_EMAIL_TO to one or more comma separated emails
if !Rails.env.test? && ENV["REDIRECT_ALL_OUTGOING_EMAIL_TO"].present?
ActionMailer::Base.register_interceptor(RedirectAllOutgoingEmail)
end
end
end
Here’s where the actual overriding of emails occurs. In this case, we’re redirecting all outgoing email deliveries to our CSV list of emails, and updating the email subject to include all the relevant information about the environment that is delivering the email.
# lib/redirect_all_outgoing_email.rb
class RedirectAllOutgoingEmail
def self.delivering_email(message)
original_message_to = message.to
message.to = ENV["REDIRECT_ALL_OUTGOING_EMAIL_TO"]
original_message_subject = message.subject
message.subject = "HOST: #{ENV['HOSTNAME']} "
message.subject += "TO: #{original_message_to} "
message.subject += "SUBJECT: #{original_message_subject}"
end
end
You may need to add this line to your config/application.rb
file to load the
RedirectAllOutgoingEmail
class.
# https://stackoverflow.com/a/40206732
config.autoload_paths << "#{Rails.root}/lib"
Depending on the email output of your application, you may want to
create an inbox filter, remove your email address from the
REDIRECT_ALL_OUTGOING_EMAIL_TO
variable, or turn off email deliveries,
altogether.
Now, you can rest assured that emails are only being delivered to end-users in the production environment.