Rails ActionMailer - Format Absender und Empfängername / E-Mail-Adresse


112

Gibt es eine Möglichkeit, bei Verwendung von ActionMailer E-Mail-UND-Namen für Absender- und Empfängerinformationen anzugeben?

Normalerweise würden Sie Folgendes tun:

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

Aber will ich Namen wie well-- angeben MyCompany <info@mycompany.com>, John Doe <john.doe@mycompany>.

Gibt es eine Möglichkeit, das zu tun?


Die Rails Guides haben ein Beispiel dafür: Guides.rubyonrails.org/… sehen auch eine andere Antwort in dieser Frage stackoverflow.com/a/8106387/879854
BF4

Antworten:


237

Wenn Sie Benutzereingaben für Name und E-Mail vornehmen, können Sie durch einfaches Verketten von Zeichenfolgen einen ungültigen From-Header erhalten, wenn Sie den Namen und die E-Mail-Adresse nicht sehr sorgfältig überprüfen oder umgehen. Hier ist ein sicherer Weg:

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
Ich danke dir sehr! Ich dachte, es gibt einen besseren Weg als String Concat, aber die Verwendung Mail::Addressist in keiner der von mir gelesenen Dokumentationen klar.
Tim Morgan

10
address.display_namescheint in einigen Fällen die Zeichenfolgencodierung zu mutieren. Wenn Sie also namespäter verwenden möchten, z. B. in Rails-Mailer-Ansichten, tun Sie diesaddress.display_name = name.dup
Eero

7
Es sieht so aus, als würde der Mail-Edelstein jetzt die übergebene Zeichenfolge täuschen, sodass er name.dupnicht mehr erforderlich zu sein scheint. Quelle liest:@display_name = str.nil? ? nil : str.dup
philoye

Dies funktioniert sogar im Devise-Initialisierer:config.mailer_sender = Proc.new { address = Mail::Address.new... }
Cimm

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

2
Das glaube ich nicht. Es darf keine Nicht-ASCII-Zeichen enthalten, es darf nicht das Anführungszeichen selbst enthalten, und es gibt einige ASCII-Zeichen, die in Überschriften nicht zulässig / nicht empfohlen sind. Ich fand heraus, dass RFC2047 einen Mechanismus für die Base64-Codierung solcher Werte bietet.
William Denniss

11
In meiner Antwort finden Sie eine Möglichkeit, Zeichenfolgen ordnungsgemäß zu codieren.
James McKinney

8
Das war hilfreich! Zu Ihrer Information, wenn Sie versuchen, dies zu testen, müssen Sie sich @ email.header ['From']. To_s ansehen, nicht @ email.from. Letzteres enthält nur die E-Mail-Adresse und nicht den Namen.
Sbleon

7
Mach es nicht so. Siehe stattdessen die Antwort von @ JamesMcKinney.
Matthew Ratzloff

5
Verwenden Sie dies auch hier nicht, da es unsicher ist. Siehe stattdessen die Antwort von @ JamesMcKinney.
Jake Petroules

43

In Rails3 platziere ich in jeder Umgebung Folgendes. dh Produktion.rb

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

Das Platzieren von Zitaten um den Firmennamen hat bei Rails3 bei mir nicht funktioniert.


Sie können es auch direkt in Ihre mailer.rb-Datei einfügen, :from => "Company Name <no-reply@email.com>"wenn Sie keine Umgebungsbeschränkungen haben.
Puce

8

In Rails 2.3.3 wurde ein Fehler im ActionMailer eingeführt. Sie können das Ticket hier sehen Ticket # 2340 . Es ist in 2-3-Stable und Master aufgelöst, sodass es in 3.x und 2.3.6 behoben wird.

Um das Problem innerhalb von 2.3. * Zu beheben, können Sie den in den Ticketkommentaren angegebenen Code verwenden:

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
Für alle, die meine Frage haben: "Wo lege ich diesen Code ab?" Die Antwort besteht darin, sie als .rb-Datei in Ihrem Verzeichnis [Rails App Root] / config / initializers zu speichern.
JellicleCat

6

Die Version, die ich gerne benutze, ist

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

`<< sind Backticks.

Aktualisieren

Sie können das auch in ändern

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

Lesen Sie mehr über String-Literale.


1

Ein weiterer irritierender Aspekt, zumindest beim neuen AR-Format, besteht darin, sich daran zu erinnern, dass "Standard" auf Klassenebene aufgerufen wird. Das Referenzieren von Routinen, die nur Instanzen sind, führt dazu, dass es stillschweigend fehlschlägt und gibt, wenn Sie versuchen, es zu verwenden:

 NoMethodError: undefined method `new_post' for Notifier:Class

Folgendes habe ich letztendlich verwendet:

def self.named_email(name,email) "\"#{name}\" <#{email}>" end
default :from => named_email(user.name, user.email)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.