Rails - 邮件,将正文作为纯文本

AnA*_*ice 42 ruby-on-rails actionmailer heroku ruby-on-rails-3

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

如下所示:http://docs.heroku.com/cloudmailin

它显示了如何将message.body作为HTML,如何获得普通/文本版本?

谢谢

Ste*_*ith 69

上面的代码:

message = Mail.new(params[:message])
Run Code Online (Sandbox Code Playgroud)

将从完整消息创建邮件gem的新实例.然后,您可以使用该消息上的任何方法来获取内容.因此,您可以使用以下方式获取普通内容

message.text_part
Run Code Online (Sandbox Code Playgroud)

或HTML

message.html_part
Run Code Online (Sandbox Code Playgroud)

这些方法只是猜测并找到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
Run Code Online (Sandbox Code Playgroud)

作为旁注,在使用这些方法时从消息中提取内容编码也很重要,并确保将输出编码为您想要的编码方法(例如UTF-8).

  • 我如何提取编码?我正在做这个..force_encoding("ISO-8859-1").编码('utf_8')和一些消息工作,在其他人不. (3认同)
  • @David"默认Rails Action Mailer"**是**mail` gem.至少,取决于它. (2认同)

fie*_*edl 47

什么是Mail

message问题中所定义似乎是相同的一个实例MailMail::Message类,它也被用在ActionMailer::Base,或在邮递员宝石.

我不确定它在哪里被集成到rails中,但Steve Smith已经指出这是在mail gem中定义的.

从多部分电子邮件中提取部件

在gem的自述文件中,有一个关于阅读多部分电子邮件示例部分.

除了方法html_parttext_part,这简单地找到对应的mime类型的第一部分,可以通过手动的部件和过滤器通过的标准根据需要访问和循环.

message.parts.each do |part|
  if part.content_type == 'text/plain'
    # ...
  elsif part.content_type == 'text/html'
    # ...
  end 
end
Run Code Online (Sandbox Code Playgroud)

Mail::Part记录在这里.

编码问题

根据收到的邮件来源,可能存在编码问题.例如,rails可以识别错误的编码类型.然后,如果尝试将主体转换为UTF-8以将其存储在数据库(body_string.encode('UTF-8'))中,则可能存在编码错误,如

Encoding::UndefinedConversionError - "\xFC" from ASCII-8BIT to UTF-8
Run Code Online (Sandbox Code Playgroud)

(就像在这个SO问题中).

为了避免这种情况,可以从消息部分读出字符集,并告诉rails在编码为UTF-8之前它是什么字符集:

encoding = part_to_use.content_type_parameters['charset']
body = part_to_use.body.decoded.force_encoding(encoding).encode('UTF-8')
Run Code Online (Sandbox Code Playgroud)

这里,该decoded方法删除标题行,如邮件gem的自述文件编码部分所示.

编辑:硬编码问题

如果确实存在硬编码问题,前一种方法无法解决,请看一下优秀的charlock_holmes gem.

在添加这个gem之后Gemfile,有一种更可靠的方法来转换电子邮件编码,使用detect_encoding这个gem添加到字符串的方法.

我发现定义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
Run Code Online (Sandbox Code Playgroud)

摘要

# 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
Run Code Online (Sandbox Code Playgroud)

编辑:或者,在定义body_in_utf8方法后,如上所示,与单行相同:

(message.html_part || message.text_part || message).body_in_utf8
Run Code Online (Sandbox Code Playgroud)

  • 认真?像这样的答案需要一个特殊的质量标记. (5认同)

Kir*_*kov 13

email = Mail.new(params[:message])
text_body = (email.text_part || email.html_part || email).body.decoded
Run Code Online (Sandbox Code Playgroud)

我在RedmineCRM Helpdesk插件上使用此解决方案