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

Action Mailer 基礎知識

本指南為您提供開始傳送所需的一切 來自您的應用程式的電子郵件,以及 Action 的許多內部結構 梅勒。它還包括如何測試您的郵件程式。

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

1 什麼是Action Mailer?

Action Mailer 允許您使用郵件程式類從您的應用程式傳送電子郵件 和 views。

1.1 郵件程式類似於 controllers

他們繼承自 ActionMailer::Base 並居住在 app/mailers。郵遞員也工作 與 controllers 非常相似。下面列舉了一些相似之處的例子。 郵寄者有:

  • Action,以及出現在 app/views 中的關聯 views。
  • 可在 views 中訪問的實例變數。
  • 利用佈局和部分的能力。
  • 訪問引數雜湊的能力。

2 傳送電子郵件

本節將提供建立郵件程式及其應用程式的分步指南 views。

2.1 生成郵件程式的演練

2.1.1 建立郵件程式
$ bin/rails generate mailer User
create  app/mailers/user_mailer.rb
create  app/mailers/application_mailer.rb
invoke  erb
create    app/views/user_mailer
create    app/views/layouts/mailer.text.erb
create    app/views/layouts/mailer.html.erb
invoke  test_unit
create    test/mailers/user_mailer_test.rb
create    test/mailers/previews/user_mailer_preview.rb
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  default from: "from@example.com"
  layout 'mailer'
end
# app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
end

如您所見,您可以像使用其他生成器一樣生成郵件程式 導軌。

如果你不想使用生成器,你可以在裡面建立你自己的檔案 app/mailers,只要確保它繼承自 ActionMailer::Base

class MyMailer < ActionMailer::Base
end
2.1.2 編輯郵件

郵件程式具有稱為“actions”的方法,它們使用 views 來構建其內容。 controller 生成 HTML 之類的內容傳送回客戶端,Mailer 建立要透過電子郵件傳遞的訊息。

app/mailers/user_mailer.rb 包含一個空郵件:

class UserMailer < ApplicationMailer
end

讓我們新增一個名為 welcome_email 的方法,它將傳送一封電子郵件到使用者的 註冊郵箱:

class UserMailer < ApplicationMailer
  default from: 'notifications@example.com'

  def welcome_email
    @user = params[:user]
    @url  = 'http://example.com/login'
    mail(to: @user.email, subject: 'Welcome to My Awesome Site')
  end
end

以下是對上述方法中出現的專案的快速說明。為了 所有可用選項的完整列表,請進一步檢視 Action Mailer 使用者可設定屬性部分的完整列表。

  • default 方法為從 這個郵遞員。在這種情況下,我們使用它來為所有設定 :from 標頭 value 這個類中的訊息。這可以在每個電子郵件的基礎上被覆蓋。
  • mail 方法建立實際的電子郵件訊息。我們用它來指定 每封電子郵件的標題的 values,如 :to:subject
2.1.3 建立郵件程式 View

app/views/user_mailer/ 中建立一個名為 welcome_email.html.erb 的檔案。這 將是用於電子郵件的模板,格式為 HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Welcome to example.com, <%= @user.name %></h1>
    <p>
      You have successfully signed up to example.com,
      your username is: <%= @user.login %>.<br>
    </p>
    <p>
      To login to the site, just follow this link: <%= @url %>.
    </p>
    <p>Thanks for joining and have a great day!</p>
  </body>
</html>

讓我們也為這封電子郵件製作一個文字部分。並非所有客戶都喜歡 HTML 電子郵件, 因此傳送兩者是最佳實踐。為此,請建立一個名為 app/views/user_mailer/ 中的 welcome_email.text.erb

Welcome to example.com, <%= @user.name %>
===============================================

You have successfully signed up to example.com,
your username is: <%= @user.login %>.

To login to the site, just follow this link: <%= @url %>.

Thanks for joining and have a great day!

現在呼叫 mail 方法時,Action Mailer 會檢測到這兩個模板 (文字和 HTML)並自動生成 multipart/alternative 電子郵件。

2.1.4 呼叫郵件程式

郵件程式實際上只是呈現 view 的另一種方式。而不是渲染一個 view 並透過 HTTP 協議傳送,他們透過 電子郵件協議。因此,讓您的 controller 告訴 Mailer 在成功建立使用者後傳送電子郵件。

設定它很簡單。

首先,讓我們建立一個 User scaffold:

$ bin/rails generate scaffold user name email login
$ bin/rails db:migrate

現在我們有一個使用者 model 可以玩,我們將編輯 app/controllers/users_controller.rb 檔案,使其指示 UserMailer 投遞 透過編輯建立 action 並插入一個電子郵件給新建立的使用者 成功儲存使用者後立即呼叫 UserMailer.with(user: @user).welcome_email

我們將使用 deliver_later 對要傳送的電子郵件進行排隊,即 由 Active Job 提供支援。這樣,controller action 就可以繼續了 等待發送完成。

class UsersController < ApplicationController
  # ...

  # POST /users or /users.json
  def create
    @user = User.new(user_params)

    respond_to do |format|
      if @user.save
        # Tell the UserMailer to send a welcome email after save
        UserMailer.with(user: @user).welcome_email.deliver_later

        format.html { redirect_to(@user, notice: 'User was successfully created.') }
        format.json { render json: @user, status: :created, location: @user }
      else
        format.html { render action: 'new' }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

  # ...
end

Active Job 的預設行為是透過 :async 介面卡執行作業。 因此,您可以使用 deliver_later 非同步傳送電子郵件。 Active Job 的預設介面卡使用程序內執行緒池執行作業。 它非常適合開發/測試環境,因為它不需要 任何外部基礎設施,但它不適合生產,因為它下降 重新啟動時掛起的作業。 如果你需要一個持久的後端,你將需要使用一個 Active Job 介面卡 具有持久後端(Sidekiq、Resque 等)。

如果您想立即傳送電子郵件(例如從 cronjob),只需致電 deliver_now:

class SendWeeklySummary
  def run
    User.find_each do |user|
      UserMailer.with(user: user).weekly_summary.deliver_now
    end
  end
end

任何傳遞給 with 的 key-value 對都會成為郵件程式的 params action。所以 with(user: @user, account: @user.account) 使 params[:user]params[:account] 在郵件程式 action 中可用。就像 controllers 有 引數。

welcome_email 方法返回一個 ActionMailer::MessageDelivery 物件,該物件 然後可以告訴 deliver_nowdeliver_later 將自己傳送出去。這 ActionMailer::MessageDelivery 物件是 Mail::Message 的包裝器。如果 你想檢查、改變或對 Mail::Message 物件做任何其他事情,你可以 使用 ActionMailer::MessageDelivery 物件上的 message 方法訪問它。

2.2 自動編碼頭 values

Action Mailer 處理內部多位元組字元的自動編碼 標題和正文。

對於更復雜的示例,例如定義替代字符集或 先自編碼文字,請參考 郵件 庫。

2.3 Action Mailer 方法的完整列表

您只需三種方法即可傳送幾乎任何電子郵件 資訊:

  • headers - 指定您想要的電子郵件的任何標題。你可以傳遞一個雜湊 header 欄位名稱和 value 對,或者你可以呼叫 headers[:field_name] = 'value'
  • attachments - 允許您向電子郵件新增附件。例如, attachments['file-name.jpg'] = File.read('file-name.jpg')
  • mail - 建立實際的電子郵件本身。您可以將標頭作為雜湊傳遞給 mail 方法作為引數。 mail 將建立一封電子郵件——要麼是普通的 text 或 multipart — 取決於您定義的電子郵件模板。
2.3.1 新增附件

Action Mailer 可以很容易地新增附件。

  • 傳遞檔名和內容以及 Action Mailer 和 Mail gem 會自動猜測 mime_type,設定encoding,並建立附件。

    attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
    

mail 方法被觸發時,它會發送一個多部分的電子郵件 一個附件,正確巢狀在頂層是 multipart/mixed 和 第一部分是一個 multipart/alternative 包含純文字和 HTML 電子郵件。

Mail 將自動對附件進行 Base64 編碼。如果你想要什麼 不同,編碼您的內容並傳入編碼的內容和編碼 Hashattachments 方法。

  • 傳遞檔名並指定標題和內容以及 Action Mailer 和郵件 將使用您傳入的設定。

    encoded_content = SpecialEncode(File.read('/path/to/filename.jpg'))
    attachments['filename.jpg'] = {
      mime_type: 'application/gzip',
      encoding: 'SpecialEncoding',
      content: encoded_content
    }
    

如果您指定編碼,Mail 將假定您的內容已經 編碼而不是嘗試對它進行 Base64 編碼。

2.3.2 製作內嵌附件

Action Mailer 3.0 製作了內聯附件,這在 3.0 之前的版本中涉及很多駭客攻擊,應該更簡單和瑣碎。

  • 首先,要告訴 Mail 將附件轉換為內嵌附件,您只需在 Mailer 中的附件方法上呼叫 #inline

    def welcome
      attachments.inline['image.jpg'] = File.read('/path/to/image.jpg')
    end
    
  • 然後在您的 view 中,您可以將 attachments 作為雜湊引用並指定 你想顯示哪個附件,在它上面呼叫 url 然後傳遞 結果進入 image_tag 方法:

    <p>Hello there, this is our image</p>
    
    <%= image_tag attachments['image.jpg'].url %>
    
  • 由於這是對 image_tag 的標準呼叫,因此您可以傳入選項雜湊 在附件 URL 之後,就像對任何其他影象一樣:

    <p>Hello there, this is our image</p>
    
    <%= image_tag attachments['image.jpg'].url, alt: 'My Photo', class: 'photos' %>
    
2.3.3 向多個收件人傳送電子郵件

可以在一封電子郵件中向一個或多個收件人傳送電子郵件(例如, 透過將電子郵件列表設定為 :to 來通知所有管理員新註冊 key。電子郵件列表可以是一組電子郵件地址或單個字串 地址用逗號分隔。

class AdminMailer < ApplicationMailer
  default to: -> { Admin.pluck(:email) },
          from: 'notification@example.com'

  def new_registration(user)
    @user = user
    mail(subject: "New User Signup: #{@user.email}")
  end
end

相同的格式可用於設定抄送(Cc:)和密送 (Bcc:) 收件人,分別使用 :cc:bcc keys。

2.3.4 傳送帶有姓名的電子郵件

有時您希望顯示此人的姓名而不僅僅是他們的電子郵件 他們收到電子郵件時的地址。您可以使用 email_address_with_name 用於 那:

def welcome_email
  @user = params[:user]
  mail(
    to: email_address_with_name(@user.email, @user.name),
    subject: 'Welcome to My Awesome Site'
  )
end

2.4 郵件程式 Views

郵件程式 views 位於 app/views/name_of_mailer_class 目錄中。這 特定的郵件程式 view 是類已知的,因為它的名稱與 郵寄方式。在我們上面的例子中,我們的郵件程式 view 用於 welcome_email 方法將在 app/views/user_mailer/welcome_email.html.erb 中 HTML 版本和 welcome_email.text.erb 純文字版本。

要為您的 action 更改預設郵件程式 view,您可以執行以下操作:

class UserMailer < ApplicationMailer
  default from: 'notifications@example.com'

  def welcome_email
    @user = params[:user]
    @url  = 'http://example.com/login'
    mail(to: @user.email,
         subject: 'Welcome to My Awesome Site',
         template_path: 'notifications',
         template_name: 'another')
  end
end

在這種情況下,它將在 app/views/notifications 處尋找具有名稱的模板 another。您還可以為 template_path 指定一組路徑,它們 將按順序搜尋。

如果你想要更多的靈活性,你也可以傳遞一個塊並渲染特定的 模板,甚至在不使用模板檔案的情況下呈現內聯或文字:

class UserMailer < ApplicationMailer
  default from: 'notifications@example.com'

  def welcome_email
    @user = params[:user]
    @url  = 'http://example.com/login'
    mail(to: @user.email,
         subject: 'Welcome to My Awesome Site') do |format|
      format.html { render 'another_template' }
      format.text { render plain: 'Render text' }
    end
  end
end

這將為 HTML 部分呈現模板“another_template.html.erb”和 將渲染的文字用於文字部分。渲染命令與使用的相同 在 Action Controller 裡面,所以你可以使用所有相同的選項,比如 :text:inline

如果您想渲染位於預設 app/views/mailer_name/ 目錄之外的模板,您可以應用 prepend_view_path,如下所示:

class UserMailer < ApplicationMailer
  prepend_view_path "custom/path/to/mailer/view"

  # This will try to load "custom/path/to/mailer/view/welcome_email" template
  def welcome_email
    # ...
  end
end

您也可以考慮使用 append_view_path 方法。

2.4.1 快取郵件程式 view

您可以使用 cache 方法在郵件程式 views 中執行片段快取,就像在應用程式 views 中一樣。

<% cache do %>
  <%= @company.name %>
<% end %>

要使用此功能,您需要使用以下內容配置您的應用程式:

config.action_mailer.perform_caching = true

多部分電子郵件也支援片段快取。 在 Rails 快取指南 中閱讀有關快取的更多資訊。

2.5 Action Mailer 佈局

就像 controller views 一樣,您也可以擁有郵件程式佈局。佈局名稱 需要與您的郵寄者相同,例如 user_mailer.html.erbuser_mailer.text.erb 被您的郵寄者自動識別為 佈局。

要使用不同的檔案,請在郵件中呼叫 layout:

class UserMailer < ApplicationMailer
  layout 'awesome' # use awesome.(html|text).erb as the layout
end

就像使用 controller views 一樣,使用 yield 在內部渲染檢視 佈局。

您還可以將 layout: 'layout_name' 選項傳遞給內部的渲染呼叫 用於為不同格式指定不同佈局的格式塊:

class UserMailer < ApplicationMailer
  def welcome_email
    mail(to: params[:user].email) do |format|
      format.html { render layout: 'my_layout' }
      format.text
    end
  end
end

將使用 my_layout.html.erb 檔案和文字部分呈現 HTML 部分 使用通常的 user_mailer.text.erb 檔案(如果存在)。

2.6 Previewing 電子郵件

Action Mailer previews 提供了一種透過訪問 呈現它們的特殊 URL。在上面的例子中, preview 類用於 UserMailer 應命名為 UserMailerPreview 並位於 test/mailers/previews/user_mailer_preview.rb。檢視 preview 的 welcome_email,實現一個同名的方法並呼叫 UserMailer.welcome_email

class UserMailerPreview < ActionMailer::Preview
  def welcome_email
    UserMailer.with(user: User.first).welcome_email
  end
end

然後 preview 將在 http://localhost:3000/rails/mailers/user_mailer/welcome_email 中可用。

如果您更改了 app/views/user_mailer/welcome_email.html.erb 中的某些內容 或郵件程式本身,它會自動重新載入並呈現它,以便您可以 視覺上立即看到新的風格。還提供了 previews 的列表 在 http://localhost:3000/rails/mailers 中。

預設情況下,這些 preview 類位於 test/mailers/previews 中。 這可以使用 preview_path 選項進行配置。例如,如果你 想改成lib/mailer_previews,可以在裡面配置 config/application.rb

config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"

2.7 在 Action Mailer View 中生成 URL

與 controllers 不同,郵件程式實例沒有關於 傳入請求,因此您需要自己提供 :host 引數。

由於 :host 通常在整個應用程式中是一致的,您可以對其進行配置 全域性在 config/application.rb

config.action_mailer.default_url_options = { host: 'example.com' }

由於這種行為,您不能在其中使用任何 *_path helpers 一封電郵。相反,您需要使用關聯的 *_url helper。例如 而不是使用

<%= link_to 'welcome', welcome_path %>

您將需要使用:

<%= link_to 'welcome', welcome_url %>

透過使用完整的 URL,您的連結現在可以在您的電子郵件中使用。

2.7.1 使用 url_for 生成 URL

url_for 預設在模板中生成完整的 URL。

如果您沒有全域性配置 :host 選項,請確保將其傳遞給 url_for

<%= url_for(host: 'example.com',
            controller: 'welcome',
            action: 'greeting') %>
2.7.2 使用命名路由生成 URL

電子郵件客戶端沒有 Web 上下文,因此路徑沒有基本 URL 來形成完整 網址。因此,您應該始終使用命名路由的 *_url 變體 helpers。

如果您沒有全域性配置 :host 選項,請確保將其傳遞給 網址 helper。

<%= user_url(@user, host: 'example.com') %>

GET 連結需要 rails-ujsjQuery UJS,在郵件模板中不起作用。 它們將導致正常的 GET 請求。

2.8 在 Action Mailer View 中新增影象

與 controllers 不同,郵件程式實例沒有關於 傳入請求,因此您需要自己提供 :asset_host 引數。

由於 :asset_host 通常在整個應用程式中是一致的,您可以 在 config/application.rb 中全域性配置它:

config.asset_host = 'http://example.com'

現在您可以在電子郵件中顯示影象。

<%= image_tag 'image.jpg' %>

2.9 傳送多部分郵件

Action Mailer 將自動傳送多部分電子郵件,如果您有不同的 相同 action 的模板。因此,對於我們的 UserMailer 示例,如果您有 welcome_email.text.erbwelcome_email.html.erbapp/views/user_mailer, Action Mailer 會自動傳送多部分郵件 將 HTML 和文字版本設定為不同的部分。

零件插入的順序由 :parts_order 決定 ActionMailer::Base.default 方法內部。

2.10 使用動態傳遞選項傳送電子郵件

如果您希望覆蓋預設傳送選項(例如 SMTP 憑據) 在傳送電子郵件時,您可以使用 delivery_method_options 在 郵寄者 action。

class UserMailer < ApplicationMailer
  def welcome_email
    @user = params[:user]
    @url  = user_url(@user)
    delivery_options = { user_name: params[:company].smtp_user,
                         password: params[:company].smtp_password,
                         address: params[:company].smtp_host }
    mail(to: @user.email,
         subject: "Please see the Terms and Conditions attached",
         delivery_method_options: delivery_options)
  end
end

2.11 傳送沒有模板渲染的電子郵件

在某些情況下,您可能希望跳過模板渲染步驟並 以字串形式提供電子郵件正文。您可以使用 :body 實現此目的 選項。在這種情況下,不要忘記新增 :content_type 選項。導軌 否則將預設為 text/plain

class UserMailer < ApplicationMailer
  def welcome_email
    mail(to: params[:user].email,
         body: params[:email_body],
         content_type: "text/html",
         subject: "Already rendered!")
  end
end

3 Action Mailer Callbacks

Action Mailer 允許您指定 before_actionafter_actionaround_action

  • 過濾器可以透過塊或 symbol 指定給郵件程式中的方法 類類似於 controllers。

  • 您可以使用 before_action 來設定實例變數,填充郵件 帶有預設值的物件,或插入預設標題和附件。

class InvitationsMailer < ApplicationMailer
  before_action :set_inviter_and_invitee
  before_action { @account = params[:inviter].account }

  default to:       -> { @invitee.email_address },
          from:     -> { common_address(@inviter) },
          reply_to: -> { @inviter.email_address_with_name }

  def account_invitation
    mail subject: "#{@inviter.name} invited you to their Basecamp (#{@account.name})"
  end

  def project_invitation
    @project    = params[:project]
    @summarizer = ProjectInvitationSummarizer.new(@project.bucket)

    mail subject: "#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"
  end

  private

  def set_inviter_and_invitee
    @inviter = params[:inviter]
    @invitee = params[:invitee]
  end
end
  • 您可以使用 after_action 進行與 before_action 類似的設定,但 使用在您的郵件程式 action 中設定的實例變數。

  • 使用 after_action callback 還可以讓您覆蓋交付方式 透過更新 mail.delivery_method.settings 設定。

class UserMailer < ApplicationMailer
  before_action { @business, @user = params[:business], params[:user] }

  after_action :set_delivery_options,
               :prevent_delivery_to_guests,
               :set_business_headers

  def feedback_message
  end

  def campaign_message
  end

  private

    def set_delivery_options
      # You have access to the mail instance,
      # @business and @user instance variables here
      if @business && @business.has_smtp_settings?
        mail.delivery_method.settings.merge!(@business.smtp_settings)
      end
    end

    def prevent_delivery_to_guests
      if @user && @user.guest?
        mail.perform_deliveries = false
      end
    end

    def set_business_headers
      if @business
        headers["X-SMTPAPI-CATEGORY"] = @business.code
      end
    end
end
  • 如果正文設定為非零的 value,郵件過濾器會中止進一步的處理。

4 使用 Action Mailer Helpers

Action Mailer 繼承自 AbstractController,因此您可以訪問大多數 與您在 Action Controller 中相同的 helpers。

還有一些 Action Mailer 特定的 helper 方法可用 ActionMailer::MailHelper。例如,這些允許訪問郵件程式 使用 mailer 從您的 view 實例,並以 message 訪問郵件:

<%= stylesheet_link_tag mailer.name.underscore %>
<h1><%= message.subject %></h1>

5 Action Mailer 配置

以下配置選項最好在其中一種環境中進行 檔案(environment.rb、production.rb 等...)

配置 說明
logger 如果可用,生成有關郵件執行的資訊。可以設定為 nil 不記錄。與 Ruby 自己的 LoggerLog4r 記錄器相容。
smtp_settings 允許詳細配置 :smtp 傳送方法:
  • :address - 允許您使用遠端郵件伺服器。只需將其從預設的 "localhost" 設定更改即可。
  • :port - 如果您的郵件伺服器不在埠 25 上執行,您可以更改它。
  • :domain - 如果您需要指定 HELO 域,您可以在此處進行。
  • :user_name - 如果您的郵件伺服器需要身份驗證,請在此設定中設定使用者名稱。
  • :password - 如果您的郵件伺服器需要身份驗證,請在此設定中設定密碼。
  • :authentication - 如果您的郵件伺服器需要身份驗證,則需要在此處指定身份驗證型別。這是一個 symbol 和 :plain(將以明文形式傳送密碼)、:login(將傳送 Base64 編碼的密碼)或 :cram_md5(結合挑戰/回應機制來交換資訊和加密訊息摘要 5 演算法來雜湊重要資訊)之一
  • :enable_starttls_auto - 檢測您的 SMTP 伺服器中是否啟用了 STARTTLS 並開始使用它。預設為 true
  • :openssl_verify_mode - 使用 TLS 時,您可以設定 OpenSSL 檢查證書的方式。如果您需要驗證自簽名和/或萬用字元證書,這非常有用。您可以使用 OpenSSL 驗證常量的名稱(“none”或“peer”)或直接使用常量(OpenSSL::SSL::VERIFY_NONEOpenSSL::SSL::VERIFY_PEER)。
  • :ssl/:tls - 啟用 SMTP 連線以使用 SMTP/TLS(SMTPS:透過直接 TLS 連線的 SMTP)
  • :open_timeout - 嘗試開啟連線時等待的秒數。
  • :read_timeout - 等待讀取超時的秒數(2)
sendmail_settings 允許您覆蓋 :sendmail 傳送方法的選項。
  • :location - sendmail 可執行檔案的位置。預設為 /usr/sbin/sendmail
  • :arguments - 要傳遞給 sendmail 的命令列引數。預設為 -i
raise_delivery_errors 郵件傳送失敗時是否報錯。這僅在外部電子郵件伺服器配置為立即交付時才有效。
delivery_method 定義交付方式。可能的 values 有:
  • :smtp(預設),可以使用 config.action_mailer.smtp_settings 進行配置。
  • ActionMailer,可以使用 config.action_mailer.sendmail_settings 進行配置。
  • :file:儲存電子郵件檔案;可以使用 config.action_mailer.file_settings 進行配置。
  • :test:將電子郵件儲存到 ActionMailer::Base.deliveries 陣列。
請參閱 API 文件 瞭解更多資訊。
perform_deliveries 確定在對郵件訊息呼叫 deliver 方法時是否實際執行傳遞。預設情況下它們是,但可以將其關閉以幫助功能測試。如果此 value 是 false,則即使 delivery_method:test,也不會填充 deliveries 陣列。
deliveries 使用delivery_method :test 儲存透過Action Mailer 傳送的所有電子郵件的陣列。對單元和功能測試最有用。
default_options 允許您為 mail 方法選項(:from:reply_to 等)設定預設的 values。

有關可能配置的完整記錄,請參閱 配置Action Mailer 在 我們的配置 Rails 應用程式指南。

5.1 示例 Action Mailer 配置

一個例子是將以下內容新增到您適當的 config/environments/$RAILS_ENV.rb 檔案:

config.action_mailer.delivery_method = :sendmail
# 預設為:
# config.action_mailer.sendmail_settings = {
# location: '/usr/sbin/sendmail',
# 引數:'-i'
# }
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_options = {from: 'no-reply@example.com'}

5.2 Action Mailer Gmail 的配置

Action Mailer 使用 Mail gem 並接受類似的配置。 將此新增到您的 config/environments/$RAILS_ENV.rb 檔案以透過 Gmail 傳送:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address:              'smtp.gmail.com',
  port:                 587,
  domain:               'example.com',
  user_name:            '<username>',
  password:             '<password>',
  authentication:       'plain',
  enable_starttls_auto: true,
  open_timeout:         5,
  read_timeout:         5 }

2014 年 7 月 15 日,Google 增加了其安全措施 以阻止來自它認為不太安全的應用程式的嘗試。 您可以 此處 更改 Gmail 設定以允許嘗試。如果您的 Gmail 帳戶啟用了 2 因素身份驗證, 那麼您需要設定一個 應用密碼 並使用它來代替您的正常密碼。

6 郵件測試

您可以在 測試指南

7 攔截和觀察電子郵件

Action Mailer 提供了到郵件觀察器和攔截器方法的掛載機制。這些允許您註冊在傳送的每封電子郵件的郵件傳遞生命週期中呼叫的類。

7.1 攔截郵件

攔截器允許您在將電子郵件交給遞送代理之前對其進行修改。攔截器類必須實現 ::delivering_email(message) 方法,該方法將在傳送電子郵件之前呼叫。

class SandboxEmailInterceptor
  def self.delivering_email(message)
    message.to = ['sandbox@example.com']
  end
end

在攔截器完成其工作之前,您需要使用 interceptors 配置選項註冊它。 您可以在像 config/initializers/mail_interceptors.rb 這樣的初始化檔案中執行此操作:

Rails.application.configure do
  if Rails.env.staging?
    config.action_mailer.interceptors = %w[SandboxEmailInterceptor]
  end
end

上面的示例使用名為“staging”的自定義環境 類似生產的伺服器,但用於測試目的。你可以閱讀 建立 Rails 環境 有關自定義 Rails 環境的更多資訊。

7.2 觀察郵件

觀察者允許您在傳送電子郵件後訪問該電子郵件。觀察者類必須實現 :delivered_email(message) 方法,該方法將在傳送電子郵件後呼叫。

class EmailDeliveryObserver
  def self.delivered_email(message)
    EmailDelivery.log(message)
  end
end

與攔截器類似,您必須使用 observers 配置選項註冊觀察者。 您可以在像 config/initializers/mail_observers.rb 這樣的初始化檔案中執行此操作:

Rails.application.configure do
  config.action_mailer.observers = %w[EmailDeliveryObserver]
end

回饋

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

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

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

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

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