Étant donné: message = Mail.new(params[:message])
comme on le voit ici: http://docs.heroku.com/cloudmailin
Il montre comment obtenir le message.body en HTML, comment obtenir la version en clair/texte?
Merci
Le code ci-dessus:
message = Mail.new(params[:message])
créera une nouvelle instance de mail gem à partir du message complet. Vous pouvez ensuite utiliser n’importe laquelle des méthodes de ce message pour obtenir le contenu. Vous pouvez donc obtenir le contenu brut en utilisant:
message.text_part
ou le HTML avec
message.html_part
Ces méthodes vont simplement deviner et trouver la première partie dans un message en plusieurs parties de type de contenu text/plain ou text/html. CloudMailin les fournit également à titre de méthodes pratiques toutefois via params [: plain] et params [: html]. Il convient de rappeler que le message n’est jamais garanti d’avoir une partie simple ou HTML. Il peut être intéressant d’utiliser quelque chose comme ce qui suit pour être sûr:
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
Notez également qu'il est important d'extraire le contenu du message lorsque vous utilisez ces méthodes et de vous assurer que la sortie est codée dans la méthode de codage souhaitée (comme UTF-8).
Mail
?La message
définie dans la question semble être une instance de la même classe Mail
ou Mail::Message
, qui est également utilisée dans ActionMailer::Base
ou dans le mailman gem .
Je ne suis pas sûr de savoir où cela est intégré dans Rails, mais Steve Smith a souligné que cela est défini dans le mail gem .
Mail::Message
sur rubydoc.info .Dans le readme de la gemme, il y a une section example sur la lecture d'emails en plusieurs parties .
Outre les méthodes html_part
et text_part
, qui trouvent simplement la première partie du type mime correspondant , vous pouvez accéder aux parties, les parcourir en boucle et les filtrer selon les critères.
message.parts.each do |part|
if part.content_type == 'text/plain'
# ...
elsif part.content_type == 'text/html'
# ...
end
end
Le Mail::Part
est documenté ici .
Selon la source du courrier reçu, des problèmes d'encodage peuvent survenir. Par exemple, Rails pourrait identifier le type de codage incorrect. Si, alors, on essaie de convertir le corps en UTF-8 afin de le stocker dans la base de données (body_string.encode('UTF-8')
), des erreurs de codage telles que
Encoding::UndefinedConversionError - "\xFC" from ASCII-8BIT to UTF-8
(comme dans cette SO question ).
Afin de contourner ce problème, on peut lire le jeu de caractères de la partie message et dire à Rails quel était ce jeu de caractères avant de l'encoder en UTF-8:
encoding = part_to_use.content_type_parameters['charset']
body = part_to_use.body.decoded.force_encoding(encoding).encode('UTF-8')
Ici, la méthode decoded
supprime les lignes d'en-tête, comme indiqué dans la section de codage du fichier readme de la gemme mail .
S'il y a vraiment des problèmes de codage difficiles à résoudre, jetez un coup d'œil à l'excellent charlock_holmes gem .
Après avoir ajouté cette gemme à la Gemfile
, il existe un moyen plus fiable de convertir les encodages de courrier électronique, à l'aide de la méthode detect_encoding
, qui est ajoutée à Strings par cette gemme.
J'ai trouvé utile de définir une méthode body_in_utf8
pour les messages électroniques. (Mail::Part
hérite également 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
# 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: Ou, après avoir défini une méthode body_in_utf8
, comme ci-dessus, identique à one-liner:
(message.html_part || message.text_part || message).body_in_utf8
email = Mail.new(params[:message])
text_body = (email.text_part || email.html_part || email).body.decoded
J'utilise cette solution sur RedmineCRM Helpdesk plugin
Je crois que si vous appelez message.text_part.body.decoded, vous obtiendrez le convertir en UTF-8 pour vous par la gemme du courrier, la documentation n’est cependant pas claire à 100%.
Enregistrer le format de corps HTML dans Rails USE <% = @ email.body.html_safe%> Cela enverra le texte écrit dans l’éditeur de texte de messagerie électronique tel quel.