rails/rails
Action Mailbox
Active contributors: rafaelfranca, dhh, georgeclaghorn
Purpose
Action Mailbox routes inbound email — from Postmark, Mailgun, SendGrid, Mandrill, Postfix, exim, qmail, or anything else that can speak HTTP or pipe to a Rake task — into Ruby classes that handle them. Inbound mail is persisted in the action_mailbox_inbound_emails table for durability and retries.
It's the smallest of the 12 components by line count: ~728 lines of lib/ Ruby.
Directory layout
actionmailbox/
├── app/
│ ├── controllers/action_mailbox/
│ │ ├── base_controller.rb
│ │ └── ingresses/ # Per-provider ingress controllers
│ ├── models/action_mailbox/
│ │ ├── inbound_email.rb
│ │ └── inbound_email/
│ │ ├── incineration.rb
│ │ └── message_id.rb
│ └── jobs/action_mailbox/
│ ├── incineration_job.rb
│ └── routing_job.rb
├── config/routes.rb
├── db/migrate/ # action_mailbox_inbound_emails table
├── lib/
│ └── action_mailbox/
│ ├── base.rb # ApplicationMailbox base class
│ ├── callbacks.rb
│ ├── engine.rb
│ ├── mail_ext/ # Mail::Message patches
│ ├── relayer.rb # CLI relay for Postfix etc.
│ ├── router.rb # The routing DSL
│ ├── routing.rb
│ ├── test_case.rb
│ └── test_helper.rb
└── actionmailbox.gemspecKey abstractions
| Constant | File | Purpose |
|---|---|---|
ApplicationMailbox (in user apps) |
extends ActionMailbox::Base |
The user's root mailbox class with routing rules |
ActionMailbox::Base |
actionmailbox/lib/action_mailbox/base.rb |
Subclass for an individual mailbox |
ActionMailbox::Router |
actionmailbox/lib/action_mailbox/router.rb |
Pattern-match incoming mail to a mailbox |
ActionMailbox::InboundEmail |
actionmailbox/app/models/action_mailbox/inbound_email.rb |
AR model wrapping the raw email + metadata |
ActionMailbox::Ingresses::*::InboundEmailsController |
actionmailbox/app/controllers/action_mailbox/ingresses/ |
Per-provider ingress endpoints |
ActionMailbox::Relayer |
actionmailbox/lib/action_mailbox/relayer.rb |
CLI helper for piping mail from Postfix/exim |
Routing DSL
The user's app defines ApplicationMailbox with rules:
class ApplicationMailbox < ActionMailbox::Base
routing /^support@/i => :support
routing ->(inbound) { inbound.mail.to_addrs.any? { |a| a.include?("@inbox.") } } => :user_inbox
routing :all => :catch_all
endThe router (actionmailbox/lib/action_mailbox/router.rb) evaluates rules in order; the first matching rule wins. Conditions can be Regexps, Procs, or :all.
How it works
sequenceDiagram
participant Provider as Mail Provider<br/>(Postmark, Mailgun, ...)
participant Ingress as Ingress Controller
participant DB as action_mailbox_inbound_emails
participant RoutingJob as RoutingJob
participant Mailbox as MyMailbox
Provider->>Ingress: POST inbound email
Ingress->>DB: persist InboundEmail
Ingress->>RoutingJob: enqueue
RoutingJob->>Mailbox: route + process
Mailbox->>Mailbox: business logicThe ingress endpoint validates the request (signature / shared secret) and creates an ActionMailbox::InboundEmail row. A RoutingJob picks it up via Active Job, finds the matching mailbox, and processes it. If processing succeeds, an IncinerationJob deletes the inbound email after a configurable retention period.
Ingress controllers
actionmailbox/app/controllers/action_mailbox/ingresses/:
mailgun/inbound_emails_controller.rbmandrill/inbound_emails_controller.rbpostmark/inbound_emails_controller.rbrelay/inbound_emails_controller.rb— generic, used bybin/rails action_mailbox:ingress:eximetc.sendgrid/inbound_emails_controller.rb
Each verifies its provider-specific authentication (HMAC signature, basic auth password) before persisting.
Engine
actionmailbox/lib/action_mailbox/engine.rb is a Rails::Engine that:
- Mounts the ingress routes under
/rails/action_mailbox/. - Runs the migration to create
action_mailbox_inbound_emails. - Configures the queue name and incineration interval.
Integration points
- Active Record — the
InboundEmailmodel. - Active Job —
RoutingJobandIncinerationJob. - Active Storage — the raw email source is stored as an Active Storage blob.
- Action Mailer — outbound side; reuses the
mailgem'sMail::Message.
Entry points for modification
- Adding an ingress provider: new controller under
actionmailbox/app/controllers/action_mailbox/ingresses/<provider>/. Register a route inactionmailbox/config/routes.rb. Add tests underactionmailbox/test/controllers/ingresses/<provider>/. - Adding routing matchers: edit
ActionMailbox::Router::Routeto support new condition types. - Modifying retention:
config.action_mailbox.incinerate_aftercontrols the schedule. Implementation inapp/jobs/action_mailbox/incineration_job.rb.
Related pages
- packages/action-mailer — the outbound counterpart.
- packages/active-storage — backs the raw email blob storage.
- packages/active-job — runs the routing and incineration jobs.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.