Last month, Thoughtbot’s Matt Jankowski wrote up a post about How to not accidentally send thousands of ‘beta invites’.
The method outlined is elegant and simple. It also requires modifying the recipients of all of your ActionMailer models.
We wanted something that would allow our QA team to safely test email-sending features all over the site, and without a lot of management overhead.
module ActionMailer class Part def to_mail_with_capture defaults self.body += defaults.captures to_mail_without_capture defaults end alias_method_chain :to_mail, :capture end class Base cattr_writer :captured_email_recipient_address def captured_email_recipient_address @@captured_email_recipient_address end def captures # Add information about captured recipients to the footer of the email body captured_addresses = @captures.map do |method, addresses| if addresses.kind_of?(Array) captured_address = [ "<ul>", addresses.map { |a| "<li>#{a}</li>" }, "</ul>" ].join else captured_address = addresses end [ "<dl>", "<dt>", method, "</dt>", "<dd>", captured_address, "</dd>", "</dl>" ].join end captured_addresses_report = [ "<div><p>Intended recipients</p>", captured_addresses, "</div>" ].join captured_addresses_report end def captured method, list @captures ||= {} @captures[method] = list self.recipients_without_capture = captured_email_recipient_address end def recipients_with_capture= list captured :recipients, list end def cc_with_capture= list captured :cc, list end def bcc_with_capture= list captured :bcc, list end # Defer to the overridden setters if setting the list of recipients # Otherwise, return the unaliased list def recipients_with_capture list = nil list ? self.recipients_with_capture= list : recipients_without_capture end def cc_with_capture list = nil list ? self.cc_with_capture= list : cc_without_capture end def bcc_with_capture list = nil list ? self.bcc_with_capture= list : bcc_without_capture end alias_method_chain :cc=, :capture alias_method_chain :bcc=, :capture alias_method_chain :recipients=, :capture alias_method_chain :cc, :capture alias_method_chain :bcc, :capture alias_method_chain :recipients, :capture end end
Requiring this file will cause all ActionMailer deliveries to be sent to one address, which you can set by using:
ActionMailer::Base.captured_email_recipient_address = "testing@yourdomain.com"
Additionally, a div will be appended to the email body indicating who its intended recipients were, and how the email would have been sent to them; recipient, cc, or bcc. Perfect for QA!
We simply set up the testing address as a mailing list in Google Docs, so we don’t have to manage who gets these emails from within the application, and can instead use Google’s tools.
Remember to set in your deploy recipe whether or not emails should be captured, as you wouldn’t want to accidentally capture all the email being sent out from your live application!
Leave a Comment