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         = "info@mycompany.com"
@subject      = "Hi"
@content_type = "text/html"

Pero, quiero especificar nombre como bien-- MyCompany <info@mycompany.com>, John Doe <john.doe@mycompany>.

¿Hay una manera de hacer eso?


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: "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
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\" <info@mycompany.com>"

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 <no-reply@production-server.ca>"

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


También puede ponerlo directamente en su archivo mailer.rb de esta manera :from => "Company Name <no-reply@email.com>"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

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.


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)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.