v7.0.0
更多資訊請前往 rubyonrails.org: 更多在 Ruby on Rails

Action Mailbox 基礎知識

本指南為您提供了開始接收所需的一切 電子郵件到您的應用程式。

閱讀本指南後,您將瞭解:

1 Action Mailbox 是什麼?

Action Mailbox 將收到的電子郵件路由到類似 controller 的郵箱,以便 在 Rails 中處理。它附帶了 Mailgun、Mandrill、Postmark、 和傳送網格。您還可以透過內建的 Exim 直接處理入站郵件, Postfix 和 Qmail 入口。

使用 Active Record 將入站電子郵件轉換為 InboundEmail 記錄 並具有生命週期跟蹤功能,將原始電子郵件儲存在雲端儲存中 透過 Active Storage,以及負責的資料處理 預設焚燒。

這些入站電子郵件使用 Active Job 非同步路由到一個或 幾個專用郵箱,可以直接互動 與您域的其餘部分 model。

2 設定

安裝 InboundEmail 所需的 migrations 並確保已設定 Active Storage:

$ bin/rails action_mailbox:install
$ bin/rails db:migrate

3 配置

3.1 進出口

告訴 Action Mailbox 接受來自 SMTP 中繼的電子郵件:

# 配置/環境/production.rb
config.action_mailbox.ingress = :relay

生成一個強密碼,Action Mailbox 可以用它來驗證對中繼入口的請求。

使用 bin/rails credentials:edit 將密碼新增到您的應用程式的加密憑據下 action_mailbox.ingress_password,其中Action Mailbox會自動找到:

action_mailbox:
  ingress_password: ...

或者,在 RAILS_INBOUND_EMAIL_PASSWORD 環境變數中提供密碼。

配置 Exim 以透過管道將入站電子郵件傳送到 bin/rails action_mailbox:ingress:exim, 提供中繼入口的 URLINGRESS_PASSWORD 你 之前生成的。如果您的應用程式位於 https://example.com,則 完整命令如下所示:

$ bin/rails action_mailbox:ingress:exim URL=https://example.com/rails/action_mailbox/relay/inbound_emails INGRESS_PASSWORD=...

3.2 郵槍

給 Action Mailbox 你的 Mailgun 簽名 key(您可以在 Mailgun 中的設定 -> 安全和使用者 -> API 安全下找到), 因此它可以驗證對 Mailgun 入口的請求。

使用 bin/rails credentials:edit 將您的簽名 key 新增到您的應用程式的 action_mailbox.mailgun_signing_key 下的加密憑證, 其中 Action Mailbox 會自動找到它:

action_mailbox:
  mailgun_signing_key: ...

或者,在 MAILGUN_INGRESS_SIGNING_KEY 環境中提供您的簽名 key 多變的。

告訴 Action Mailbox 接受來自 Mailgun 的電子郵件:

# 配置/環境/production.rb
config.action_mailbox.ingress = :mailgun

配置Mailgun 將入站電子郵件轉發到 /rails/action_mailbox/mailgun/inbound_emails/mime。 如果您的應用程式位於 https://example.com,您將指定 完全限定的 URL https://example.com/rails/action_mailbox/mailgun/inbound_emails/mime

3.3 山魈

給 Action Mailbox 你的 Mandrill API key,這樣它就可以驗證請求 山魈入口。

使用 bin/rails credentials:edit 將您的 API key 新增到您的應用程式的 action_mailbox.mandrill_api_key 下的加密憑證, 其中 Action Mailbox 會自動找到它:

action_mailbox:
  mandrill_api_key: ...

或者,在 MANDRILL_INGRESS_API_KEY 中提供您的 API key 環境變數。

告訴 Action Mailbox 接受來自 Mandrill 的電子郵件:

# 配置/環境/production.rb
config.action_mailbox.ingress = :mandrill

配置 Mandrill 將入站電子郵件路由到 /rails/action_mailbox/mandrill/inbound_emails。 如果您的應用程式位於 https://example.com,您將指定 完全限定的 URL https://example.com/rails/action_mailbox/mandrill/inbound_emails

3.4 字尾

告訴 Action Mailbox 接受來自 SMTP 中繼的電子郵件:

# 配置/環境/production.rb
config.action_mailbox.ingress = :relay

生成一個強密碼,Action Mailbox 可以用它來驗證對中繼入口的請求。

使用 bin/rails credentials:edit 將密碼新增到您的應用程式的加密憑據下 action_mailbox.ingress_password,其中Action Mailbox會自動找到:

action_mailbox:
  ingress_password: ...

或者,在 RAILS_INBOUND_EMAIL_PASSWORD 環境變數中提供密碼。

配置字尾 將入站電子郵件透過管道傳輸到 bin/rails action_mailbox:ingress:postfix,提供 Postfix入口的URL和你之前的INGRESS_PASSWORD 生成。如果您的應用程式位於 https://example.com,則完整命令 看起來像這樣:

$ bin/rails action_mailbox:ingress:postfix URL=https://example.com/rails/action_mailbox/relay/inbound_emails INGRESS_PASSWORD=...

3.5 郵戳

告訴 Action Mailbox 接受來自 Postmark 的電子郵件:

# 配置/環境/production.rb
config.action_mailbox.ingress = :postmark

生成一個強密碼,Action Mailbox 可以使用該密碼進行身份驗證 對 Postmark 入口的請求。

使用 bin/rails credentials:edit 將密碼新增到您的應用程式的 action_mailbox.ingress_password 下的加密憑證, 其中 Action Mailbox 會自動找到它:

action_mailbox:
  ingress_password: ...

或者,在 RAILS_INBOUND_EMAIL_PASSWORD 中提供密碼 環境變數。

配置 Postmark 入站 webhook 使用使用者名稱 actionmailbox 將入站電子郵件轉發到 /rails/action_mailbox/postmark/inbound_emails 以及您之前生成的密碼。如果您的應用程式位於 https://example.com,您將 使用以下完全限定的 URL 配置 Postmark:

https://actionmailbox:PASSWORD@example.com/rails/action_mailbox/postmark/inbound_emails

配置 Postmark 入站 Webhook 時,請務必選中標記為 “在 JSON 有效負載中包含原始電子郵件內容” 的框。 Action Mailbox 需要原始電子郵件內容才能工作。

3.6 Qmail

告訴 Action Mailbox 接受來自 SMTP 中繼的電子郵件:

# 配置/環境/production.rb
config.action_mailbox.ingress = :relay

生成一個強密碼,Action Mailbox 可以用它來驗證對中繼入口的請求。

使用 bin/rails credentials:edit 將密碼新增到您的應用程式的加密憑據下 action_mailbox.ingress_password,其中Action Mailbox會自動找到:

action_mailbox:
  ingress_password: ...

或者,在 RAILS_INBOUND_EMAIL_PASSWORD 環境變數中提供密碼。

配置 Qmail 以透過管道將入站電子郵件傳送到 bin/rails action_mailbox:ingress:qmail, 提供中繼入口的 URLINGRESS_PASSWORD 你 之前生成的。如果您的應用程式位於 https://example.com,則 完整命令如下所示:

$ bin/rails action_mailbox:ingress:qmail URL=https://example.com/rails/action_mailbox/relay/inbound_emails INGRESS_PASSWORD=...

3.7 SendGrid

告訴 Action Mailbox 接受來自 SendGrid 的電子郵件:

# 配置/環境/production.rb
config.action_mailbox.ingress = :sendgrid

生成一個強密碼,Action Mailbox 可以使用該密碼進行身份驗證 對 SendGrid 入口的請求。

使用 bin/rails credentials:edit 將密碼新增到您的應用程式的 action_mailbox.ingress_password 下的加密憑證, 其中 Action Mailbox 會自動找到它:

action_mailbox:
  ingress_password: ...

或者,在 RAILS_INBOUND_EMAIL_PASSWORD 中提供密碼 環境變數。

配置 SendGrid 入站解析 將入站電子郵件轉發到 /rails/action_mailbox/sendgrid/inbound_emails 使用者名稱為 actionmailbox 以及您之前生成的密碼。如果您的應用程式位於 https://example.com, 您將使用以下 URL 配置 SendGrid:

https://actionmailbox:PASSWORD@example.com/rails/action_mailbox/sendgrid/inbound_emails

在配置您的 SendGrid Inbound Parse webhook 時,請務必選中標記為 “釋出原始的完整 MIME 訊息”的框。 Action Mailbox 需要原始 MIME 訊息才能工作。

4 示例

配置基本路由:

# app/mailboxes/application_mailbox.rb
class ApplicationMailbox < ActionMailbox::Base
  routing /^save@/i     => :forwards
  routing /@replies\./i => :replies
end

然後設定郵箱:

# 生成新郵箱
$ bin/rails generate mailbox forwards
# app/mailboxes/forwards_mailbox.rb
class ForwardsMailbox < ApplicationMailbox
  # Callbacks specify prerequisites to processing
  before_processing :require_projects

  def process
    # Record the forward on the one project, or…
    if forwarder.projects.one?
      record_forward
    else
      # …involve a second Action Mailer to ask which project to forward into.
      request_forwarding_project
    end
  end

  private
    def require_projects
      if forwarder.projects.none?
        # Use Action Mailers to bounce incoming emails back to sender – this halts processing
        bounce_with Forwards::BounceMailer.no_projects(inbound_email, forwarder: forwarder)
      end
    end

    def record_forward
      forwarder.forwards.create subject: mail.subject, content: mail.content
    end

    def request_forwarding_project
      Forwards::RoutingMailer.choose_project(inbound_email, forwarder: forwarder).deliver_now
    end

    def forwarder
      @forwarder ||= User.find_by(email_address: mail.from)
    end
end

5 InboundEmail 的焚燒

預設情況下,已成功處理的 InboundEmail 將是 30 天后焚燒。這可確保您不會保留人們的資料 在他們可能已經取消帳戶或刪除他們的 內容。目的是在您處理完電子郵件後,您應該 提取您需要的所有資料並將其轉換為域 models 和內容 在您的應用程式方面。 InboundEmail 只是留在系統中 額外的時間來提供除錯和取證選項。

實際的焚燒是透過預定的 IncinerationJob 完成的 在 config.action_mailbox.incinerate_after 時間後執行。這個 value 是 預設設定為 30.days,但您可以在 production.rb 中更改它 配置。 (請注意,這個遙遠的未來焚燒排程依賴於 您的工作佇列能夠保留那麼長時間的工作。)

6 在開發中使用 Action Mailbox

能夠在開發中測試收到的電子郵件很有幫助,而無需實際 傳送和接收真實的電子郵件。為了做到這一點,有一個指揮家 controller 安裝在 /rails/conductor/action_mailbox/inbound_emails, 它為您提供系統中所有 InboundEmail 的索引,它們的 處理狀態,以及用於建立新 InboundEmail 的表單。

7 測試郵箱

例子:

class ForwardsMailboxTest < ActionMailbox::TestCase
  test "directly recording a client forward for a forwarder and forwardee corresponding to one project" do
    assert_difference -> { people(:david).buckets.first.recordings.count } do
      receive_inbound_email_from_mail \
        to: 'save@example.com',
        from: people(:david).email_address,
        subject: "Fwd: Status update?",
        body: <<~BODY
          --- Begin forwarded message ---
          From: Frank Holland <frank@microsoft.com>

          What's the status?
        BODY
    end

    recording = people(:david).buckets.first.recordings.last
    assert_equal people(:david), recording.creator
    assert_equal "Status update?", recording.forward.subject
    assert_match "What's the status?", recording.forward.content.to_s
  end
end

請參閱 ActionMailbox::TestHelper API 以獲取更多測試輔助方法。

回饋

我們鼓勵您幫助提高本指南的品質。

如果您發現任何拼寫錯誤或資訊錯誤,請提供回饋。 要開始回饋,您可以閱讀我們的 回饋 部分。

您還可能會發現不完整的內容或不是最新的內容。 請務必為 main 新增任何遺漏的文件。假設是 非穩定版指南(edge guides) 請先驗證問題是否已經在主分支上解決。 請前往 Ruby on Rails 指南寫作準則 查看寫作風格和慣例。

如果由於某種原因您發現要修復的內容但無法自行修補,請您 提出 issue

關於 Ruby on Rails 的任何類型的討論歡迎提供任何文件至 rubyonrails-docs 討論區