Action Mailer 基礎
Action Mailer 讓你可以使用郵件模型和檢視從應用程式傳送電子郵件。
郵件模型
若要使用 Action Mailer,你需要建立一個郵件模型。
$ bin/rails generate mailer Notifier
產生的模型繼承自 ApplicationMailer
,而 ApplicationMailer
又繼承自 ActionMailer::Base
。郵件模型定義用於產生電子郵件訊息的方法。在這些方法中,你可以設定要在郵件檢視中使用的變數、郵件本身的選項(例如 :from
位址)和附件。
class ApplicationMailer < ActionMailer::Base
default from: '[email protected]'
layout 'mailer'
end
class NotifierMailer < ApplicationMailer
default from: '[email protected]',
return_path: '[email protected]'
def welcome(recipient)
@account = recipient
mail(to: recipient.email_address_with_name,
bcc: ["[email protected]", "Order Watcher <[email protected]>"])
end
end
在郵件方法中,你可以存取下列方法
-
attachments[]=
- 允許你以直覺的方式將附件新增到電子郵件中;attachments['filename.png'] = File.read('path/to/filename.png')
-
attachments.inline[]=
- 允許你以與attachments[]=
相同的方式將內嵌附件新增到電子郵件中 -
headers[]=
- 允許你指定電子郵件中的任何標頭欄位,例如headers['X-No-Spam'] = 'True'
。請注意,多次宣告標頭會新增許多具有相同名稱的欄位。請參閱headers
文件以取得更多資訊。 -
headers(hash)
- 允許你指定電子郵件中的多個標頭,例如headers({'X-No-Spam' => 'True', 'In-Reply-To' => '[email protected]'})
-
mail
- 允許你指定要傳送的電子郵件。
傳遞給郵件方法的雜湊允許你指定 Mail::Message
會接受的任何標頭(任何有效的電子郵件標頭,包括選用欄位)。
如果未傳遞區塊給 mail
方法,它會檢查你的檢視並傳送所有與方法同名的檢視,因此上述動作會傳送 welcome.text.erb
檢視檔案,以及 welcome.html.erb
檢視檔案,並以 multipart/alternative
電子郵件傳送。
如果你只想明確呈現某些範本,請傳遞區塊
mail(to: user.email) do |format|
format.text
format.html
end
區塊語法在提供特定部分的資訊時也很有用
mail(to: user.email) do |format|
format.text(content_transfer_encoding: "base64")
format.html
end
甚至可以呈現特殊檢視
mail(to: user.email) do |format|
format.text
format.html { render "some_other_template" }
end
郵件檢視
就像 Action Controller,每個郵件類別都有對應的檢視目錄,類別中的每個方法都在其中尋找具有其名稱的範本。
若要定義要與郵件一起使用的範本,請建立一個 .erb
檔案,其名稱與郵件模型中的方法相同。例如,在上面定義的郵件中,app/views/notifier_mailer/welcome.text.erb
的範本將用於產生電子郵件。
在郵件模型的方法中定義的變數可以在其對應的檢視中作為實例變數存取。
預設情況下,電子郵件會以純文字傳送,因此我們模型範例的範本範例可能如下所示
Hi <%= @account.name %>,
Thanks for joining our service! Please check back often.
您甚至可以在這些檢視中使用 Action View 輔助程式。例如
You got a new note!
<%= truncate(@note.body, length: 25) %>
如果您需要在檢視中存取主旨、寄件者或收件者,您可以透過訊息物件來執行此操作
You got a new note from <%= message.from %>!
<%= truncate(@note.body, length: 25) %>
產生網址
可以使用 url_for
或命名路由在郵件檢視中產生網址。與 Action Pack 的控制器不同,郵件實例沒有任何關於傳入要求的內容,因此您需要提供產生網址所需的所有詳細資料。
當使用 url_for
時,您需要提供 :host
、:controller
和 :action
<%= url_for(host: "example.com", controller: "welcome", action: "greeting") %>
當使用命名路由時,您只需要提供 :host
<%= users_url(host: "example.com") %>
您應該使用 named_route_url
樣式(產生絕對網址),並避免使用 named_route_path
樣式(產生相對網址),因為閱讀郵件的客戶端將無法知道當前網址,因此無法決定相對路徑。
也可以透過在 config/application.rb
中將 :host
選項設定為組態選項,來設定所有郵件中將使用的預設主機。
config.action_mailer.default_url_options = { host: "example.com" }
您也可以在個別郵件中定義 default_url_options
方法,以覆寫每個郵件的這些預設設定。
預設情況下,當 config.force_ssl
為 true
時,為主機產生的網址將使用 HTTPS 協定。
傳送郵件
定義郵件動作和範本後,您可以傳送您的訊息或延後其建立和傳送的時間
NotifierMailer.welcome(User.first).deliver_now # sends the email
mail = NotifierMailer.welcome(User.first) # => an ActionMailer::MessageDelivery object
mail.deliver_now # generates and sends the email now
ActionMailer::MessageDelivery
類別是包覆在委派器中的包裝器,它會呼叫您的方法來產生郵件。如果您想要直接存取委派器或 Mail::Message
,您可以呼叫 ActionMailer::MessageDelivery
物件上的 message
方法。
NotifierMailer.welcome(User.first).message # => a Mail::Message object
Action Mailer 與 Active Job 很好地整合,因此您可以在背景中產生並傳送電子郵件(範例:在要求回應循環之外,因此使用者不必等待)。
NotifierMailer.welcome(User.first).deliver_later # enqueue the email sending to Active Job
請注意,deliver_later
會從背景工作執行您的方法。
您永遠不會實例化您的郵件寄送器類別。相反地,您只要呼叫您在類別本身定義的方法即可。所有實例方法預期會傳回要傳送的訊息物件。
多部分電子郵件
多部分訊息也可以隱含地使用,因為 Action Mailer 會自動偵測並使用多部分範本,其中每個範本都以動作的名稱命名,後接內容類型。每個偵測到的範本都會新增到訊息中,作為一個獨立的部分。
例如,如果存在下列範本
-
signup_notification.text.erb
-
signup_notification.html.erb
-
signup_notification.xml.builder
-
signup_notification.yml.erb
每個範本都會被渲染並新增到訊息中,作為一個獨立的部分,並具有對應的內容類型。整個訊息的內容類型會自動設定為 multipart/alternative
,這表示電子郵件包含同一電子郵件主體的多個不同表示。在動作中定義的相同實例變數會傳遞給所有電子郵件範本。
如果已將任何附件或部分新增到電子郵件,則不會執行隱含範本渲染。這表示您必須手動將每個部分新增到電子郵件,並將電子郵件的內容類型設定為 multipart/alternative
。
附件
在電子郵件中傳送附件很簡單
class NotifierMailer < ApplicationMailer
def welcome(recipient)
attachments['free_book.pdf'] = File.read('path/to/file.pdf')
mail(to: recipient, subject: "New account information")
end
end
如果在檢視目錄中有 welcome.text.erb
和 welcome.html.erb
範本,則會傳送一個完整的 multipart/mixed
電子郵件,其中包含兩個部分,第一個部分是包含文字和 HTML 電子郵件部分的 multipart/alternative
,第二個部分是包含 file.pdf 檔案的 Base64 編碼副本的 application/pdf
,檔案名稱為 free_book.pdf
。
如果您需要傳送沒有內容的附件,您需要為其建立一個空的檢視,或新增一個空的 body 參數,如下所示
class NotifierMailer < ApplicationMailer
def welcome(recipient)
attachments['free_book.pdf'] = File.read('path/to/file.pdf')
mail(to: recipient, subject: "New account information", body: "")
end
end
您也可以傳送包含 HTML 範本的附件,在這種情況下,您需要新增 body、附件和自訂內容類型,如下所示
class NotifierMailer < ApplicationMailer
def welcome(recipient)
attachments["free_book.pdf"] = File.read("path/to/file.pdf")
mail(to: recipient,
subject: "New account information",
content_type: "text/html",
body: "<html><body>Hello there</body></html>")
end
end
內嵌附件
您也可以指定檔案應與其他 HTML 內嵌顯示。如果您想要顯示公司標誌或照片,這會很有用。
class NotifierMailer < ApplicationMailer
def welcome(recipient)
attachments.inline['photo.png'] = File.read('path/to/photo.png')
mail(to: recipient, subject: "Here is what we look like")
end
end
然後,若要在檢視中參照圖像,請建立一個 welcome.html.erb
檔案,並呼叫 image_tag
,傳入要顯示的附件,然後呼叫附件上的 url
以取得圖像來源的相對內容 ID 路徑
<h1>Please Don't Cringe</h1>
<%= image_tag attachments['photo.png'].url -%>
由於我們使用 Action View 的 image_tag
方法,因此您可以傳入任何想要的其他選項
<h1>Please Don't Cringe</h1>
<%= image_tag attachments['photo.png'].url, alt: 'Our Photo', class: 'photo' -%>
觀察和攔截郵件
Action Mailer 提供掛鉤至 Mail
觀察者和攔截器方法。這些方法允許您註冊在郵件傳遞生命週期中會被呼叫的類別。
觀察者類別必須實作 :delivered_email(message)
方法,此方法會在郵件發送後針對每封已發送的郵件呼叫一次。
攔截器類別必須實作 :delivering_email(message)
方法,此方法會在郵件發送之前呼叫,讓您可以在郵件送達傳遞代理之前修改郵件。您的類別應直接對傳入的 Mail::Message
實例進行任何必要的修改。
預設雜湊
Action Mailer 為您的電子郵件提供一些智慧型預設值,這些預設值通常在類別定義內的預設方法中指定
class NotifierMailer < ApplicationMailer
default sender: '[email protected]'
end
您可以傳入 Mail::Message
接受的任何標頭值。ActionMailer::Base
開箱即用時會設定下列內容
-
mime_version: "1.0"
-
charset: "UTF-8"
-
content_type: "text/plain"
-
parts_order: [ "text/plain", "text/enriched", "text/html" ]
parts_order
和 charset
實際上並非有效的 Mail::Message
標頭欄位,但 Action Mailer 會適當地轉譯它們並設定正確的值。
由於您可以傳入任何標頭,因此您需要將標頭作為字串引用,或將其作為底線符號傳入,因此下列內容會運作
class NotifierMailer < ApplicationMailer
default 'Content-Transfer-Encoding' => '7bit',
content_description: 'This is a description'
end
最後,Action Mailer 也支援將 Proc
和 Lambda
物件傳入預設雜湊,因此您可以定義在訊息產生時評估的方法
class NotifierMailer < ApplicationMailer
default 'X-Special-Header' => Proc.new { my_method }, to: -> { @inviter.email_address }
private
def my_method
'some complex call'
end
end
請注意,proc/lambda 會在郵件訊息產生的一開始就評估,因此如果您使用 proc 在預設雜湊中設定某個項目,然後在郵件程式方法中設定相同的項目,它會被郵件程式方法覆寫。
也可以透過 config/application.rb
中的 default_options=
組態設定這些預設選項,這些選項會用於所有郵件程式中
config.action_mailer.default_options = { from: "[email protected]" }
回呼
您可以使用 before_action
和 after_action
指定回呼來設定您的訊息,並使用 before_deliver
和 after_deliver
來包裝傳遞程序。例如,當您想要為某個郵件程式類別所發送的所有訊息新增預設內嵌附件和記錄傳遞時
class NotifierMailer < ApplicationMailer
before_action :add_inline_attachment!
after_deliver :log_delivery
def welcome
mail
end
private
def add_inline_attachment!
attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
end
def log_delivery
Rails.logger.info "Sent email with message id '#{message.message_id}' at #{Time.current}."
end
end
Action Mailer 中的動作回呼是使用 AbstractController::Callbacks
實作的,因此您可以使用與在繼承自 ActionController::Base
的類別中使用回呼相同的方式來定義和設定回呼。
請注意,除非您有特定理由這樣做,否則您應該偏好於在 Action Mailer 類別中使用 before_action
而不是 after_action
,以便正確地解析標頭。
救援錯誤
郵件程式方法中的 rescue
區塊無法救援發生在呈現之外的錯誤,例如背景工作中的記錄反序列化錯誤,或來自第三方郵件傳遞服務的錯誤。
若要救援在郵件處理的任何部分中發生的錯誤,請使用 rescue_from
class NotifierMailer < ApplicationMailer
rescue_from ActiveJob::DeserializationError do
# ...
end
rescue_from "SomeThirdPartyService::ApiError" do
# ...
end
def notify(recipient)
mail(to: recipient, subject: "Notification")
end
end
預覽電子郵件
您可以透過將郵件程式預覽檔案新增到 ActionMailer::Base.preview_paths
,以視覺方式預覽您的電子郵件範本。由於大多數電子郵件會對資料庫資料進行一些有趣的處理,因此您需要撰寫一些場景來載入具有虛假資料的訊息
class NotifierMailerPreview < ActionMailer::Preview
def welcome
NotifierMailer.welcome(User.first)
end
end
方法必須傳回一個 Mail::Message
物件,該物件可以透過呼叫郵件程式方法而產生,而不需要額外的 deliver_now
/ deliver_later
。郵件程式預覽目錄的位置可以使用 preview_paths
選項進行設定,其預設值為 test/mailers/previews
config.action_mailer.preview_paths << "#{Rails.root}/lib/mailer_previews"
在執行中的開發伺服器執行個體上,可以在 http://localhost:3000/rails/mailers
存取所有預覽的概觀。
Previews
也可以透過類似於傳遞的方式攔截,方法是註冊具有 previewing_email
方法的預覽攔截器
class CssInlineStyler
def self.previewing_email(message)
# inline CSS styles
end
end
config.action_mailer.preview_interceptors :css_inline_styler
請注意,如果攔截器要在傳送和預覽電子郵件時執行,則需要使用 register_interceptor
和 register_preview_interceptor
註冊攔截器。
設定選項
這些選項是在類別層級上指定的,例如 ActionMailer::Base.raise_delivery_errors = true
-
default_options
- 您可以根據上述部分在類別層級以及類別本身中傳入此選項。 -
logger
- 若可用,則記錄器用於產生郵件執行資訊。可設定為nil
以不記錄。相容於 Ruby 自有的Logger
和 Log4r 記錄器。 -
smtp_settings
- 允許對:smtp
傳送方法進行詳細設定-
:address
- 允許您使用遠端郵件伺服器。只需將其從預設的「localhost」設定變更即可。 -
:port
- 您的郵件伺服器若未執行於埠 25,則可變更。 -
:domain
- 若您需要指定 HELO 網域,則可在此處執行。 -
:user_name
- 若您的郵件伺服器需要驗證,請在此設定中設定使用者名稱。 -
:password
- 若您的郵件伺服器需要驗證,請在此設定中設定密碼。 -
:authentication
- 若您的郵件伺服器需要驗證,則您需要在此處指定驗證類型。這是一個符號,且為:plain
(將以 Base64 編碼傳送密碼)、:login
(將以 Base64 編碼傳送密碼)或:cram_md5
(結合挑戰/回應機制以交換資訊和加密訊息Digest
5 演算法以雜湊重要資訊)之一 -
:enable_starttls
- 連線至您的 SMTP 伺服器時使用 STARTTLS,且若不支援則會失敗。預設為false
。需要Mail
範例程式碼的 2.7 以上版本。 -
:enable_starttls_auto
- 偵測您的 SMTP 伺服器中是否啟用 STARTTLS,並開始使用它。預設為true
。 -
:openssl_verify_mode
- 使用 TLS 時,您可以設定 OpenSSL 如何檢查憑證。若您需要驗證自簽署和/或萬用字元憑證,這非常有用。您可以使用 OpenSSL 驗證常數的名稱('none'
或'peer'
)或直接使用常數(OpenSSL::SSL::VERIFY_NONE
或OpenSSL::SSL::VERIFY_PEER
)。 -
:ssl/:tls
啟用 SMTP 連線以使用 SMTP/TLS(SMTPS:透過直接 TLS 連線的 SMTP) -
:open_timeout
嘗試開啟連線時等待的秒數。 -
:read_timeout
讀取 (read(2)) 呼叫逾時前的等待秒數。
-
-
sendmail_settings
- 允許您覆寫:sendmail
傳送方法的選項。-
:location
- sendmail 可執行檔的位置。預設為/usr/sbin/sendmail
。 -
:arguments
- 命令列引數。預設為%w[ -i ]
,其中-f sender@address
會在傳送訊息前自動新增。
-
-
file_settings
- 允許您覆寫:file
傳送方法的選項。-
:location
- 將寫入電子郵件的目錄。預設為應用程式tmp/mails
。
-
-
raise_delivery_errors
- 如果電子郵件無法傳送,是否應產生錯誤。 -
delivery_method
- 定義傳送方式。可能的數值為:smtp
(預設值)、:sendmail
、:test
和:file
。或者,您可以提供自訂傳送方式物件,例如MyOwnDeliveryMethodClass
。請參閱Mail
範例文件,了解自訂傳送代理程式需要實作的介面。 -
perform_deliveries
- 決定當您在電子郵件訊息或 Action Mailer 方法上呼叫.deliver
時,是否實際從 Action Mailer 傳送電子郵件。預設為開啟,但可以關閉以協助功能測試。 -
deliveries
- 保留透過 Action Mailer 傳送的所有電子郵件陣列,其中delivery_method :test
。最適合單元和功能測試。 -
delivery_job
- 與deliver_later
一起使用的作業類別。郵件程式可以設定此設定項以使用自訂傳送作業。預設為ActionMailer::MailDeliveryJob
。 -
deliver_later_queue_name
-deliver_later
使用的佇列名稱,其中delivery_job
為預設值。郵件程式可以設定此設定項以使用自訂佇列名稱。
- A
- C
- D
- E
- H
- M
- N
- R
- S
- U
- ActionMailer::Callbacks
- ActionMailer::DeliveryMethods
- ActionMailer::QueuedDelivery
- ActionMailer::Rescuable
- ActionMailer::Parameterized
- ActionMailer::Previews
- ActionMailer::FormBuilder
- AbstractController::Rendering
- AbstractController::Helpers
- AbstractController::Translation
- AbstractController::Callbacks
- AbstractController::Caching
- ActionView::Layouts
常數
PROTECTED_IVARS | = | AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [:@_action_has_layout] |
屬性
[W] | 郵件程式名稱 | 允許設定目前郵件發送器的名稱。 |
類別公共方法
default(value = nil) 連結
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 582 def default(value = nil) self.default_params = default_params.merge(value).freeze if value default_params end
default_options=(value = nil) 連結
允許透過應用程式設定來設定預設值
config.action_mailer.default_options = { from: "[email protected]" }
email_address_with_name(address, name) 連結
傳回格式為「Name <[email protected]>」的電子郵件。
如果名稱是空白字串,則只傳回位址。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 607 def email_address_with_name(address, name) Mail::Address.new.tap do |builder| builder.address = address builder.display_name = name.presence end.to_s end
mailer_name() 連結
傳回目前郵件發送器的名稱。此方法也用作檢視查詢的路徑。如果這是匿名郵件發送器,則此方法將傳回 anonymous
。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 570 def mailer_name @mailer_name ||= anonymous? ? "anonymous" : name.underscore end
new() 連結
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 644 def initialize super() @_mail_was_called = false @_message = Mail.new end
register_interceptor(interceptor) 連結
註冊一個攔截器,它會在郵件發送之前被呼叫。可以傳入攔截器作為類別、字串或符號。如果傳入字串或符號,它將被駝峰化並常數化。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 547 def register_interceptor(interceptor) Mail.register_interceptor(observer_class_for(interceptor)) end
register_interceptors(*interceptors) 連結
註冊一個或多個攔截器,這些攔截器會在發送郵件之前被呼叫。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 521 def register_interceptors(*interceptors) interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) } end
register_observer(observer) 連結
註冊一個觀察者,當郵件傳送時會通知該觀察者。可以將類別、字串或符號傳遞為觀察者。如果傳遞的是字串或符號,它將會被駝峰化並常數化。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 533 def register_observer(observer) Mail.register_observer(observer_class_for(observer)) end
register_observers(*observers) 連結
註冊一個或多個觀察者,當郵件傳送時會通知這些觀察者。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 511 def register_observers(*observers) observers.flatten.compact.each { |observer| register_observer(observer) } end
unregister_interceptor(interceptor) 連結
取消註冊先前註冊的攔截器。可以將類別、字串或符號傳遞為攔截器。如果傳遞的是字串或符號,它將會被駝峰化並常數化。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 554 def unregister_interceptor(interceptor) Mail.unregister_interceptor(observer_class_for(interceptor)) end
unregister_interceptors(*interceptors) 連結
取消註冊一個或多個先前註冊的攔截器。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 526 def unregister_interceptors(*interceptors) interceptors.flatten.compact.each { |interceptor| unregister_interceptor(interceptor) } end
unregister_observer(觀察者) 連結
取消註冊先前註冊的觀察者。可以將類別、字串或符號傳遞為觀察者。如果傳遞字串或符號,它將會變成駝峰式大小寫並轉換為常數。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 540 def unregister_observer(observer) Mail.unregister_observer(observer_class_for(observer)) end
unregister_observers(*觀察者) 連結
取消註冊一個或多個先前註冊的觀察者。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 516 def unregister_observers(*observers) observers.flatten.compact.each { |observer| unregister_observer(observer) } end
類別私有方法
supports_path?() 連結
電子郵件不支援相對路徑連結。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 943 def self.supports_path? # :doc: false end
執行個體公開方法
attachments() 連結
允許您將附件新增到電子郵件,如下所示
mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
如果您這樣做,則 Mail
將取得檔案名稱並找出 MIME 類型。它還會設定 Content-Type
、Content-Disposition
和 Content-Transfer-Encoding
,並以 Base64 編碼附件的內容。
如果您願意,也可以透過傳遞雜湊而不是字串來指定覆寫。
mail.attachments['filename.jpg'] = {mime_type: 'application/gzip',
content: File.read('/path/to/filename.jpg')}
如果您想使用 Base64 以外的編碼,則需要傳遞編碼類型以及預編碼的內容,因為 Mail
不知道如何解碼資料
file_content = SpecialEncode(File.read('/path/to/filename.jpg'))
mail.attachments['filename.jpg'] = {mime_type: 'application/gzip',
encoding: 'SpecialEncoding',
content: file_content }
您也可以搜尋特定附件
# By Filename
mail.attachments['filename.jpg'] # => Mail::Part object or nil
# or by index
mail.attachments[0] # => Mail::Part (first attachment)
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 761 def attachments if @_mail_was_called LateAttachmentsProxy.new(@_message.attachments) else @_message.attachments end end
email_address_with_name(地址,名稱) 連結
傳回格式為「Name <[email protected]>」的電子郵件。
如果名稱是空白字串,則只傳回位址。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 685 def email_address_with_name(address, name) self.class.email_address_with_name(address, name) end
headers(args = nil) 連結
允許您傳遞隨機且不尋常的標頭給新的 Mail::Message
物件,它會將這些標頭新增到自己身上。
headers['X-Special-Domain-Specific-Header'] = "SecretValue"
您也可以將雜湊傳遞到標題欄位名稱和值的標題,然後將其設定在 Mail::Message
物件上
headers 'X-Special-Domain-Specific-Header' => "SecretValue",
'In-Reply-To' => incoming.message_id
產生的 Mail::Message
會在其標題中包含以下內容
X-Special-Domain-Specific-Header: SecretValue
關於取代已定義標題的注意事項
-
主旨
-
寄件者
-
發件者
-
收件者
-
副本收件者
-
密件副本收件者
-
回覆至
-
原始日期
-
訊息識別碼
-
參考
欄位在電子郵件標題中只能出現一次,而其他欄位(例如 X-Anything
)可以出現多次。
如果您要取代任何已存在的標題,請先將其設定為 nil
以重設值,否則會為同一個標題新增另一個欄位。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 723 def headers(args = nil) if args @_message.headers(args) else @_message end end
mail(headers = {}, &block) 連結
建立訊息和呈現電子郵件範本的主要方法。有兩種呼叫此方法的方式,使用區塊或不使用區塊。
它接受標題雜湊。這個雜湊讓您能夠在電子郵件訊息中指定最常用的標題,這些標題是
-
:subject
- 訊息的主旨,如果省略這個,Action Mailer 會要求 Rails I18n 類別在[mailer_scope, action_name]
範圍內翻譯:subject
,或者如果這個不存在,會翻譯action_name
的人性化版本 -
:to
- 訊息的收件者,可以是地址字串或地址陣列。 -
:from
- 訊息的寄件者 -
:cc
- 您希望在這個電子郵件中抄送的人,可以是地址字串或地址陣列。 -
:bcc
- 您希望在這個電子郵件中密件抄送的人,可以是地址字串或地址陣列。 -
:reply_to
- 將電子郵件的回覆至
標題設定為誰。 -
:date
- 寄送電子郵件的日期。
你可以使用 ::default
類別方法,為上述任何標頭設定預設值(:date
除外)
class Notifier < ActionMailer::Base
default from: '[email protected]',
bcc: '[email protected]',
reply_to: '[email protected]'
end
如果你需要上述未列出的其他標頭,你可以將它們傳遞為標頭雜湊的一部分,或使用 headers['name'] = value
方法。
當 :return_path
指定為標頭時,該值將用作 Mail
訊息的「信封寄件人」地址。當你想要將傳遞通知寄送到與 :from
中不同的地址時,設定此值很有用。Mail
實際上會優先使用 :return_path
,其次是 :sender
,最後才是 :from
欄位,作為「信封寄件人」的值。
如果你沒有將區塊傳遞給 mail
方法,它將使用預設的郵件名稱和呼叫它的方法名稱,在檢視路徑中找到所有範本,然後它將為這些範本中的每個範本建立部分,對正確的內容類型和順序進行有根據的猜測,並傳回一個完全準備好的 Mail::Message
,準備好呼叫 :deliver
來傳送。
例如
class Notifier < ActionMailer::Base
default from: '[email protected]'
def welcome
mail(to: '[email protected]')
end
end
將在「app/views/notifier」中尋找所有名稱為「welcome」的範本。如果沒有 welcome 範本,它將引發 ActionView::MissingTemplate 錯誤。
但是,這些可以自訂
mail(template_path: 'notifications', template_name: 'another')
現在它將在「app/views/notifications」中尋找所有名稱為「another」的範本。
如果你傳遞一個區塊,你可以呈現你選擇的特定範本
mail(to: '[email protected]') do |format|
format.text
format.html
end
你甚至可以直接呈現純文字,而不使用範本
mail(to: '[email protected]') do |format|
format.text { render plain: "Hello Mikel!" }
format.html { render html: "<h1>Hello Mikel!</h1>".html_safe }
end
這將呈現一個具有 text/plain
和 text/html
部分的 multipart/alternative
電子郵件。
區塊語法還允許你自訂部分標頭(如果需要)
mail(to: '[email protected]') do |format|
format.text(content_transfer_encoding: "base64")
format.html
end
來源: 顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 870 def mail(headers = {}, &block) return message if @_mail_was_called && headers.blank? && !block # At the beginning, do not consider class default for content_type content_type = headers[:content_type] headers = apply_defaults(headers) # Apply charset at the beginning so all fields are properly quoted message.charset = charset = headers[:charset] # Set configure delivery behavior wrap_delivery_behavior!(headers[:delivery_method], headers[:delivery_method_options]) assign_headers_to_message(message, headers) # Render the templates and blocks responses = collect_responses(headers, &block) @_mail_was_called = true create_parts_from_responses(message, responses) wrap_inline_attachments(message) # Set up content type, reapply charset and handle parts order message.content_type = set_content_type(message, content_type, headers[:content_type]) message.charset = charset if message.multipart? message.body.set_sort_order(headers[:parts_order]) message.body.sort_parts! end message end
mailer_name() 連結
傳回郵件物件的名稱。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 678 def mailer_name self.class.mailer_name end
執行個體私有方法
default_i18n_subject(interpolations = {}) 連結
使用 Rails I18n 類別在 [mailer_scope, action_name]
範圍下翻譯 subject
。如果在指定的範圍下找不到 subject
的翻譯,它會預設為 action_name
的人性化版本。如果主旨有內插,您可以透過 interpolations
參數傳遞。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 937 def default_i18n_subject(interpolations = {}) # :doc: mailer_scope = self.class.mailer_name.tr("/", ".") I18n.t(:subject, **interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize)) end
set_content_type(m, user_content_type, class_default) 連結
mail
使用來設定訊息的內容類型。
它會使用指定的 user_content_type
,或是在郵件訊息有任何附件時使用 multipart。如果附件是內嵌的,內容類型會是「multipart/related」,否則為「multipart/mixed」。
如果沒有透過標頭傳入任何內容類型,而且沒有任何附件,或訊息是 multipart,則會使用預設的內容類型。
來源:顯示 | 在 GitHub 上
# File actionmailer/lib/action_mailer/base.rb, line 915 def set_content_type(m, user_content_type, class_default) # :doc: params = m.content_type_parameters || {} case when user_content_type.present? user_content_type when m.has_attachments? if m.attachments.all?(&:inline?) ["multipart", "related", params] else ["multipart", "mixed", params] end when m.multipart? ["multipart", "alternative", params] else m.content_type || class_default end end