Class: ActionMailbox::Base
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
|
|
Instance Chain:
|
|
Inherits: | Object |
Defined in: | actionmailbox/lib/action_mailbox/base.rb |
Overview
The base class for all application mailboxes. Not intended to be inherited from directly. Inherit from ApplicationMailbox
instead, as that’s where the app-specific routing is configured. This routing is specified in the following ways:
class ApplicationMailbox < ActionMailbox::Base
# Any of the recipients of the mail (whether to, cc, bcc) are matched against the regexp.
routing /^replies@/i => :replies
# Any of the recipients of the mail (whether to, cc, bcc) needs to be an exact match for the string.
routing "help@example.com" => :help
# Any callable (proc, lambda, etc) object is passed the inbound_email record and is a match if true.
routing ->(inbound_email) { inbound_email.mail.to.size > 2 } => :multiple_recipients
# Any object responding to #match? is called with the inbound_email record as an argument. Match if true.
routing CustomAddress.new => :custom
# Any inbound_email that has not been already matched will be sent to the BackstopMailbox.
routing :all => :backstop
end
Application mailboxes need to override the #process method, which is invoked by the framework after callbacks have been run. The callbacks available are: before_processing
, after_processing
, and around_processing
. The primary use case is to ensure that certain preconditions to processing are fulfilled using before_processing
callbacks.
If a precondition fails to be met, you can halt the processing using the #bounced! method, which will silently prevent any further processing, but not actually send out any bounce notice. You can also pair this behavior with the invocation of an Action Mailer class responsible for sending out an actual bounce email. This is done using the #bounce_with method, which takes the mail object returned by an Action Mailer method, like so:
class ForwardsMailbox < ApplicationMailbox
before_processing :ensure_sender_is_a_user
private
def ensure_sender_is_a_user
unless User.exist?(email_address: mail.from)
bounce_with UserRequiredMailer.missing(inbound_email)
end
end
end
During the processing of the inbound email, the status will be tracked. Before processing begins, the email will normally have the pending
status. Once processing begins, just before callbacks and the #process method is called, the status is changed to processing
. If processing is allowed to complete, the status is changed to delivered
. If a bounce is triggered, then bounced
. If an unhandled exception is bubbled up, then failed
.
Exceptions can be handled at the class level using the familiar ::ActiveSupport::Rescuable
approach:
class ForwardsMailbox < ApplicationMailbox
rescue_from(ApplicationSpecificVerificationError) { bounced! }
end
Constant Summary
Routing
- Attributes & Methods
::ActiveSupport::Rescuable
- Attributes & Methods
Class Method Summary
- .new(inbound_email) ⇒ Base constructor
- .receive(inbound_email)
::ActiveSupport::DescendantsTracker
- self
Instance Attribute Summary
- #inbound_email readonly
- #logger readonly
- #mail readonly
- #finished_processing? ⇒ Boolean readonly Internal use only
Callbacks
- Included
Instance Method Summary
-
#bounce_now_with(message)
Immediately sends the given
message
and changes the inbound email’s status to:bounced
. -
#bounce_with(message)
Enqueues the given
message
for delivery and changes the inbound email’s status to:bounced
. - #bounced!
- #delivered!
- #process
- #instrumentation_payload private
- #track_status_of_inbound_email private
- #perform_processing Internal use only
::ActiveSupport::Callbacks
- Included
#run_callbacks | Runs the callbacks for the given event. |
#halted_callback_hook | A hook invoked every time a before callback is halted. |
::ActiveSupport::Rescuable
- Included
#rescue_with_handler | Delegates to the class method, but uses the instance as the subject for rescue_from handlers (method calls, |
#handler_for_rescue | Internal handler lookup. |
Constructor Details
.new(inbound_email) ⇒ Base
# File 'actionmailbox/lib/action_mailbox/base.rb', line 79
def initialize(inbound_email) @inbound_email = inbound_email end
Class Attribute Details
.rescue_handlers (rw)
[ GitHub ]# File 'activesupport/lib/active_support/rescuable.rb', line 15
class_attribute :rescue_handlers, default: []
.rescue_handlers? ⇒ Boolean
(rw)
[ GitHub ]
# File 'activesupport/lib/active_support/rescuable.rb', line 15
class_attribute :rescue_handlers, default: []
.router (rw) Also known as: #router
[ GitHub ]# File 'actionmailbox/lib/action_mailbox/routing.rb', line 9
cattr_accessor :router, default: ActionMailbox::Router.new
Class Method Details
.receive(inbound_email)
[ GitHub ]# File 'actionmailbox/lib/action_mailbox/base.rb', line 75
def self.receive(inbound_email) new(inbound_email).perform_processing end
Instance Attribute Details
#finished_processing? ⇒ Boolean
(readonly)
# File 'actionmailbox/lib/action_mailbox/base.rb', line 100
def finished_processing? # :nodoc: inbound_email.delivered? || inbound_email.bounced? end
#inbound_email (readonly)
[ GitHub ]# File 'actionmailbox/lib/action_mailbox/base.rb', line 70
attr_reader :inbound_email
#logger (readonly)
[ GitHub ]# File 'actionmailbox/lib/action_mailbox/base.rb', line 73
delegate :logger, to: ActionMailbox
#mail (readonly)
[ GitHub ]# File 'actionmailbox/lib/action_mailbox/base.rb', line 71
delegate :mail, :delivered!, :bounced!, to: :inbound_email
#rescue_handlers (rw)
[ GitHub ]# File 'activesupport/lib/active_support/rescuable.rb', line 15
class_attribute :rescue_handlers, default: []
#rescue_handlers? ⇒ Boolean
(rw)
[ GitHub ]
# File 'activesupport/lib/active_support/rescuable.rb', line 15
class_attribute :rescue_handlers, default: []
#router (rw)
[ GitHub ]# File 'actionmailbox/lib/action_mailbox/routing.rb', line 9
cattr_accessor :router, default: ActionMailbox::Router.new
Instance Method Details
#bounce_now_with(message)
Immediately sends the given message
and changes the inbound email’s status to :bounced
.
# File 'actionmailbox/lib/action_mailbox/base.rb', line 111
def bounce_now_with( ) inbound_email.bounced! .deliver_now end
#bounce_with(message)
Enqueues the given message
for delivery and changes the inbound email’s status to :bounced
.
# File 'actionmailbox/lib/action_mailbox/base.rb', line 105
def bounce_with( ) inbound_email.bounced! .deliver_later end
#bounced!
[ GitHub ]# File 'actionmailbox/lib/action_mailbox/base.rb', line 71
delegate :mail, :delivered!, :bounced!, to: :inbound_email
#delivered!
[ GitHub ]# File 'actionmailbox/lib/action_mailbox/base.rb', line 71
delegate :mail, :delivered!, :bounced!, to: :inbound_email
#instrumentation_payload (private)
[ GitHub ]# File 'actionmailbox/lib/action_mailbox/base.rb', line 117
def instrumentation_payload { mailbox: self, inbound_email: inbound_email.instrumentation_payload } end
#perform_processing
# File 'actionmailbox/lib/action_mailbox/base.rb', line 83
def perform_processing # :nodoc: ActiveSupport::Notifications.instrument "process.action_mailbox", instrumentation_payload do 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 end
#process
[ GitHub ]# File 'actionmailbox/lib/action_mailbox/base.rb', line 96
def process # Override in subclasses end
#track_status_of_inbound_email (private)
[ GitHub ]# File 'actionmailbox/lib/action_mailbox/base.rb', line 124
def track_status_of_inbound_email inbound_email.processing! yield inbound_email.delivered! unless inbound_email.bounced? rescue inbound_email.failed! raise end