Rails-Mail, obteniendo el cuerpo como Texto sin formato


Dado: message = Mail.new(params[:message])

Como se ve aquí: http://docs.heroku.com/cloudmailin

Muestra cómo obtener el mensaje.cuerpo como HTML, ¿cómo se obtiene la versión sin formato / texto?

Gracias

Author: John Topley, 2011-02-02

5 answers

El código anterior:

message = Mail.new(params[:message])

Creará una nueva instancia de la gema de correo a partir del mensaje completo. A continuación, puede utilizar cualquiera de los métodos en ese mensaje para obtener el contenido. Por lo tanto, puede obtener el contenido plano usando:

message.text_part

O el HTML con

message.html_part

Estos métodos solo adivinarán y encontrarán la primera parte en un mensaje multiparte de tipo de contenido text/plain o text/html. CloudMailin también proporciona estos como métodos de conveniencia sin embargo a través de params [: plain] y params [: html]. Vale la pena recordar que nunca se garantiza que el mensaje tenga una parte simple o html. Puede valer la pena usar algo como lo siguiente para estar seguro:

plain_part = message.multipart? ? (message.text_part ? message.text_part.body.decoded : nil) : message.body.decoded
html_part = message.html_part ? message.html_part.body.decoded : nil

Como nota al margen, también es importante extraer la codificación de contenido del mensaje cuando utilice estos métodos y asegurarse de que la salida esté codificada en el método de codificación que desee (como UTF-8).

 60
Author: Steve Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-01 21:53:32

¿Qué es Mail?

El message definido en la pregunta parece ser una instancia de la misma clase Mail o Mail::Message, que también se usa en ActionMailer::Base, o en la gema mailman.

No estoy seguro de dónde está integrado en rails, pero Steve Smith ha señalado que esto está definido en la gema de correo .

Extrayendo una Parte De un Correo Electrónico Multiparte

En el readme de la gema, hay una sección de ejemplo sobre la lectura de correos electrónicos de varias partes.

Además de los métodos html_part y text_part, que simplemente encuentran la primera parte del tipo mime correspondiente, uno puede acceder y recorrer las partes manualmente y filtrar por los criterios según sea necesario.

message.parts.each do |part|
  if part.content_type == 'text/plain'
    # ...
  elsif part.content_type == 'text/html'
    # ...
  end 
end

El Mail::Part está documentado aquí.

Codificación Cuestiones

Dependiendo de la fuente del correo recibido, puede haber problemas de codificación. Por ejemplo, rails podría identificar el tipo de codificación incorrecto. Si, entonces, uno intenta convertir el cuerpo a UTF-8 para almacenarlo en la base de datos (body_string.encode('UTF-8')), puede haber errores de codificación como

Encoding::UndefinedConversionError - "\xFC" from ASCII-8BIT to UTF-8

(como en esta pregunta).

Para evitar esto, uno puede leer el conjunto de caracteres de la parte del mensaje y decirle a rails qué conjunto de caracteres ha sido antes de la codificación para UTF-8:

encoding = part_to_use.content_type_parameters['charset']
body = part_to_use.body.decoded.force_encoding(encoding).encode('UTF-8')

Aquí, el método decoded elimina las líneas de encabezado, como se muestra en la sección de codificación del readme de la gema de correo.

EDITAR: Problemas de Codificación dura

Si hay problemas de codificación realmente difíciles, el primer enfoque no resuelve, eche un vistazo a la excelente gema charlock_holmes.

Después de agregar esta gema a Gemfile, hay una forma más confiable de convertir codificaciones de correo electrónico, utilizando el método detect_encoding, que se agrega a Cuerdas por esta joya.

Me pareció útil definir un método body_in_utf8 para los mensajes de correo. (Mail::Part también hereda de Mail::Message.):

module Mail
  class Message
    def body_in_utf8
      require 'charlock_holmes/string'
      body = self.body.decoded
      if body.present?
        encoding = body.detect_encoding[:encoding]
        body = body.force_encoding(encoding).encode('UTF-8')
      end
      return body
    end
  end
end

Resumen

# select the part to use, either like shown above, or as one-liner
part_to_use = message.html_part || message.text_part || message

# readout the encoding (charset) of the part
encoding = part_to_use.content_type_parameters['charset'] if part_to_use.content_type_parameters

# get the message body without the header information
body = part_to_use.body.decoded

# and convert it to UTF-8
body = body.force_encoding(encoding).encode('UTF-8') if encoding

EDIT: O, después de definir un método body_in_utf8, como se muestra arriba, lo mismo que one-liner:

(message.html_part || message.text_part || message).body_in_utf8
 45
Author: fiedl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:38
email = Mail.new(params[:message])
text_body = (email.text_part || email.html_part || email).body.decoded

Estoy usando esta solución en RedmineCRM Helpdesk plugin

 12
Author: Kirill Bezrukov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-26 11:50:30

Creo que si llamas mensaje.text_part.cuerpo.decodificado usted conseguirá convertido a UTF-8 para usted por la gema del correo, la documentación no es 100% clara en esto sin embargo.

 3
Author: W. Andrew Loe III,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-06 23:55:37

Guardar el formato de Cuerpo HTML en Rails UTILICE Esto enviará texto escrito en el editor de texto de correo electrónico como lo es para enviar por correo electrónico.

 0
Author: Dhanshree,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-07 13:56:19