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.