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>.

Есть ли способ сделать это?

Grnbeagle
источник
В руководствах Rails есть пример того, как это сделать: guides.rubyonrails.org/… также см. Другой ответ в этом вопросе stackoverflow.com/a/8106387/879854
BF4

Ответы:

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
Спасибо вам большое! Я подумал, что есть способ лучше, чем конкатенация строк, но использование Mail::Addressнеясно ни в одной из прочитанных мною документации.
Тим Морган
10
address.display_nameв некоторых случаях кажется, что кодировка строки видоизменяется, поэтому, если вы планируете использовать ее nameпозже, например, в представлениях почтовой программы rails, сделайте этоaddress.display_name = name.dup
Eero
7
Похоже, что гем Mail теперь дублирует переданную строку, поэтому name.dupбольше не кажется необходимым. Источник гласит:@display_name = str.nil? ? nil : str.dup
Philoye
Это работает даже в инициализаторе 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
см. мой ответ, чтобы узнать, как правильно кодировать строки.
Джеймс МакКинни
8
Это было полезно! К вашему сведению, если вы пытаетесь это проверить, вам нужно будет посмотреть @ email.header ['From']. To_s, а не @ email.from. Последний содержит только адрес электронной почты, но не имя.
sbleon
7
Не делай так. Вместо этого см. Ответ @ JamesMcKinney.
Мэтью Ратцлофф
5
Опять же, не используйте это, так как это небезопасно. Вместо этого см. Ответ @ JamesMcKinney.
Джейк Петроулз
43

В rails3 я помещаю следующее в каждую среду. т.е. production.rb

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

Размещение цитат вокруг названия компании в Rails3 у меня не сработало.

Astjohn
источник
Вы также можете поместить его прямо в ваш файл mailer.rb, например, :from => "Company Name <no-reply@email.com>"если у вас нет ограничений среды.
Puce
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
Для всех, у кого есть мой вопрос: "Где мне поместить этот код?" ответ - сохранить его как файл .rb в каталоге [корень приложения rails] / config / initializers.
JellicleCat
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, - это помнить, что «default» вызывается на уровне класса. Ссылка на подпрограммы, предназначенные только для экземпляра, приводит к тому, что он молча терпит неудачу и дает при попытке использовать его:

 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)
Кевин
источник