2008-12-04 22 views
6

Soy un correo electrónico n00b, pero estoy trabajando en una aplicación que envía correos electrónicos HTML con caracteres Unicode (como mi amigo señaló "disfrutar el infierno de la codificación").Cómo manejar encabezados de correo electrónico UTF-8 (como Asunto :) usando Ruby?

El encabezado Subject: proviene de la entrada del usuario y, por lo tanto, puede contener caracteres Unicode. Algunos clientes de correo (como GMail y Outlook 2007) están de acuerdo con esto, pero desde mi lectura parece que la forma correcta de hacerlo es usar MIME Encoded-Word encoding para los encabezados.

No puedo encontrar una biblioteca de Ruby para hacer esto. ¿Hay alguno?

Además, ¿hay un encabezado para agregar que indique a los clientes de correo que utilicen UTF-8 al mostrar el mensaje? Estamos enviando un correo electrónico de varias partes para que nuestro Content-Type sea multipart/mixed. Apple Mail.app en particular no está usando la codificación correcta, a pesar de que se especifica en las partes individuales como UTF-8.

Respuesta

5

Ahah! ActionMailer::Quoting tiene un método quoted_printable.

Así que aquí es lo que hice:

def my_email(foo) 
    ... 
    @subject = quoted_printable(foo.some_subject_with_accented_chars, 'utf-8') 
    ... 
end 

Hacer esto convenció a Mail.app para mostrar el resto del correo electrónico con UTF-8. ¡Ahora para probar el resto!

+0

Debería estar bien también. – Tomalak

+0

Este método no existe en los rieles 4 :(- ¿Alguna alternativa? – Hackeron

9

Su opcionalmente puede hacer lo mismo usando la codificación Base64:

require "base64" 

value = Base64.encode64("Your UTF-8 string") 
header = "=?UTF-8?B?" + value + "?=" 

Nota de la "B", que marca la carga útil codificada en Base64, en contraposición a la "Q", que marca la carga útil "Q-codificada". Este último podría ser falsificado mediante la codificación URL de la cadena y reemplazando todos los caracteres "%" por "=".

Al "falsear" me refiero a esto: produciría un resultado válido, pero quizás se codifiquen más caracteres de los que serían necesarios. La especificación permite codificar cada carácter que hay con "=" + ByteCodeAsHex, simplemente perjudica la legibilidad humana de los encabezados sin formato. UrlEncode es + .gsub(/%/, "=") no es un mal compromiso cuando no hay nada más disponible.

+0

¡Gracias!Empecé usando Base64 pero me preocupaba que los filtros de spam marcaran eso, así que cambié a imprimible entre comillas. Encontré un método para hacerlo en ActionMailer :: Citando. ¡Parece que también funciona! –

+0

No creo que los filtros de correo no deseado marcarían esto, este es un valor de encabezado válido. – Tomalak

+0

Sí, no tengo ninguna prueba de eso. Pensé que los spammers podrían intentar evitar filtros de contenido ingenuos. –

3

Dado que ninguna de las respuestas dice sobre el mensaje completo con Ruby puro, aquí está.

Net::SMTP.start("localhost") do |smtp| 
    smtp.open_message_stream opts[:sender_address], opts[:receiver_address] do |f| 

     f.puts "Content-type: text/plain; charset=UTF-8" 
     f.puts from 
     f.puts to 
     f.puts subject 
     f.puts message 
    end 
end 

Aquí abre la conexión a localhost. También es posible utilizar un servidor SMTP externo, consulte la documentación de net/smtp.

La primera línea establece el juego de caracteres utilizado en el mensaje. El resto de las líneas son variables definidas por separado:

desde es una dirección en forma de From: Name here <[email protected]>. Si no se desea un nombre, solo se puede especificar la dirección, como From: [email protected].

utiliza la misma sintaxis, con la excepción From: cambiado a To:.

El tema está en la forma de Asunto: asunto aquí. Para UTF-8, debe estar codificado en Base64 para que se muestre correctamente para los clientes.

subject = "Subject: =?UTF-8?B?" + Base64.strict_encode64(subject) + "?=" 

mensaje es el mensaje de texto sin formato codificado en UTF-8, sin ningún prefijo. net/smtp se encargará de formar el correo correcto.

Cuestiones relacionadas