Nest Action Mailbox classes in the API docs
This commit is contained in:
parent
11a8ba1272
commit
6c168aaffb
|
@ -1,7 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# The base class for all Active Mailbox ingress controllers.
|
||||
class ActionMailbox::BaseController < ActionController::Base
|
||||
class BaseController < ActionController::Base
|
||||
skip_forgery_protection
|
||||
|
||||
before_action :ensure_configured
|
||||
|
@ -34,3 +35,4 @@ class ActionMailbox::BaseController < ActionController::Base
|
|||
Rails.application.credentials.dig(:action_mailbox, :ingress_password) || ENV["RAILS_INBOUND_EMAIL_PASSWORD"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# Ingests inbound emails from Amazon's Simple Email Service (SES).
|
||||
#
|
||||
# Requires the full RFC 822 message in the +content+ parameter. Authenticates requests by validating their signatures.
|
||||
|
@ -29,7 +30,7 @@
|
|||
# to deliver emails to your application via POST requests to +/rails/action_mailbox/amazon/inbound_emails+.
|
||||
# If your application lived at <tt>https://example.com</tt>, you would specify the fully-qualified URL
|
||||
# <tt>https://example.com/rails/action_mailbox/amazon/inbound_emails</tt>.
|
||||
class ActionMailbox::Ingresses::Amazon::InboundEmailsController < ActionMailbox::BaseController
|
||||
class Ingresses::Amazon::InboundEmailsController < BaseController
|
||||
before_action :authenticate
|
||||
|
||||
cattr_accessor :verifier
|
||||
|
@ -50,3 +51,4 @@ class ActionMailbox::Ingresses::Amazon::InboundEmailsController < ActionMailbox:
|
|||
head :unauthorized unless verifier.authentic?(request.body)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# Ingests inbound emails from Mailgun. Requires the following parameters:
|
||||
#
|
||||
# - +body-mime+: The full RFC 822 message
|
||||
|
@ -41,7 +42,7 @@
|
|||
#
|
||||
# If your application lived at <tt>https://example.com</tt>, you would specify the fully-qualified URL
|
||||
# <tt>https://example.com/rails/action_mailbox/mailgun/inbound_emails/mime</tt>.
|
||||
class ActionMailbox::Ingresses::Mailgun::InboundEmailsController < ActionMailbox::BaseController
|
||||
class Ingresses::Mailgun::InboundEmailsController < ActionMailbox::BaseController
|
||||
before_action :authenticate
|
||||
|
||||
def create
|
||||
|
@ -99,3 +100,4 @@ class ActionMailbox::Ingresses::Mailgun::InboundEmailsController < ActionMailbox
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# Ingests inbound emails from Mandrill.
|
||||
#
|
||||
# Requires a +mandrill_events+ parameter containing a JSON array of Mandrill inbound email event objects.
|
||||
|
@ -13,7 +14,7 @@
|
|||
# - <tt>422 Unprocessable Entity</tt> if the request is missing required parameters
|
||||
# - <tt>500 Server Error</tt> if the Mandrill API key is missing, or one of the Active Record database,
|
||||
# the Active Storage service, or the Active Job backend is misconfigured or unavailable
|
||||
class ActionMailbox::Ingresses::Mandrill::InboundEmailsController < ActionMailbox::BaseController
|
||||
class Ingresses::Mandrill::InboundEmailsController < ActionMailbox::BaseController
|
||||
before_action :authenticate
|
||||
|
||||
def create
|
||||
|
@ -78,3 +79,4 @@ class ActionMailbox::Ingresses::Mandrill::InboundEmailsController < ActionMailbo
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# Ingests inbound emails relayed from Postfix.
|
||||
#
|
||||
# Authenticates requests using HTTP basic access authentication. The username is always +actionmailbox+, and the
|
||||
|
@ -41,7 +42,7 @@
|
|||
# If your application lived at <tt>https://example.com</tt>, the full command would look like this:
|
||||
#
|
||||
# URL=https://example.com/rails/action_mailbox/postfix/inbound_emails INGRESS_PASSWORD=... bin/rails action_mailbox:ingress:postfix
|
||||
class ActionMailbox::Ingresses::Postfix::InboundEmailsController < ActionMailbox::BaseController
|
||||
class Ingresses::Postfix::InboundEmailsController < ActionMailbox::BaseController
|
||||
before_action :authenticate_by_password, :require_valid_rfc822_message
|
||||
|
||||
def create
|
||||
|
@ -55,3 +56,4 @@ class ActionMailbox::Ingresses::Postfix::InboundEmailsController < ActionMailbox
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# Ingests inbound emails from SendGrid. Requires an +email+ parameter containing a full RFC 822 message.
|
||||
#
|
||||
# Authenticates requests using HTTP basic access authentication. The username is always +actionmailbox+, and the
|
||||
|
@ -43,10 +44,11 @@
|
|||
#
|
||||
# *NOTE:* When configuring your SendGrid Inbound Parse webhook, be sure to check the box labeled *"Post the raw,
|
||||
# full MIME message."* Action Mailbox needs the raw MIME message to work.
|
||||
class ActionMailbox::Ingresses::Sendgrid::InboundEmailsController < ActionMailbox::BaseController
|
||||
class Ingresses::Sendgrid::InboundEmailsController < ActionMailbox::BaseController
|
||||
before_action :authenticate_by_password
|
||||
|
||||
def create
|
||||
ActionMailbox::InboundEmail.create_and_extract_message_id! params.require(:email)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Rails::Conductor::ActionMailbox::InboundEmailsController < Rails::Conductor::BaseController
|
||||
module Rails
|
||||
class Conductor::ActionMailbox::InboundEmailsController < Rails::Conductor::BaseController
|
||||
def index
|
||||
@inbound_emails = ActionMailbox::InboundEmail.order(created_at: :desc)
|
||||
end
|
||||
|
@ -27,3 +28,4 @@ class Rails::Conductor::ActionMailbox::InboundEmailsController < Rails::Conducto
|
|||
{ io: StringIO.new(mail.to_s), filename: "inbound.eml", content_type: "message/rfc822" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Rails
|
||||
# Rerouting will run routing and processing on an email that has already been, or attempted to be, processed.
|
||||
class Rails::Conductor::ActionMailbox::ReroutesController < Rails::Conductor::BaseController
|
||||
class Conductor::ActionMailbox::ReroutesController < Rails::Conductor::BaseController
|
||||
def create
|
||||
inbound_email = ActionMailbox::InboundEmail.find(params[:inbound_email_id])
|
||||
reroute inbound_email
|
||||
|
@ -15,3 +16,4 @@ class Rails::Conductor::ActionMailbox::ReroutesController < Rails::Conductor::Ba
|
|||
inbound_email.route_later
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Rails
|
||||
# TODO: Move this to Rails::Conductor gem
|
||||
class Rails::Conductor::BaseController < ActionController::Base
|
||||
class Conductor::BaseController < ActionController::Base
|
||||
layout "rails/conductor"
|
||||
before_action :ensure_development_env
|
||||
|
||||
|
@ -10,3 +11,4 @@ class Rails::Conductor::BaseController < ActionController::Base
|
|||
head :forbidden unless Rails.env.development?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# You can configure when this `IncinerationJob` will be run as a time-after-processing using the
|
||||
# `config.action_mailbox.incinerate_after` or `ActionMailbox.incinerate_after` setting.
|
||||
#
|
||||
# Since this incineration is set for the future, it'll automatically ignore any `InboundEmail`s
|
||||
# that have already been deleted and discard itself if so.
|
||||
class ActionMailbox::IncinerationJob < ActiveJob::Base
|
||||
class IncinerationJob < ActiveJob::Base
|
||||
queue_as { ActionMailbox.queues[:incineration] }
|
||||
|
||||
discard_on ActiveRecord::RecordNotFound
|
||||
|
@ -18,3 +19,4 @@ class ActionMailbox::IncinerationJob < ActiveJob::Base
|
|||
inbound_email.incinerate
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# Routing a new InboundEmail is an asynchronous operation, which allows the ingress controllers to quickly
|
||||
# accept new incoming emails without being burdened to hang while they're actually being processed.
|
||||
class ActionMailbox::RoutingJob < ActiveJob::Base
|
||||
class RoutingJob < ActiveJob::Base
|
||||
queue_as { ActionMailbox.queues[:routing] }
|
||||
|
||||
def perform(inbound_email)
|
||||
inbound_email.route
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
require "mail"
|
||||
|
||||
module ActionMailbox
|
||||
# The `InboundEmail` is an Active Record that keeps a reference to the raw email stored in Active Storage
|
||||
# and tracks the status of processing. By default, incoming emails will go through the following lifecycle:
|
||||
#
|
||||
|
@ -23,7 +24,7 @@ require "mail"
|
|||
#
|
||||
# inbound_email.mail.from # => 'david@loudthinking.com'
|
||||
# inbound_email.source # Returns the full rfc822 source of the email as text
|
||||
class ActionMailbox::InboundEmail < ActiveRecord::Base
|
||||
class InboundEmail < ActiveRecord::Base
|
||||
self.table_name = "action_mailbox_inbound_emails"
|
||||
|
||||
include Incineratable, MessageId, Routable
|
||||
|
@ -43,3 +44,4 @@ class ActionMailbox::InboundEmail < ActiveRecord::Base
|
|||
delivered? || failed? || bounced?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# Command class for carrying out the actual incineration of the `InboundMail` that's been scheduled
|
||||
# for removal. Before the incineration – which really is just a call to `#destroy!` – is run, we verify
|
||||
# that it's both eligible (by virtue of having already been processed) and time to do so (that is,
|
||||
# the `InboundEmail` was processed after the `incinerate_after` time).
|
||||
class ActionMailbox::InboundEmail::Incineratable::Incineration
|
||||
class InboundEmail::Incineratable::Incineration
|
||||
def initialize(inbound_email)
|
||||
@inbound_email = inbound_email
|
||||
end
|
||||
|
@ -22,3 +23,4 @@ class ActionMailbox::InboundEmail::Incineratable::Incineration
|
|||
@inbound_email.processed?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Mail::Address
|
||||
module Mail
|
||||
class Address
|
||||
def ==(other_address)
|
||||
other_address.is_a?(Mail::Address) && to_s == other_address.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Mail::Address
|
||||
module Mail
|
||||
class Address
|
||||
def self.wrap(address)
|
||||
address.is_a?(Mail::Address) ? address : Mail::Address.new(address)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Mail::Message
|
||||
module Mail
|
||||
class Message
|
||||
def from_address
|
||||
header[:from]&.address_list&.addresses&.first
|
||||
end
|
||||
|
@ -25,3 +26,4 @@ class Mail::Message
|
|||
Array(header[:x_original_to]).collect { |header| Mail::Address.new header.to_s }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Mail::Message
|
||||
module Mail
|
||||
class Message
|
||||
def recipients
|
||||
Array(to) + Array(cc) + Array(bcc) + Array(header[:x_original_to]).map(&:to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# Encapsulates the routes that live on the ApplicationMailbox and performs the actual routing when
|
||||
# an inbound_email is received.
|
||||
class ActionMailbox::Router
|
||||
class Router
|
||||
class RoutingError < StandardError; end
|
||||
|
||||
def initialize
|
||||
|
@ -36,5 +37,6 @@ class ActionMailbox::Router
|
|||
routes.detect { |route| route.match?(inbound_email) }.try(:mailbox_class)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require "action_mailbox/router/route"
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# Encapsulates a route, which can then be matched against an inbound_email and provide a lookup of the matching
|
||||
# mailbox class. See examples for the different route addresses and how to use them in the `ActionMailbox::Base`
|
||||
# documentation.
|
||||
class ActionMailbox::Router::Route
|
||||
class Router::Route
|
||||
attr_reader :address, :mailbox_name
|
||||
|
||||
def initialize(address, to:)
|
||||
|
@ -38,3 +39,4 @@ class ActionMailbox::Router::Route
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue