Rails - почта, получая тело в виде простого текста - PullRequest
40 голосов
/ 02 февраля 2011

Дано: message = Mail.new(params[:message])

, как показано здесь: http://docs.heroku.com/cloudmailin

Это показывает, как получить message.body в виде HTML, как получить простую / текстовую версию?

Спасибо

Ответы [ 5 ]

65 голосов
/ 02 февраля 2011

Код выше:

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

создаст новый экземпляр почты gem из полного сообщения.Затем вы можете использовать любой из методов в этом сообщении, чтобы получить контент.Поэтому вы можете получить простой контент, используя:

message.text_part

или HTML с

message.html_part

Эти методы просто угадывают и находят первую часть в составном сообщении либо text / plainили тип содержимого text / html.CloudMailin также предоставляет их как удобные методы, однако через params [: plain] и params [: html].Стоит помнить, что сообщение никогда не будет иметь простой или HTML-части.Может быть стоит использовать что-то вроде следующего, чтобы быть уверенным:

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

В качестве примечания также важно извлечь кодировку содержимого из сообщения при использовании этих методов и убедиться, что выходные данные закодированыв метод кодирования, который вы хотите (например, UTF-8).

46 голосов
/ 04 апреля 2013

Что такое Mail?

Определенный в вопросе message представляется экземпляром того же класса Mail или Mail::Message, который также используется в ActionMailer::Base или в mailman gem .

Я не уверен, где это интегрировано в рельсы, но Стив Смит указал , что это определено в mail gem .

Извлечение детали из составного электронного письма

В файле readme для драгоценного камня есть пример раздела о чтении составных писем .

Помимо методов html_part и text_part, которые просто находят первую часть соответствующего типа MIME , можно обращаться к деталям и просматривать их вручную, а также фильтровать по критериям.

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

Mail::Part задокументировано здесь .

Проблемы с кодировкой

В зависимости от источника полученной почты могут возникнуть проблемы с кодировкой. Например, рельсы могут идентифицировать неправильный тип кодировки. Если затем попытаться преобразовать тело в UTF-8, чтобы сохранить его в базе данных (body_string.encode('UTF-8')), могут быть ошибки кодирования, например

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

(как в этот вопрос ).

Чтобы обойти это, можно прочитать кодировку из части сообщения и сообщить rails, какой кодировкой она была до кодирования в UTF-8:

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

Здесь метод decoded удаляет строки заголовка, как показано в разделе кодировки в readme .

почтового гема.

РЕДАКТИРОВАТЬ: проблемы жесткого кодирования

Если есть действительно сложные проблемы с кодированием, прежний подход не решает, взгляните на превосходный charlock_holmes gem .

После добавления этого драгоценного камня в Gemfile существует более надежный способ преобразования кодировок электронной почты, используя метод detect_encoding, который добавляется в строки этим драгоценным камнем.

Мне было полезно определить метод body_in_utf8 для почтовых сообщений. (Mail::Part также наследуется от 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
*

Резюме * 1081 # 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 РЕДАКТИРОВАТЬ: Или, после определения метода body_in_utf8, как показано выше, так же, как однострочный: (message.html_part || message.text_part || message).body_in_utf8

13 голосов
/ 26 октября 2012
email = Mail.new(params[:message])
text_body = (email.text_part || email.html_part || email).body.decoded

Я использую это решение на Плагин RedmineCRM Helpdesk

3 голосов
/ 07 апреля 2011

Я полагаю, что если вы позвоните message.text_part.body.decoded, вы конвертируете его в UTF-8 для вас с помощью самоцвета Mail, хотя документация не ясна на 100% по этому вопросу.

0 голосов
/ 07 августа 2018

Сохранить формат тела HTML в Rails USE <% = @ email.body.html_safe%> Это отправит текст, написанный в текстовом редакторе электронной почты, как и на электронную почту.

...