Rails ActionMailer - format nazwy nadawcy i odbiorcy / adresu e-mail

112

Czy istnieje sposób określenia adresu e-mail ORAZ nazwy dla informacji o nadawcy i odbiorcy podczas korzystania z ActionMailer?

Zwykle zrobiłbyś:

@recipients   = "#{user.email}"
@from         = "[email protected]"
@subject      = "Hi"
@content_type = "text/html"

Ale chcę, aby podać nazwę, jak well-- MyCompany <[email protected]>, John Doe <john.doe@mycompany>.

Czy jest na to sposób?

Grnbeagle
źródło
Przewodnik po Railsach zawiera przykład, jak to zrobić: guide.rubyonrails.org/ ... zobacz także inną odpowiedź w tym pytaniu stackoverflow.com/a/8106387/879854
BF4

Odpowiedzi:

237

Jeśli przyjmujesz dane wejściowe użytkownika dla nazwy i adresu e-mail, to jeśli nie sprawdzisz bardzo dokładnie nazwy i adresu e-mail lub nie zmienisz ich znaczenia, możesz skończyć z nieprawidłowym nagłówkiem From, po prostu łącząc ciągi. Oto bezpieczny sposób:

require 'mail'
address = Mail::Address.new email # ex: "[email protected]"
address.display_name = name.dup   # ex: "John Doe"
# Set the From or Reply-To header to the following:
address.format # returns "John Doe <[email protected]>"
James McKinney
źródło
1
Dziękuję bardzo! Pomyślałem, że jest lepszy sposób niż konkatacja ciągów, ale użycie go Mail::Addressnie jest jasne w żadnej z przeczytanych dokumentacji.
Tim Morgan
10
address.display_namewydaje się, że w niektórych przypadkach modyfikuje kodowanie ciągów znaków, więc jeśli planujesz używać namepóźniej, np. w widokach mailera rails, zróbaddress.display_name = name.dup
Eero
7
Wygląda na to, że klejnot Mail podszywa teraz przekazany ciąg, więc name.dupnie wydaje się już potrzebny. Źródło brzmi:@display_name = str.nil? ? nil : str.dup
philoye,
Działa to nawet w inicjatorze Devise:config.mailer_sender = Proc.new { address = Mail::Address.new... }
Cimm
97
@recipients   = "\"#{user.name}\" <#{user.email}>"
@from         = "\"MyCompany\" <[email protected]>"
Eduardo Scoz
źródło
2
Nie sądzę. Nie może zawierać żadnych znaków spoza zestawu ASCII, nie może zawierać samego znaku cudzysłowu, a niektóre znaki ASCII są również niedozwolone / niezalecane w nagłówkach. Odkryłem, że RFC2047 zapewnia mechanizm kodowania base64 takich wartości.
William Denniss,
11
zobacz moją odpowiedź na sposób zrobienia tego, który prawidłowo koduje ciągi.
James McKinney,
8
To było pomocne! Do Twojej wiadomości, jeśli próbujesz to przetestować, musisz spojrzeć na @ email.header ['Od']. To_s, a nie @ email.from. Ten ostatni zawiera tylko adres e-mail, a nie nazwisko.
sbleon
7
Nie rób tego w ten sposób. Zamiast tego zobacz odpowiedź @ JamesMcKinney.
Matthew Ratzloff,
5
Ponownie, nie używaj tego, ponieważ jest to niebezpieczne. Zamiast tego zobacz odpowiedź @ JamesMcKinney.
Jake Petroules
43

W rails3 umieszczam następujące elementy w każdym środowisku. tj. production.rb

ActionMailer::Base.default :from => "Company Name <[email protected]>"

Umieszczanie cudzysłowów wokół nazwy firmy nie działało w Rails3.

astjohn
źródło
Możesz również umieścić go bezpośrednio w swoim pliku mailer.rb w ten sposób, :from => "Company Name <[email protected]>"jeśli nie masz ograniczeń środowiskowych.
Puce
8

w Railsach 2.3.3 pojawił się błąd w ActionMailer. Możesz zobaczyć bilet tutaj. Bilet # 2340 . Jest rozwiązany w wersji 2-3-stabilnej i głównej, więc zostanie naprawiony w wersjach 3.x i 2.3.6.

Aby rozwiązać problem w 2.3. *, Możesz użyć kodu podanego w komentarzach do zgłoszenia:

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
anka
źródło
2
Dla każdego, kto ma moje pytanie „gdzie mam umieścić ten kod?” odpowiedzią jest zapisanie go jako plik .rb w katalogu [root aplikacji railsowej] / config / initializers.
JellicleCat
6

Wersja, którą lubię używać, to

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

`<< to grawerunki.

Aktualizacja

Możesz to również zmienić na

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

Przeczytaj więcej o literałach ciągów.

Marc
źródło
1

Innym irytującym aspektem, przynajmniej w przypadku nowego formatu AR, jest pamiętanie, że na poziomie klas nazywa się „default”. Odwoływanie się do procedur, które są tylko instancjami, powoduje dyskretne niepowodzenie i daje przy próbie użycia:

 NoMethodError: undefined method `new_post' for Notifier:Class

Oto, czego ostatecznie użyłem:

def self.named_email(name,email) "\"#{name}\" <#{email}>" end
default :from => named_email(user.name, user.email)
Kevin
źródło