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

Відповіді:


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пізніше, наприклад, у режимах перегляду електронної пошти, виконайте цеaddress.display_name = name.dup
Eero

7
Схоже, дорогоцінний камінь тепер обробляє передану рядок, тому name.dupбільше не здається потрібним. Джерело зазначає:@display_name = str.nil? ? nil : str.dup
Філой

Це навіть працює в ініціалізаторі config.mailer_sender = Proc.new { address = Mail::Address.new... }
Devise

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

2
Я не думаю, що так. Він не може містити жодних символів, що не належать до ASCII, не може містити сам символ цитати, а також є деякі символи ASCII, які також не дозволено / не рекомендується в заголовках. Я виявив, що RFC2047 забезпечує механізм кодування таких значень base64.
Вільям Денніс

11
дивіться мою відповідь про спосіб зробити це, що правильно кодує рядки.
Джеймс Маккінні

8
Це було корисно! FYI, якщо ви намагаєтеся перевірити це, вам потрібно буде подивитися @ email.header ['From']. To_s, а не @ email.from. Останній містить лише адресу електронної пошти, а не ім’я.
sbleon

7
Не роби це так. Дивіться замість @ JamesMcKinney відповідь.
Меттью Ратфлофф

5
Знову ж таки, не використовуйте це, оскільки це небезпечно. Дивіться замість @ JamesMcKinney відповідь.
Джейк Петрулес

43

У рейки3 я розміщую наступне у кожному середовищі. тобто виробництво.rb

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

Розміщення цитат навколо назви компанії не працювало для мене в Rails3.


Ви також можете розмістити його безпосередньо у файлі mailer.rb, як це, :from => "Company Name <no-reply@email.com>"якщо у вас немає обмежень щодо середовища.
Пуче

8

в межах Rails 2.3.3 була введена помилка в програмі ActionMailer. Білет ви можете побачити тут Білет № 2340 . Він вирішений в 2-3-стабільний і 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 root root] / config / inicijalizers.
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, є пам’ятати, що «рівень за замовчуванням» називається на рівні класу. Підпрограми, що посилаються лише на екземпляр, призводять до того, що він безшумно відмовляється і видає, коли ви намагаєтесь використовувати його:

 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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.