Rails ActionMailer-格式化发件人和收件人名称/电子邮件地址


112

使用ActionMailer时,是否可以为发件人和收件人信息指定电子邮件和名称?

通常,您会这样做:

@recipients   = "#{user.email}"
@from         = "info@mycompany.com"
@subject      = "Hi"
@content_type = "text/html"

但是,我想指定名称well-- MyCompany <info@mycompany.com>John Doe <john.doe@mycompany>

有没有办法做到这一点?


Rails指南提供了有关此操作的示例:guides.rubyonrails.org/…在此问题中还可以看到另一个答案stackoverflow.com/a/8106387/879854
BF4

Answers:


237

如果要使用用户输入的名称和电子邮件,那么除非您非常仔细地验证或转义名称和电子邮件,否则您可以通过简单地串联字符串来获得无效的From头。这是一种安全的方法:

require 'mail'
address = Mail::Address.new email # ex: "john@example.com"
address.display_name = name.dup   # ex: "John Doe"
# Set the From or Reply-To header to the following:
address.format # returns "John Doe <john@example.com>"

1
非常感谢!我发现有比字符串concat更好的方法,但是Mail::Address在我阅读的任何文档中都不清楚该使用哪种方法。
蒂姆·摩根

10
address.display_name在某些情况下似乎会使字符串编码发生变化,因此,如果您打算name稍后再使用,例如在rails mailer视图中,请做address.display_name = name.dup
Eero

7
看起来Mail宝石现在会欺骗传入的字符串,因此name.dup似乎不再需要了。消息来源@display_name = str.nil? ? nil : str.dup
philoye's

这甚至可以在Devise初始化程序中使用:config.mailer_sender = Proc.new { address = Mail::Address.new... }
Cimm

97
@recipients   = "\"#{user.name}\" <#{user.email}>"
@from         = "\"MyCompany\" <info@mycompany.com>"

2
我不这么认为。它不能包含任何一个非ASCII字符,它不能包含引号字符本身,并且标头中也不允许/不建议使用某些ASCII字符。我发现RFC2047提供了一种对这些值进行base64编码的机制。
威廉·丹尼斯

11
请参阅我的答案以获取正确编码字符串的方法。
James McKinney

8
这很有帮助!仅供参考,如果您要测试这一点,则需要查看@ email.header ['From']。to_s,而不是@ email.from。后者仅包含电子邮件地址,而不包含名称。
sbleon 2012年

7
不要这样 请参阅@JamesMcKinney的答案。
马修·拉兹洛夫

5
同样,请勿使用此方法,因为这是不安全的。请参阅@JamesMcKinney的答案。
杰克·彼得鲁里斯

43

在rails3中,我在每个环境中放置以下内容。即production.rb

ActionMailer::Base.default :from => "Company Name <no-reply@production-server.ca>"

在Rails3中,在公司名称周围放置引号对我不起作用。


:from => "Company Name <no-reply@email.com>"如果没有环境限制,您也可以像这样直接将其放在mailer.rb文件中。
2015年

8

在Rails 2.3.3中,引入了ActionMailer中的错误。您可以在此处查看票证#2340。它在2-3-stable和master中已解决,因此将在3.x和2.3.6中修复。

要在2.3。*中解决问题,可以使用票证注释中提供的代码:

module ActionMailer
  class Base
    def perform_delivery_smtp(mail)
      destinations = mail.destinations
      mail.ready_to_send
      sender = (mail['return-path'] && mail['return-path'].spec) || Array(mail.from).first

      smtp = Net::SMTP.new(smtp_settings[:address], smtp_settings[:port])
      smtp.enable_starttls_auto if smtp_settings[:enable_starttls_auto] && smtp.respond_to?(:enable_starttls_auto)
      smtp.start(smtp_settings[:domain], smtp_settings[:user_name], smtp_settings[:password],
                 smtp_settings[:authentication]) do |smtp|
        smtp.sendmail(mail.encoded, sender, destinations)
      end
    end
  end
end

2
对于任何有我问题的人,“我将这段代码放在哪里?” 答案是将其另存为您的[rails app root] / config / initializers目录中的.rb文件。
JellicleCat 2012年

6

我喜欢使用的版本是

%`"#{account.full_name}" <#{account.email}>`

`<<是反引号。

更新资料

您也可以将其更改为

%|"#{account.full_name}" <#{account.email}>|
%\"#{account.full_name}" <#{account.email}>\
%^"#{account.full_name}" <#{account.email}>^
%["#{account.full_name}" <#{account.email}>]

阅读有关字符串文字的更多信息。


1

至少在使用新的AR格式时,另一个令人烦恼的方面是要记住在类级别调用了“默认”。引用仅实例的例程会导致它默默地失败并在您尝试使用它时给出:

 NoMethodError: undefined method `new_post' for Notifier:Class

这是我最终使用的内容:

def self.named_email(name,email) "\"#{name}\" <#{email}>" end
default :from => named_email(user.name, user.email)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.