Rails ActionMailer - formatta il nome / indirizzo email del mittente e del destinatario


112

Esiste un modo per specificare l'email E il nome per le informazioni sul mittente e sul destinatario quando si utilizza ActionMailer?

In genere faresti:

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

Ma, voglio specificare il nome come well-- MyCompany <info@mycompany.com>, John Doe <john.doe@mycompany>.

C'è un modo per farlo?


Le guide Rails ha un esempio di come fare questo: guides.rubyonrails.org/... vedere anche un'altra risposta a questa domanda stackoverflow.com/a/8106387/879854
BF4

Risposte:


237

Se stai prendendo l'input dell'utente per nome ed e-mail, a meno che non convalidi molto attentamente o esegui l'escape del nome e dell'e-mail, puoi finire con un'intestazione From non valida semplicemente concatenando le stringhe. Ecco un modo sicuro:

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
Grazie mille! Ho pensato che ci fosse un modo migliore del concatenamento di stringhe, ma l'uso Mail::Addressnon è chiaro in nessuna documentazione che ho letto.
Tim Morgan

10
address.display_namesembra mutare la codifica della stringa in alcuni casi, quindi se prevedi di utilizzarlo in nameseguito, ad esempio nelle visualizzazioni del mailer di rails, faiaddress.display_name = name.dup
Eero

7
Sembra che la gemma di posta ora duplichi la stringa passata, quindi name.dupnon sembra più necessaria. La fonte dice:@display_name = str.nil? ? nil : str.dup
philoye

Funziona anche nell'inizializzatore Devise:config.mailer_sender = Proc.new { address = Mail::Address.new... }
Cimm

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

2
Non credo proprio. Non può contenere caratteri non ASCII per uno, non può contenere il carattere di virgolette stesso e ci sono alcuni caratteri ASCII che non sono consentiti / non consigliati anche nelle intestazioni. Ho scoperto che RFC2047 fornisce un meccanismo per la codifica base64 di tali valori.
William Denniss

11
vedi la mia risposta per un modo per farlo che codifichi correttamente le stringhe.
James McKinney,

8
Questo è stato utile! Cordiali saluti, se stai provando a testarlo, dovrai guardare @ email.header ['From']. To_s, non @ email.from. Quest'ultimo contiene solo l'indirizzo email e non il nome.
sbleon

7
Non farlo in questo modo. Vedi invece la risposta di @ JamesMcKinney.
Matthew Ratzloff,

5
Ancora una volta, non usarlo perché non è sicuro. Vedi invece la risposta di @ JamesMcKinney.
Jake Petroules

43

In rails3 inserisco quanto segue in ogni ambiente. cioè production.rb

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

L'inserimento di citazioni intorno al nome dell'azienda non ha funzionato per me in Rails3.


Puoi anche metterlo direttamente nel tuo file mailer.rb in questo modo :from => "Company Name <no-reply@email.com>"se non hai restrizioni ambientali.
Puce

8

all'interno di Rails 2.3.3 è stato introdotto un bug all'interno di ActionMailer. Puoi vedere il biglietto qui. Biglietto n . 2340 . È risolto in 2-3-stabile e master, quindi verrà risolto in 3.xe 2.3.6.

Per risolvere il problema entro 2.3. * Puoi utilizzare il codice fornito nei commenti del ticket:

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
Per chiunque abbia la mia domanda, "dove metto questo codice?" la risposta è salvarlo come file .rb nella directory [root dell'app rails] / config / initializers.
JellicleCat

6

La versione che mi piace usare di questo è

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

`<< sono backtick.

Aggiornare

Puoi anche cambiarlo in

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

Ulteriori informazioni sui valori letterali stringa.


1

Un altro aspetto irritante, almeno con il nuovo formato AR, è ricordare che "predefinito" viene chiamato a livello di classe. Fare riferimento a routine che sono solo istanze fa sì che fallisca silenziosamente e dia quando si tenta di usarlo:

 NoMethodError: undefined method `new_post' for Notifier:Class

Ecco cosa ho finito per usare:

def self.named_email(name,email) "\"#{name}\" <#{email}>" end
default :from => named_email(user.name, user.email)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.