No release in over 3 years
Rails engine that stores outbound mail like Action Mailbox stores inbound mail.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 7.0, < 8.2
>= 7.0, < 8.2
>= 7.0, < 8.2
>= 2.8.0
>= 7.0, < 8.2
 Project Readme

Outbound Mailbox

Rails engine that stores outbound email the same way Action Mailbox stores inbound email: Active Record metadata, raw RFC822 source in Active Storage, a Mail delivery method, and an HTML conductor at /rails/conductor/outbound_mailbox/outbound_emails when enabled — by default if Action Mailer uses delivery_method :outbound_mailbox, or any time via config.outbound_mailbox.mount_conductor.

There is no runtime dependency on Action Mailer in the library; the delivery class implements Mail’s delivery contract so any stack that ends in Mail::Message#deliver! can use it. Typical Rails hosts configure Action Mailer to use this method in development.

Installation

Add to your Gemfile:

gem "outbound_mailbox"

Then:

bundle install
bin/rails generate outbound_mailbox:install
bin/rails db:migrate

Optional: use a dedicated Active Storage service for captured mail (mirrors Action Mailbox’s config.action_mailbox.storage_service):

# config/application.rb
config.outbound_mailbox.storage_service = :local # or any configured service name

To browse captured mail via the conductor without using Action Mailer's :outbound_mailbox delivery method (for example you call OutboundMailbox::OutboundEmail.create_from_mail! yourself or use a custom delivery path), enable routes explicitly:

# config/application.rb
config.outbound_mailbox.mount_conductor = true

Set to false to hide the conductor even when delivery_method is :outbound_mailbox. You can also assign a proc: config.outbound_mailbox.mount_conductor = ->(app) { ... } (must return a boolean-coercible value). The default is nil, meaning mount when config.action_mailer.delivery_method is :outbound_mailbox.

Capturing mail in development

# config/environments/development.rb
config.action_mailer.delivery_method = :outbound_mailbox

This replaces real SMTP delivery in that environment (similar to :test or Letter Opener). Plain Mail is also supported if you assign the same delivery class.

Conductor

By default, when config.action_mailer.delivery_method is :outbound_mailbox, the engine registers conductor routes under:

/rails/conductor/outbound_mailbox/outbound_emails

You can override that with config.outbound_mailbox.mount_conductor; see Installation optional settings above.

List and show stored messages, or Incinerate to delete a record and purge its blob. When routes are not registered, those URLs are not routed (404). Route registration follows config/routes.rb (startup and reload in development).

Testing this gem

Tests boot a single-file Rails app in test/dummy/app.rb. Migrations live under test/dummy/db/migrate.

bundle install
bundle exec rake test
bundle exec rubocop

Continuous integration uses the latest stable MRI Ruby ruby/setup-ruby, ruby-version: "ruby" and exercises Rails 8.1 (default Gemfile), Rails 8.0, Rails 7.1, and Rails 7.0 via gemfiles/rails_8_1.gemfile, gemfiles/rails_8_0.gemfile, gemfiles/rails_7_1.gemfile, and gemfiles/rails_7_0.gemfile. To match a matrix entry locally:

BUNDLE_GEMFILE=gemfiles/rails_7_0.gemfile bundle install
BUNDLE_GEMFILE=gemfiles/rails_7_0.gemfile bundle exec rake test

The gem’s Gemfile includes actionmailer so config.action_mailer exists in that app; the gemspec does not list action_mailer or actionmailbox as runtime dependencies. Runtime Rails components are constrained to >= 7.0, < 8.2 (actionpack, activestorage, activerecord, railties). The gem requires Ruby 3.1+ (required_ruby_version).

Releasing

Releases are done automatically by GitHub Actions when a new tag is pushed to the repository.

To release a new version, create a pull request updating the "Unreleased" section of CHANGELOG.md file to reflect the upcoming version and expected release date, and to update the version number in lib/outbound_mailbox/version.rb. Once the pull request is merged, create a new tag in the format vX.Y.Z, which will trigger GitHub Actions to publish the new version to RubyGems.

License

MIT — see MIT-LICENSE.