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
routing :all => :backstop
# Any inbound_email that has not been already matched will be sent to the BackstopMailbox.
routing CustomAddress.new => :custom
# Any object responding to #match? is called with the inbound_email record as an argument. Match if true.
routing ->(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.
routing “help@example.com” => :help
# Any of the recipients of the mail (whether to, cc, bcc) needs to be an exact match for the string.
routing /^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? # :nodoc:
def finished_processing? # :nodoc: inbound_email.delivered? || inbound_email.bounced? end
def initialize(inbound_email)
def initialize(inbound_email) @inbound_email = inbound_email end
def perform_processing # :nodoc:
def perform_processing # :nodoc: 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