Rails ActionMailer: formatee el nombre del remitente y el destinatario / dirección de correo electrónico

112

¿Hay alguna forma de especificar el correo electrónico Y el nombre de la información del remitente y del destinatario cuando se usa ActionMailer?

Normalmente harías:

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

Pero, quiero especificar nombre como bien-- MyCompany <[email protected]>, John Doe <john.doe@mycompany>.

¿Hay una manera de hacer eso?

Grnbeagle
fuente
Las guías de Rails tienen un ejemplo de cómo hacer esto: guides.rubyonrails.org/… también vea otra respuesta en esta pregunta stackoverflow.com/a/8106387/879854
BF4

Respuestas:

237

Si está tomando la entrada del usuario para el nombre y el correo electrónico, a menos que valide con mucho cuidado o escape el nombre y el correo electrónico, puede terminar con un encabezado From no válido simplemente concatenando cadenas. He aquí una forma segura:

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
fuente
1
Muchas gracias! Pensé que había una forma mejor que la cadena concat, pero el uso Mail::Addressno está claro en la documentación que leí.
Tim Morgan
10
address.display_nameparece mutar la codificación de la cadena en algunos casos, por lo que si planea usarla namemás adelante, por ejemplo, en las vistas del mailer de rieles, hágaloaddress.display_name = name.dup
Eero
7
Parece que la gema Mail ahora engaña a la cadena pasada, por lo que name.dupya no parece necesaria. La fuente dice:@display_name = str.nil? ? nil : str.dup
philoye
Esto incluso funciona en el inicializador de Devise:config.mailer_sender = Proc.new { address = Mail::Address.new... }
Cimm
97
@recipients   = "\"#{user.name}\" <#{user.email}>"
@from         = "\"MyCompany\" <[email protected]>"
Eduardo Scoz
fuente
2
No lo creo. No puede contener ningún carácter que no sea ASCII para uno, no puede contener el carácter de comillas en sí, y hay algunos caracteres ASCII que no están permitidos / no recomendados en los encabezados también. Descubrí que RFC2047 proporciona un mecanismo para codificar en base64 dichos valores.
William Denniss
11
vea mi respuesta para ver una forma de hacer esto que codifique correctamente las cadenas.
James McKinney
8
¡Esto fue útil! Para su información, si está intentando probar esto, deberá mirar @ email.header ['From']. To_s, no @ email.from. Este último contiene solo la dirección de correo electrónico y no el nombre.
sbleon
7
No lo hagas de esta manera. En su lugar, consulte la respuesta de @ JamesMcKinney.
Matthew Ratzloff
5
Nuevamente, no use esto ya que no es seguro. En su lugar, consulte la respuesta de @ JamesMcKinney.
Jake Petroules
43

En rails3 coloco lo siguiente en cada ambiente. es decir, production.rb

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

Colocar citas alrededor del nombre de la empresa no funcionó para mí en Rails3.

astjohn
fuente
También puede ponerlo directamente en su archivo mailer.rb de esta manera :from => "Company Name <[email protected]>"si no tiene restricciones de entorno.
Puce
8

en Rails 2.3.3 se introdujo un error en ActionMailer. Puede ver el boleto aquí Boleto # 2340 . Está resuelto en 2-3-estable y maestro, por lo que se solucionará en 3.xy 2.3.6.

Para solucionar el problema dentro de 2.3. * Puede usar el código provisto dentro de los comentarios 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
anka
fuente
2
Para cualquiera que tenga mi pregunta, "¿dónde coloco este código?" la respuesta es guardarlo como un archivo .rb en su directorio [rails app root] / config / initializers.
JellicleCat
6

La versión que me gusta usar de esto es

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

`<< son comillas invertidas.

Actualizar

También puedes cambiar eso a

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

Obtenga más información sobre los literales de cadena.

Bagazo
fuente
1

Otro aspecto irritante, al menos con el nuevo formato AR, es recordar que se llama "predeterminado" a nivel de clase. Hacer referencia a rutinas que son solo de instancia hace que falle silenciosamente y ceda cuando intentas usarlo:

 NoMethodError: undefined method `new_post' for Notifier:Class

Esto es lo que terminé usando:

def self.named_email(name,email) "\"#{name}\" <#{email}>" end
default :from => named_email(user.name, user.email)
Kevin
fuente