class ActionMailbox::Base

end
rescue_from(ApplicationSpecificVerificationError) { bounced! }
class ForwardsMailbox < ApplicationMailbox
Exceptions can be handled at the class level using the familiar ‘Rescuable` approach:
exception is bubbled up, then `failed`.
complete, the status is changed to `delivered`. If a bounce is triggered, then `bounced`. If an unhandled
and the `#process` method is called, the status is changed to `processing`. If processing is allowed to
the email will normally have the `pending` status. Once processing begins, just before callbacks
During the processing of the inbound email, the status will be tracked. Before processing begins,
end
end
end
bounce_with UserRequiredMailer.missing(inbound_email)
unless User.exist?(email_address: mail.from)
def ensure_sender_is_a_user
private
before_processing :ensure_sender_is_a_user
class ForwardsMailbox < ApplicationMailbox
by an Action Mailer method, like so:
an actual bounce email. This is done using the `#bounce_with` method, which takes the mail object returned
can also pair this behavior with the invocation of an Action Mailer class responsible for sending out
which will silently prevent any further processing, but not actually send out any bounce notice. You
If a precondition fails to be met, you can halt the processing using the `#bounced!` method,
using `before_processing` callbacks.
`around_processing`. The primary use case is ensure certain preconditions to processing are fulfilled
callbacks have been run. The callbacks available are: `before_processing`, `after_processing`, and
Application mailboxes need to overwrite the `#process` method, which is invoked by the framework after
end
route :all => :backstop
# Any inbound_email that has not been already matched will be sent to the BackstopMailbox.
route CustomAddress.new => :custom
# Any object responding to #match? is called with the inbound_email record as an argument. Match if true.
route ->(inbound_email) { inbound_email.mail.to.size > 2 } => :multiple_recipients
# Any callable (proc, lambda, etc) object is passed the inbound_email record and is a match if true.
route “help@example.com” => :help
# Any of the recipients of the mail (whether to, cc, bcc) needs to be an exact match for the string.
route /^replies@/i => :replies
# Any of the recipients of the mail (whether to, cc, bcc) are matched against the regexp.
class ApplicationMailbox < ActionMailbox::Base
is specified in the following ways:
`ApplicationMailbox` instead, as that’s where the app-specific routing is configured. This routing
The base class for all application mailboxes. Not intended to be inherited from directly. Inherit from

def self.receive(inbound_email)

def self.receive(inbound_email)
  new(inbound_email).perform_processing
end

def bounce_with(message)

def bounce_with(message)
  inbound_email.bounced!
  message.deliver_later
end

def finished_processing?

def finished_processing?
  inbound_email.delivered? || inbound_email.bounced?
end

def initialize(inbound_email)

def initialize(inbound_email)
  @inbound_email = inbound_email
end

def perform_processing

def perform_processing
  track_status_of_inbound_email do
    run_callbacks :process do
      process
    end
  end
rescue => exception
  # TODO: Include a reference to the inbound_email in the exception raised so error handling becomes easier
  rescue_with_handler(exception) || raise
end

def process

def process
  # Overwrite in subclasses
end

def track_status_of_inbound_email

def track_status_of_inbound_email
  inbound_email.processing!
  yield
  inbound_email.delivered! unless inbound_email.bounced?
rescue
  inbound_email.failed!
  raise
end