mirror of https://github.com/rails/rails
Add Exim and Qmail support to Action Mailbox
This commit is contained in:
parent
bb75d68fe2
commit
512b5316dd
|
@ -1,6 +1,6 @@
|
|||
# Action Mailbox
|
||||
|
||||
Action Mailbox routes incoming emails to controller-like mailboxes for processing in Rails. It ships with ingresses for Amazon SES, Mailgun, Mandrill, Postmark, and SendGrid. You can also handle inbound mails directly via the built-in Postfix ingress.
|
||||
Action Mailbox routes incoming emails to controller-like mailboxes for processing in Rails. It ships with ingresses for Amazon SES, Mailgun, Mandrill, Postmark, and SendGrid. You can also handle inbound mails directly via the built-in Exim, Postfix, and Qmail ingresses.
|
||||
|
||||
The inbound emails are turned into `InboundEmail` records using Active Record and feature lifecycle tracking, storage of the original email on cloud storage via Active Storage, and responsible data handling with on-by-default incineration.
|
||||
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionMailbox
|
||||
# Ingests inbound emails relayed from Postfix.
|
||||
# Ingests inbound emails relayed from an SMTP server.
|
||||
#
|
||||
# Authenticates requests using HTTP basic access authentication. The username is always +actionmailbox+, and the
|
||||
# password is read from the application's encrypted credentials or an environment variable. See the Usage section below.
|
||||
#
|
||||
# Note that basic authentication is insecure over unencrypted HTTP. An attacker that intercepts cleartext requests to
|
||||
# the Postfix ingress can learn its password. You should only use the Postfix ingress over HTTPS.
|
||||
# the ingress can learn its password. You should only use this ingress over HTTPS.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# - <tt>204 No Content</tt> if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox
|
||||
# - <tt>401 Unauthorized</tt> if the request could not be authenticated
|
||||
# - <tt>404 Not Found</tt> if Action Mailbox is not configured to accept inbound emails from Postfix
|
||||
# - <tt>404 Not Found</tt> if Action Mailbox is not configured to accept inbound emails relayed from an SMTP server
|
||||
# - <tt>415 Unsupported Media Type</tt> if the request does not contain an RFC 822 message
|
||||
# - <tt>500 Server Error</tt> if the ingress password is not configured, or if one of the Active Record database,
|
||||
# the Active Storage service, or the Active Job backend is misconfigured or unavailable
|
||||
#
|
||||
# == Usage
|
||||
#
|
||||
# 1. Tell Action Mailbox to accept emails from Postfix:
|
||||
# 1. Tell Action Mailbox to accept emails from an SMTP relay:
|
||||
#
|
||||
# # config/environments/production.rb
|
||||
# config.action_mailbox.ingress = :postfix
|
||||
# config.action_mailbox.ingress = :relay
|
||||
#
|
||||
# 2. Generate a strong password that Action Mailbox can use to authenticate requests to the Postfix ingress.
|
||||
# 2. Generate a strong password that Action Mailbox can use to authenticate requests to the ingress.
|
||||
#
|
||||
# Use <tt>rails credentials:edit</tt> to add the password to your application's encrypted credentials under
|
||||
# +action_mailbox.ingress_password+, where Action Mailbox will automatically find it:
|
||||
|
@ -35,14 +35,20 @@ module ActionMailbox
|
|||
#
|
||||
# Alternatively, provide the password in the +RAILS_INBOUND_EMAIL_PASSWORD+ environment variable.
|
||||
#
|
||||
# 3. {Configure Postfix}[https://serverfault.com/questions/258469/how-to-configure-postfix-to-pipe-all-incoming-email-to-a-script]
|
||||
# to pipe inbound emails to <tt>bin/rails action_mailbox:ingress:postfix</tt>, providing the +URL+ of the Postfix
|
||||
# ingress and the +INGRESS_PASSWORD+ you previously generated.
|
||||
# 3. Configure your SMTP server to pipe inbound emails to the appropriate ingress command, providing the +URL+ of the
|
||||
# relay ingress and the +INGRESS_PASSWORD+ you previously generated.
|
||||
#
|
||||
# If your application lived at <tt>https://example.com</tt>, the full command would look like this:
|
||||
# If your application lives at <tt>https://example.com</tt>, you would configure the Postfix SMTP server to pipe
|
||||
# inbound emails to the following command:
|
||||
#
|
||||
# URL=https://example.com/rails/action_mailbox/postfix/inbound_emails INGRESS_PASSWORD=... bin/rails action_mailbox:ingress:postfix
|
||||
class Ingresses::Postfix::InboundEmailsController < ActionMailbox::BaseController
|
||||
# bin/rails action_mailbox:ingress:postfix URL=https://example.com/rails/action_mailbox/postfix/inbound_emails INGRESS_PASSWORD=...
|
||||
#
|
||||
# Built-in ingress commands are available for these popular SMTP servers:
|
||||
#
|
||||
# - Exim (<tt>bin/rails action_mailbox:ingress:exim)
|
||||
# - Postfix (<tt>bin/rails action_mailbox:ingress:postfix)
|
||||
# - Qmail (<tt>bin/rails action_mailbox:ingress:qmail)
|
||||
class Ingresses::Relay::InboundEmailsController < ActionMailbox::BaseController
|
||||
before_action :authenticate_by_password, :require_valid_rfc822_message
|
||||
|
||||
def create
|
|
@ -4,8 +4,8 @@ Rails.application.routes.draw do
|
|||
scope "/rails/action_mailbox", module: "action_mailbox/ingresses" do
|
||||
post "/amazon/inbound_emails" => "amazon/inbound_emails#create", as: :rails_amazon_inbound_emails
|
||||
post "/mandrill/inbound_emails" => "mandrill/inbound_emails#create", as: :rails_mandrill_inbound_emails
|
||||
post "/postfix/inbound_emails" => "postfix/inbound_emails#create", as: :rails_postfix_inbound_emails
|
||||
post "/postmark/inbound_emails" => "postmark/inbound_emails#create", as: :rails_postmark_inbound_emails
|
||||
post "/relay/inbound_emails" => "relay/inbound_emails#create", as: :rails_relay_inbound_emails
|
||||
post "/sendgrid/inbound_emails" => "sendgrid/inbound_emails#create", as: :rails_sendgrid_inbound_emails
|
||||
|
||||
# Mailgun requires that a webhook's URL end in 'mime' for it to receive the raw contents of emails.
|
||||
|
|
|
@ -5,19 +5,27 @@ require "net/http"
|
|||
require "uri"
|
||||
|
||||
module ActionMailbox
|
||||
class PostfixRelayer
|
||||
class Result < Struct.new(:output)
|
||||
class Relayer
|
||||
class Result < Struct.new(:status_code, :message)
|
||||
def success?
|
||||
!failure?
|
||||
end
|
||||
|
||||
def failure?
|
||||
output.match?(/\A[45]\.\d{1,3}\.\d{1,3}(\s|\z)/)
|
||||
transient_failure? || permanent_failure?
|
||||
end
|
||||
|
||||
def transient_failure?
|
||||
status_code.start_with?("4.")
|
||||
end
|
||||
|
||||
def permanent_failure?
|
||||
status_code.start_with?("5.")
|
||||
end
|
||||
end
|
||||
|
||||
CONTENT_TYPE = "message/rfc822"
|
||||
USER_AGENT = "Action Mailbox Postfix relayer v#{ActionMailbox.version}"
|
||||
USER_AGENT = "Action Mailbox relayer v#{ActionMailbox.version}"
|
||||
|
||||
attr_reader :uri, :username, :password
|
||||
|
||||
|
@ -28,18 +36,18 @@ module ActionMailbox
|
|||
def relay(source)
|
||||
case response = post(source)
|
||||
when Net::HTTPSuccess
|
||||
Result.new "2.0.0 Successfully relayed message to Postfix ingress"
|
||||
Result.new "2.0.0", "Successfully relayed message to ingress"
|
||||
when Net::HTTPUnauthorized
|
||||
Result.new "4.7.0 Invalid credentials for Postfix ingress"
|
||||
Result.new "4.7.0", "Invalid credentials for ingress"
|
||||
else
|
||||
Result.new "4.0.0 HTTP #{response.code}"
|
||||
Result.new "4.0.0", "HTTP #{response.code}"
|
||||
end
|
||||
rescue IOError, SocketError, SystemCallError => error
|
||||
Result.new "4.4.2 Network error relaying to Postfix ingress: #{error.message}"
|
||||
Result.new "4.4.2", "Network error relaying to ingress: #{error.message}"
|
||||
rescue Timeout::Error
|
||||
Result.new "4.4.2 Timed out relaying to Postfix ingress"
|
||||
Result.new "4.4.2", "Timed out relaying to ingress"
|
||||
rescue => error
|
||||
Result.new "4.0.0 Error relaying to Postfix ingress: #{error.message}"
|
||||
Result.new "4.0.0", "Error relaying to ingress: #{error.message}"
|
||||
end
|
||||
|
||||
private
|
|
@ -2,12 +2,37 @@
|
|||
|
||||
namespace :action_mailbox do
|
||||
namespace :ingress do
|
||||
desc "Pipe an inbound email from STDIN to the Postfix ingress (URL and INGRESS_PASSWORD required)"
|
||||
task :postfix do
|
||||
task :environment do
|
||||
require "active_support"
|
||||
require "active_support/core_ext/object/blank"
|
||||
require "action_mailbox/postfix_relayer"
|
||||
require "action_mailbox/relayer"
|
||||
end
|
||||
|
||||
desc "Relay an inbound email from Exim to Action Mailbox (URL and INGRESS_PASSWORD required)"
|
||||
task exim: "action_mailbox:ingress:environment" do
|
||||
url, password = ENV.values_at("URL", "INGRESS_PASSWORD")
|
||||
|
||||
if url.blank? || password.blank?
|
||||
print "URL and INGRESS_PASSWORD are required"
|
||||
exit 64 # EX_USAGE
|
||||
end
|
||||
|
||||
ActionMailbox::Relayer.new(url: url, password: password).relay(STDIN.read).tap do |result|
|
||||
print result.message
|
||||
|
||||
case
|
||||
when result.success?
|
||||
exit 0
|
||||
when result.transient_failure?
|
||||
exit 75 # EX_TEMPFAIL
|
||||
else
|
||||
exit 69 # EX_UNAVAILABLE
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Relay an inbound email from Postfix to Action Mailbox (URL and INGRESS_PASSWORD required)"
|
||||
task postfix: "action_mailbox:ingress:environment" do
|
||||
url, password = ENV.values_at("URL", "INGRESS_PASSWORD")
|
||||
|
||||
if url.blank? || password.blank?
|
||||
|
@ -15,10 +40,33 @@ namespace :action_mailbox do
|
|||
exit 1
|
||||
end
|
||||
|
||||
ActionMailbox::PostfixRelayer.new(url: url, password: password).relay(STDIN.read).tap do |result|
|
||||
print result.output
|
||||
ActionMailbox::Relayer.new(url: url, password: password).relay(STDIN.read).tap do |result|
|
||||
print "#{result.status_code} #{result.message}"
|
||||
exit result.success?
|
||||
end
|
||||
end
|
||||
|
||||
desc "Relay an inbound email from Qmail to Action Mailbox (URL and INGRESS_PASSWORD required)"
|
||||
task qmail: "action_mailbox:ingress:environment" do
|
||||
url, password = ENV.values_at("URL", "INGRESS_PASSWORD")
|
||||
|
||||
if url.blank? || password.blank?
|
||||
print "URL and INGRESS_PASSWORD are required"
|
||||
exit 111
|
||||
end
|
||||
|
||||
ActionMailbox::Relayer.new(url: url, password: password).relay(STDIN.read).tap do |result|
|
||||
print result.message
|
||||
|
||||
case
|
||||
when result.success?
|
||||
exit 0
|
||||
when result.transient_failure?
|
||||
exit 111
|
||||
else
|
||||
exit 100
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
require "test_helper"
|
||||
|
||||
class ActionMailbox::Ingresses::Postfix::InboundEmailsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup { ActionMailbox.ingress = :postfix }
|
||||
class ActionMailbox::Ingresses::Relay::InboundEmailsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup { ActionMailbox.ingress = :relay }
|
||||
|
||||
test "receiving an inbound email from Postfix" do
|
||||
test "receiving an inbound email relayed from an SMTP server" do
|
||||
assert_difference -> { ActionMailbox::InboundEmail.count }, +1 do
|
||||
post rails_postfix_inbound_emails_url, headers: { "Authorization" => credentials, "Content-Type" => "message/rfc822" },
|
||||
post rails_relay_inbound_emails_url, headers: { "Authorization" => credentials, "Content-Type" => "message/rfc822" },
|
||||
params: file_fixture("../files/welcome.eml").read
|
||||
end
|
||||
|
||||
|
@ -18,18 +18,18 @@ class ActionMailbox::Ingresses::Postfix::InboundEmailsControllerTest < ActionDis
|
|||
assert_equal "0CB459E0-0336-41DA-BC88-E6E28C697DDB@37signals.com", inbound_email.message_id
|
||||
end
|
||||
|
||||
test "rejecting an unauthorized inbound email from Postfix" do
|
||||
test "rejecting an unauthorized inbound email" do
|
||||
assert_no_difference -> { ActionMailbox::InboundEmail.count } do
|
||||
post rails_postfix_inbound_emails_url, headers: { "Content-Type" => "message/rfc822" },
|
||||
post rails_relay_inbound_emails_url, headers: { "Content-Type" => "message/rfc822" },
|
||||
params: file_fixture("../files/welcome.eml").read
|
||||
end
|
||||
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
test "rejecting an inbound email of an unsupported media type from Postfix" do
|
||||
test "rejecting an inbound email of an unsupported media type" do
|
||||
assert_no_difference -> { ActionMailbox::InboundEmail.count } do
|
||||
post rails_postfix_inbound_emails_url, headers: { "Authorization" => credentials, "Content-Type" => "text/plain" },
|
||||
post rails_relay_inbound_emails_url, headers: { "Authorization" => credentials, "Content-Type" => "text/plain" },
|
||||
params: file_fixture("../files/welcome.eml").read
|
||||
end
|
||||
|
||||
|
@ -39,7 +39,7 @@ class ActionMailbox::Ingresses::Postfix::InboundEmailsControllerTest < ActionDis
|
|||
test "raising when the configured password is nil" do
|
||||
switch_password_to nil do
|
||||
assert_raises ArgumentError do
|
||||
post rails_postfix_inbound_emails_url, headers: { "Authorization" => credentials, "Content-Type" => "message/rfc822" },
|
||||
post rails_relay_inbound_emails_url, headers: { "Authorization" => credentials, "Content-Type" => "message/rfc822" },
|
||||
params: file_fixture("../files/welcome.eml").read
|
||||
end
|
||||
end
|
||||
|
@ -48,7 +48,7 @@ class ActionMailbox::Ingresses::Postfix::InboundEmailsControllerTest < ActionDis
|
|||
test "raising when the configured password is blank" do
|
||||
switch_password_to "" do
|
||||
assert_raises ArgumentError do
|
||||
post rails_postfix_inbound_emails_url, headers: { "Authorization" => credentials, "Content-Type" => "message/rfc822" },
|
||||
post rails_relay_inbound_emails_url, headers: { "Authorization" => credentials, "Content-Type" => "message/rfc822" },
|
||||
params: file_fixture("../files/welcome.eml").read
|
||||
end
|
||||
end
|
|
@ -2,35 +2,37 @@
|
|||
|
||||
require_relative "../test_helper"
|
||||
|
||||
require "action_mailbox/postfix_relayer"
|
||||
require "action_mailbox/relayer"
|
||||
|
||||
module ActionMailbox
|
||||
class PostfixRelayerTest < ActiveSupport::TestCase
|
||||
URL = "https://example.com/rails/action_mailbox/postfix/inbound_emails"
|
||||
class RelayerTest < ActiveSupport::TestCase
|
||||
URL = "https://example.com/rails/action_mailbox/relay/inbound_emails"
|
||||
INGRESS_PASSWORD = "secret"
|
||||
|
||||
setup do
|
||||
@relayer = ActionMailbox::PostfixRelayer.new(url: URL, password: INGRESS_PASSWORD)
|
||||
@relayer = ActionMailbox::Relayer.new(url: URL, password: INGRESS_PASSWORD)
|
||||
end
|
||||
|
||||
test "successfully relaying an email" do
|
||||
stub_request(:post, URL).to_return status: 204
|
||||
|
||||
result = @relayer.relay(file_fixture("welcome.eml").read)
|
||||
assert_equal "2.0.0 Successfully relayed message to Postfix ingress", result.output
|
||||
assert_equal "2.0.0", result.status_code
|
||||
assert_equal "Successfully relayed message to ingress", result.message
|
||||
assert result.success?
|
||||
assert_not result.failure?
|
||||
|
||||
assert_requested :post, URL, body: file_fixture("welcome.eml").read,
|
||||
basic_auth: [ "actionmailbox", INGRESS_PASSWORD ],
|
||||
headers: { "Content-Type" => "message/rfc822", "User-Agent" => /\AAction Mailbox Postfix relayer v\d+\./ }
|
||||
headers: { "Content-Type" => "message/rfc822", "User-Agent" => /\AAction Mailbox relayer v\d+\./ }
|
||||
end
|
||||
|
||||
test "unsuccessfully relaying with invalid credentials" do
|
||||
stub_request(:post, URL).to_return status: 401
|
||||
|
||||
result = @relayer.relay(file_fixture("welcome.eml").read)
|
||||
assert_equal "4.7.0 Invalid credentials for Postfix ingress", result.output
|
||||
assert_equal "4.7.0", result.status_code
|
||||
assert_equal "Invalid credentials for ingress", result.message
|
||||
assert_not result.success?
|
||||
assert result.failure?
|
||||
end
|
||||
|
@ -39,7 +41,8 @@ module ActionMailbox
|
|||
stub_request(:post, URL).to_return status: 500
|
||||
|
||||
result = @relayer.relay(file_fixture("welcome.eml").read)
|
||||
assert_equal "4.0.0 HTTP 500", result.output
|
||||
assert_equal "4.0.0", result.status_code
|
||||
assert_equal "HTTP 500", result.message
|
||||
assert_not result.success?
|
||||
assert result.failure?
|
||||
end
|
||||
|
@ -48,7 +51,8 @@ module ActionMailbox
|
|||
stub_request(:post, URL).to_return status: 504
|
||||
|
||||
result = @relayer.relay(file_fixture("welcome.eml").read)
|
||||
assert_equal "4.0.0 HTTP 504", result.output
|
||||
assert_equal "4.0.0", result.status_code
|
||||
assert_equal "HTTP 504", result.message
|
||||
assert_not result.success?
|
||||
assert result.failure?
|
||||
end
|
||||
|
@ -57,7 +61,8 @@ module ActionMailbox
|
|||
stub_request(:post, URL).to_raise Errno::ECONNRESET.new
|
||||
|
||||
result = @relayer.relay(file_fixture("welcome.eml").read)
|
||||
assert_equal "4.4.2 Network error relaying to Postfix ingress: Connection reset by peer", result.output
|
||||
assert_equal "4.4.2", result.status_code
|
||||
assert_equal "Network error relaying to ingress: Connection reset by peer", result.message
|
||||
assert_not result.success?
|
||||
assert result.failure?
|
||||
end
|
||||
|
@ -66,7 +71,8 @@ module ActionMailbox
|
|||
stub_request(:post, URL).to_raise SocketError.new("Failed to open TCP connection to example.com:443")
|
||||
|
||||
result = @relayer.relay(file_fixture("welcome.eml").read)
|
||||
assert_equal "4.4.2 Network error relaying to Postfix ingress: Failed to open TCP connection to example.com:443", result.output
|
||||
assert_equal "4.4.2", result.status_code
|
||||
assert_equal "Network error relaying to ingress: Failed to open TCP connection to example.com:443", result.message
|
||||
assert_not result.success?
|
||||
assert result.failure?
|
||||
end
|
||||
|
@ -75,7 +81,8 @@ module ActionMailbox
|
|||
stub_request(:post, URL).to_timeout
|
||||
|
||||
result = @relayer.relay(file_fixture("welcome.eml").read)
|
||||
assert_equal "4.4.2 Timed out relaying to Postfix ingress", result.output
|
||||
assert_equal "4.4.2", result.status_code
|
||||
assert_equal "Timed out relaying to ingress", result.message
|
||||
assert_not result.success?
|
||||
assert result.failure?
|
||||
end
|
||||
|
@ -84,7 +91,8 @@ module ActionMailbox
|
|||
stub_request(:post, URL).to_raise StandardError.new("Something went wrong")
|
||||
|
||||
result = @relayer.relay(file_fixture("welcome.eml").read)
|
||||
assert_equal "4.0.0 Error relaying to Postfix ingress: Something went wrong", result.output
|
||||
assert_equal "4.0.0", result.status_code
|
||||
assert_equal "Error relaying to ingress: Something went wrong", result.message
|
||||
assert_not result.success?
|
||||
assert result.failure?
|
||||
end
|
|
@ -21,7 +21,7 @@ Introduction
|
|||
Action Mailbox routes incoming emails to controller-like mailboxes for
|
||||
processing in Rails. It ships with ingresses for Amazon SES, Mailgun, Mandrill,
|
||||
Postmark, and SendGrid. You can also handle inbound mails directly via the
|
||||
built-in Postfix ingress.
|
||||
built-in Exim, Postfix, and Qmail ingresses.
|
||||
|
||||
The inbound emails are turned into `InboundEmail` records using Active Record
|
||||
and feature lifecycle tracking, storage of the original email on cloud storage
|
||||
|
@ -65,6 +65,36 @@ to deliver emails to your application via POST requests to
|
|||
`https://example.com`, you would specify the fully-qualified URL
|
||||
`https://example.com/rails/action_mailbox/amazon/inbound_emails`.
|
||||
|
||||
### Exim
|
||||
|
||||
Tell Action Mailbox to accept emails from an SMTP relay:
|
||||
|
||||
```ruby
|
||||
# config/environments/production.rb
|
||||
config.action_mailbox.ingress = :relay
|
||||
```
|
||||
|
||||
Generate a strong password that Action Mailbox can use to authenticate requests to the relay ingress.
|
||||
|
||||
Use `rails credentials:edit` to add the password to your application's encrypted credentials under
|
||||
`action_mailbox.ingress_password`, where Action Mailbox will automatically find it:
|
||||
|
||||
```yaml
|
||||
action_mailbox:
|
||||
ingress_password: ...
|
||||
```
|
||||
|
||||
Alternatively, provide the password in the `RAILS_INBOUND_EMAIL_PASSWORD` environment variable.
|
||||
|
||||
Configure Exim to pipe inbound emails to `bin/rails action_mailbox:ingress:exim`,
|
||||
providing the `URL` of the relay ingress and the `INGRESS_PASSWORD` you
|
||||
previously generated. If your application lived at `https://example.com`, the
|
||||
full command would look like this:
|
||||
|
||||
```shell
|
||||
bin/rails action_mailbox:ingress:exim URL=https://example.com/rails/action_mailbox/relay/inbound_emails INGRESS_PASSWORD=...
|
||||
```
|
||||
|
||||
### Mailgun
|
||||
|
||||
Give Action Mailbox your
|
||||
|
@ -126,14 +156,14 @@ the fully-qualified URL `https://example.com/rails/action_mailbox/mandrill/inbou
|
|||
|
||||
### Postfix
|
||||
|
||||
Tell Action Mailbox to accept emails from Postfix:
|
||||
Tell Action Mailbox to accept emails from an SMTP relay:
|
||||
|
||||
```ruby
|
||||
# config/environments/production.rb
|
||||
config.action_mailbox.ingress = :postfix
|
||||
config.action_mailbox.ingress = :relay
|
||||
```
|
||||
|
||||
Generate a strong password that Action Mailbox can use to authenticate requests to the Postfix ingress.
|
||||
Generate a strong password that Action Mailbox can use to authenticate requests to the relay ingress.
|
||||
|
||||
Use `rails credentials:edit` to add the password to your application's encrypted credentials under
|
||||
`action_mailbox.ingress_password`, where Action Mailbox will automatically find it:
|
||||
|
@ -151,8 +181,8 @@ the `URL` of the Postfix ingress and the `INGRESS_PASSWORD` you previously
|
|||
generated. If your application lived at `https://example.com`, the full command
|
||||
would look like this:
|
||||
|
||||
```bash
|
||||
$ URL=https://example.com/rails/action_mailbox/postfix/inbound_emails INGRESS_PASSWORD=... rails action_mailbox:ingress:postfix
|
||||
```shell
|
||||
$ bin/rails action_mailbox:ingress:postfix URL=https://example.com/rails/action_mailbox/relay/inbound_emails INGRESS_PASSWORD=...
|
||||
```
|
||||
|
||||
### Postmark
|
||||
|
@ -191,6 +221,36 @@ https://actionmailbox:PASSWORD@example.com/rails/action_mailbox/postmark/inbound
|
|||
NOTE: When configuring your Postmark inbound webhook, be sure to check the box labeled **"Include raw email content in JSON payload"**.
|
||||
Action Mailbox needs the raw email content to work.
|
||||
|
||||
### Qmail
|
||||
|
||||
Tell Action Mailbox to accept emails from an SMTP relay:
|
||||
|
||||
```ruby
|
||||
# config/environments/production.rb
|
||||
config.action_mailbox.ingress = :relay
|
||||
```
|
||||
|
||||
Generate a strong password that Action Mailbox can use to authenticate requests to the relay ingress.
|
||||
|
||||
Use `rails credentials:edit` to add the password to your application's encrypted credentials under
|
||||
`action_mailbox.ingress_password`, where Action Mailbox will automatically find it:
|
||||
|
||||
```yaml
|
||||
action_mailbox:
|
||||
ingress_password: ...
|
||||
```
|
||||
|
||||
Alternatively, provide the password in the `RAILS_INBOUND_EMAIL_PASSWORD` environment variable.
|
||||
|
||||
Configure Qmail to pipe inbound emails to `bin/rails action_mailbox:ingress:qmail`,
|
||||
providing the `URL` of the relay ingress and the `INGRESS_PASSWORD` you
|
||||
previously generated. If your application lived at `https://example.com`, the
|
||||
full command would look like this:
|
||||
|
||||
```shell
|
||||
bin/rails action_mailbox:ingress:qmail URL=https://example.com/rails/action_mailbox/relay/inbound_emails INGRESS_PASSWORD=...
|
||||
```
|
||||
|
||||
### SendGrid
|
||||
|
||||
Tell Action Mailbox to accept emails from SendGrid:
|
||||
|
|
|
@ -22,8 +22,8 @@ module ApplicationTests
|
|||
cart GET /cart(.:format) cart#show
|
||||
rails_amazon_inbound_emails POST /rails/action_mailbox/amazon/inbound_emails(.:format) action_mailbox/ingresses/amazon/inbound_emails#create
|
||||
rails_mandrill_inbound_emails POST /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#create
|
||||
rails_postfix_inbound_emails POST /rails/action_mailbox/postfix/inbound_emails(.:format) action_mailbox/ingresses/postfix/inbound_emails#create
|
||||
rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create
|
||||
rails_relay_inbound_emails POST /rails/action_mailbox/relay/inbound_emails(.:format) action_mailbox/ingresses/relay/inbound_emails#create
|
||||
rails_sendgrid_inbound_emails POST /rails/action_mailbox/sendgrid/inbound_emails(.:format) action_mailbox/ingresses/sendgrid/inbound_emails#create
|
||||
rails_mailgun_inbound_emails POST /rails/action_mailbox/mailgun/inbound_emails/mime(.:format) action_mailbox/ingresses/mailgun/inbound_emails#create
|
||||
rails_conductor_inbound_emails GET /rails/conductor/action_mailbox/inbound_emails(.:format) rails/conductor/action_mailbox/inbound_emails#index
|
||||
|
|
|
@ -26,7 +26,6 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase
|
|||
PUT /post(.:format) posts#update
|
||||
DELETE /post(.:format) posts#destroy
|
||||
POST /post(.:format) posts#create
|
||||
rails_postfix_inbound_emails POST /rails/action_mailbox/postfix/inbound_emails(.:format) action_mailbox/ingresses/postfix/inbound_emails#create
|
||||
rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create
|
||||
OUTPUT
|
||||
|
||||
|
@ -65,8 +64,8 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase
|
|||
POST /cart(.:format) cart#create
|
||||
rails_amazon_inbound_emails POST /rails/action_mailbox/amazon/inbound_emails(.:format) action_mailbox/ingresses/amazon/inbound_emails#create
|
||||
rails_mandrill_inbound_emails POST /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#create
|
||||
rails_postfix_inbound_emails POST /rails/action_mailbox/postfix/inbound_emails(.:format) action_mailbox/ingresses/postfix/inbound_emails#create
|
||||
rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create
|
||||
rails_relay_inbound_emails POST /rails/action_mailbox/relay/inbound_emails(.:format) action_mailbox/ingresses/relay/inbound_emails#create
|
||||
rails_sendgrid_inbound_emails POST /rails/action_mailbox/sendgrid/inbound_emails(.:format) action_mailbox/ingresses/sendgrid/inbound_emails#create
|
||||
rails_mailgun_inbound_emails POST /rails/action_mailbox/mailgun/inbound_emails/mime(.:format) action_mailbox/ingresses/mailgun/inbound_emails#create
|
||||
POST /rails/conductor/action_mailbox/inbound_emails(.:format) rails/conductor/action_mailbox/inbound_emails#create
|
||||
|
@ -141,7 +140,6 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase
|
|||
PUT /admin/post(.:format) admin/posts#update
|
||||
DELETE /admin/post(.:format) admin/posts#destroy
|
||||
POST /admin/post(.:format) admin/posts#create
|
||||
rails_postfix_inbound_emails POST /rails/action_mailbox/postfix/inbound_emails(.:format) action_mailbox/ingresses/postfix/inbound_emails#create
|
||||
rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create
|
||||
OUTPUT
|
||||
|
||||
|
@ -170,8 +168,8 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase
|
|||
Prefix Verb URI Pattern Controller#Action
|
||||
rails_amazon_inbound_emails POST /rails/action_mailbox/amazon/inbound_emails(.:format) action_mailbox/ingresses/amazon/inbound_emails#create
|
||||
rails_mandrill_inbound_emails POST /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#create
|
||||
rails_postfix_inbound_emails POST /rails/action_mailbox/postfix/inbound_emails(.:format) action_mailbox/ingresses/postfix/inbound_emails#create
|
||||
rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create
|
||||
rails_relay_inbound_emails POST /rails/action_mailbox/relay/inbound_emails(.:format) action_mailbox/ingresses/relay/inbound_emails#create
|
||||
rails_sendgrid_inbound_emails POST /rails/action_mailbox/sendgrid/inbound_emails(.:format) action_mailbox/ingresses/sendgrid/inbound_emails#create
|
||||
rails_mailgun_inbound_emails POST /rails/action_mailbox/mailgun/inbound_emails/mime(.:format) action_mailbox/ingresses/mailgun/inbound_emails#create
|
||||
rails_conductor_inbound_emails GET /rails/conductor/action_mailbox/inbound_emails(.:format) rails/conductor/action_mailbox/inbound_emails#index
|
||||
|
@ -219,15 +217,15 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase
|
|||
URI | /rails/action_mailbox/mandrill/inbound_emails(.:format)
|
||||
Controller#Action | action_mailbox/ingresses/mandrill/inbound_emails#create
|
||||
--[ Route 4 ]--------------
|
||||
Prefix | rails_postfix_inbound_emails
|
||||
Verb | POST
|
||||
URI | /rails/action_mailbox/postfix/inbound_emails(.:format)
|
||||
Controller#Action | action_mailbox/ingresses/postfix/inbound_emails#create
|
||||
--[ Route 5 ]--------------
|
||||
Prefix | rails_postmark_inbound_emails
|
||||
Verb | POST
|
||||
URI | /rails/action_mailbox/postmark/inbound_emails(.:format)
|
||||
Controller#Action | action_mailbox/ingresses/postmark/inbound_emails#create
|
||||
--[ Route 5 ]--------------
|
||||
Prefix | rails_relay_inbound_emails
|
||||
Verb | POST
|
||||
URI | /rails/action_mailbox/relay/inbound_emails(.:format)
|
||||
Controller#Action | action_mailbox/ingresses/relay/inbound_emails#create
|
||||
--[ Route 6 ]--------------
|
||||
Prefix | rails_sendgrid_inbound_emails
|
||||
Verb | POST
|
||||
|
|
Loading…
Reference in New Issue