ActionMailbox

ActionMailbox is a Rails component that routes incoming emails to controller-like objects called mailboxes, allowing applications to process and act on emails received from external sources.

Table of Contents

What is ActionMailbox in Ruby on Rails?

ActionMailbox handles the receiving side of email in a Rails application, as opposed to ActionMailer, which handles sending. It ingests emails from sources like SMTP, Amazon SES, Mailgun, Mandrill, Postmark, or SendGrid, and routes each incoming email to a mailbox class based on rules the developer defines.

Each mailbox processes an ActionMailbox::InboundEmail record, giving developers access to the parsed email (sender, recipients, subject, body, attachments) so the application can act on it, such as creating a support ticket, replying to a comment thread, or attaching a file to a record.

Why Is ActionMailbox Useful?

Handling inbound email manually involves parsing raw email formats, managing attachments, and integrating with email provider webhooks. ActionMailbox helps by:

  • Providing a standard interface for processing inbound email from multiple providers
  • Parsing raw emails into structured, queryable objects
  • Routing emails to the appropriate handler based on sender, recipient, or subject
  • Storing email attachments using Active Storage
  • Queuing email processing as background jobs to avoid blocking requests
  • Reducing the need for custom email-parsing logic

It is especially useful for applications that need email-based workflows, like support systems, comment-by-email features, or document submission via email.

How Does ActionMailbox Work?

ActionMailbox routes inbound emails through an ingestion point, stores them, and dispatches them to a matching mailbox class.

Key components:

  • Ingress – The integration point for an email provider (SMTP, SES, Mailgun, Mandrill, Postmark, SendGrid) that delivers raw emails to the application
  • InboundEmail – An Active Record model representing a received email, including its raw source and processing status
  • Routing – Rules defined in ApplicationMailbox that determine which mailbox handles a given email
  • Mailbox – A class that defines the process method to handle a matched email
  • Active Storage Integration – Automatically stores email attachments as Active Storage attachments

Examples

Scenario 1: Setting Up Routing

ActionMailbox routes are defined in app/mailboxes/application_mailbox.rb.

class ApplicationMailbox < ActionMailbox::Base 
  routing(/^support@/i  => :support) 
  routing(/^replies@/i  => :replies) 
  routing :all          => :catch_all 
end 

Emails sent to support@yourapp.com will be routed to the SupportMailbox, while anything not matching a defined rule falls through to CatchAllMailbox.

The :all matcher used above is the idiomatic Rails catch-all — it routes any inbound email that didn't match an earlier rule. This is the documented form; a regex like /.*/ => :catch_all is not the standard pattern and isn't necessary.

Scenario 2: Creating a Mailbox

Mailbox (app/mailboxes/support_mailbox.rb)

class SupportMailbox < ApplicationMailbox 
  def process 
    Ticket.create!( 
      subject: mail.subject, 
      body: mail.decoded, 
      requester_email: mail.from.first 
    ) 
  end 
end 

This mailbox creates a support ticket whenever an email is routed to it.

Scenario 3: Accessing Attachments

ActionMailbox automatically stores email attachments using Active Storage, making them accessible through the mail object.

class DocumentSubmissionMailbox < ApplicationMailbox 

  def process 

    submission = Submission.create!( 

      submitted_by: mail.from.first 

    ) 

  

    mail.attachments.each do |attachment| 

      submission.files.attach( 

        io: StringIO.new(attachment.read), # binary-safe read 

        filename: attachment.filename, 

        content_type: attachment.content_type 

      ) 

    end 

  end 

end 

This processes each attachment in an incoming email and attaches it to a record. Using attachment.read rather than attachment.body.decoded ensures binary-safe reading, which matters for non-text attachments like images and PDFs.

Scenario 4: Bouncing or Ignoring Emails

A mailbox can choose to stop processing an email instead of handling it normally. The bounced! method silently halts processing without sending any notification, while bounce_with sends an actual bounce email to the sender (and therefore requires a valid sender address).

class SupportMailbox < ApplicationMailbox 
  def process 
    if mail.from.first.blank? 
      bounced! # halts processing silently, no email sent 
      return 
    end 
 
    Ticket.create!(subject: mail.subject, body: mail.decoded) 
  end 
end 

If you want to notify the sender with an actual bounce email (e.g. "We couldn't process your message"), use bounce_with instead, paired with an Action Mailer:

bounce_with_ SupportMailer.unprocessable(_inbound_email) 

Where to Use ActionMailbox?

  • Support ticket systems that accept email submissions
  • Reply-by-email features on comments or notifications
  • Document or file submission via email
  • Inbound newsletters or subscription management
  • Any workflow where users interact with the application through email

In Summary

ActionMailbox handles incoming email in Rails applications by parsing, routing, and processing messages through dedicated mailbox classes. It removes the need for custom email-parsing logic and integrates cleanly with Active Storage and background job processing.