Rails ActionMailer - 格式化发件人和收件人姓名/电子邮件地址
Posted
技术标签:
【中文标题】Rails ActionMailer - 格式化发件人和收件人姓名/电子邮件地址【英文标题】:Rails ActionMailer - format sender and recipient name/email address 【发布时间】:2010-10-31 17:47:40 【问题描述】:在使用 ActionMailer 时,有没有办法为发件人和收件人信息指定电子邮件和名称?
通常你会这样做:
@recipients = "#user.email"
@from = "info@mycompany.com"
@subject = "Hi"
@content_type = "text/html"
但是,我也想指定名称--MyCompany <info@mycompany.com>
、John Doe <john.doe@mycompany>
。
有没有办法做到这一点?
【问题讨论】:
Rails 指南有一个如何做到这一点的示例:guides.rubyonrails.org/… 也可以在此问题中查看另一个答案***.com/a/8106387/879854 【参考方案1】:由于Rails 6.1,ActionMailer::Base
上有一个新的便捷辅助方法:
ActionMailer::Base.email_address_with_name("test@test.com", "John Test with Quotes <'")
=> "\"John Test with Quotes <'\" <test@test.com>"
在 Mailer 中,无需类名即可访问:
mail to: email_address_with_name(user.email, user.name), ...
在引擎盖下它使用 Mail::Address 就像在上面的答案中一样。
【讨论】:
【参考方案2】:如果您正在接受用户输入的姓名和电子邮件,那么除非您非常仔细地验证或转义姓名和电子邮件,否则您可能会通过简单地连接字符串而得到无效的 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>"
【讨论】:
非常感谢!我认为有比字符串 concat 更好的方法,但是在我阅读的任何文档中都不清楚使用Mail::Address
。
address.display_name
在某些情况下似乎会改变字符串编码,因此如果您打算稍后使用name
,例如在 Rails 邮件视图中,执行 address.display_name = name.dup
看起来 Mail gem 现在欺骗了传入的字符串,所以name.dup
似乎不再需要了。 Source 读作:@display_name = str.nil? ? nil : str.dup
这甚至可以在设计初始化器中工作:config.mailer_sender = Proc.new address = Mail::Address.new...
【参考方案3】:
我喜欢用这个的版本是
%`"#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>]
Read more about string literals.
【讨论】:
【参考方案4】:在 rails3 中,我在每个环境中放置以下内容。即生产.rb
ActionMailer::Base.default :from => "Company Name <no-reply@production-server.ca>"
在 Rails3 中,我无法在公司名称周围加上引号。
【讨论】:
如果你没有环境限制,也可以像:from => "Company Name <no-reply@email.com>"
这样直接放在你的mailer.rb文件中。【参考方案5】:
另一个令人讨厌的方面,至少对于新的 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)
【讨论】:
【参考方案6】:在 Rails 2.3.3 中引入了 ActionMailer 中的错误。你可以在这里看到票Ticket #2340。它已在 2-3-stable 和 master 中解决,因此将在 3.x 和 2.3.6 中修复。
为了解决 2.3.* 中的问题,您可以使用票证 cmets 中提供的代码:
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
【讨论】:
对于任何有我的问题的人,“我应该把这段代码放在哪里?”答案是将其保存为 .rb 文件在您的 [rails app root]/config/initializers 目录中。【参考方案7】:@recipients = "\"#user.name\" <#user.email>"
@from = "\"MyCompany\" <info@mycompany.com>"
【讨论】:
我不这么认为。它不能包含任何非 ASCII 字符,不能包含引号字符本身,并且在标题中也有一些不允许/不推荐的 ASCII 字符。我发现 RFC2047 提供了一种对此类值进行 base64 编码的机制。 查看我的答案,了解正确编码字符串的方法。 这很有帮助!仅供参考,如果您尝试对此进行测试,则需要查看@email.header['From'].to_s,而不是@email.from。后者仅包含电子邮件地址而不包含名称。 不要这样做。请参阅@JamesMcKinney 的答案。 再一次,不要使用它,因为它不安全。请参阅@JamesMcKinney 的答案。以上是关于Rails ActionMailer - 格式化发件人和收件人姓名/电子邮件地址的主要内容,如果未能解决你的问题,请参考以下文章
在 Rails3 / ActionMailer 中设置 Message-ID 邮件头
Rails ActionMailer 用户邮件发送器 无方法
Rails 5:ActionMailer 的“deliver_later”永远不会在生产中交付
Rails-如何测试ActionMailer发送了特定附件?