ActionMailerでJIS(ISO-2022-JP)のメールを受信すると incompatible encoding regexp match (US-ASCII regexp with ISO-2022-JP string) になる

RedMineでメールからのチケット登録をできるようにしようとドキュメントどおりにやっていただけど、incompatible encoding regexp match (US-ASCII regexp with ISO-2022-JP string)になってしまいうまく登録できなかった。なので原因を探っていたところ、結局はActionMailerが問題であるということがわかった。

環境は

RedMineのapp/models/mail_handler.rb では結局のところ以下のことをしている。

class MailHandler < ActionMailer::Base
 def  self.receive(email, options={})
  super(email)
 end

 def receive(email)
  @email
 end
end

controllerで、MailHandler.receive()が呼び出されて、その後、ActionMailer::Base#receiveが呼び出されて、その後、MailHandler#receiveが呼び出されている様子。で、エラーはActionMailer::Base#receiveで起きる。

なので、~/Mail 以下にあるメールファイルを用いて、何がエラーになるのかチェックしてみた。

require 'rubygems'
require 'action_mailer'

class MailHandler < ActionMailer::Base
  def self.receive(email)
    if email.respond_to?(:force_encoding)
      email.force_encoding('ASCII-8BIT') 
    end
     super(email)
  end

  def receive(email)
    return email
  end
end

if ARGV.size != 1
  puts "Error: pleasee give path"
  exit
end

# ~/Mail以下にある90XXのファイルを読み取るようにした。
# 自分の環境にあわせて適宜変更のこと。
dir = "#{ARGV[0]}/90[0-9][0-9]" 

Dir.glob(dir).each do | filename |
  p filename.strip
  email = MailHandler.receive(File.read(filename))
  puts email.subject
end

結果、JIS(ISO-2022-JP)のメールには以下のようなエラーが。

% ruby CheckActionMailer.rb ~/Mail/
"/home/hogehoge/Mail/9026"
/usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/mail-2.4.4/lib/mail/fields/unstructured_field.rb:179:in `gsub!': incompatible encoding regexp match (US-ASCII regexp with ISO-2022-JP string) (Encoding::CompatibilityError)
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/mail-2.4.4/lib/mail/fields/unstructured_field.rb:179:in `encode_crlf'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/mail-2.4.4/lib/mail/fields/unstructured_field.rb:144:in `fold'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/mail-2.4.4/lib/mail/fields/unstructured_field.rb:96:in `wrapped_value'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/mail-2.4.4/lib/mail/fields/unstructured_field.rb:60:in `do_encode'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/mail-2.4.4/lib/mail/fields/unstructured_field.rb:42:in `encoded'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/mail-2.4.4/lib/mail/field.rb:133:in `method_missing'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/mail-2.4.4/lib/mail/header.rb:190:in `block in encoded'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/mail-2.4.4/lib/mail/header.rb:189:in `each'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/mail-2.4.4/lib/mail/header.rb:189:in `encoded'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/mail-2.4.4/lib/mail/message.rb:1708:in `encoded'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/actionmailer-3.2.8/lib/action_mailer/base.rb:434:in `set_payload_for_mail'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/actionmailer-3.2.8/lib/action_mailer/base.rb:403:in `block in receive'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/activesupport-3.2.8/lib/active_support/notifications.rb:123:in `block in instrument'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/activesupport-3.2.8/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/activesupport-3.2.8/lib/active_support/notifications.rb:123:in `instrument'
	from /usr/local/rvm/gems/ruby-1.9.3-p194@rails3/gems/actionmailer-3.2.8/lib/action_mailer/base.rb:401:in `receive'
	from CheckActionMailer.rb:13:in `receive'
	from CheckActionMailer.rb:32:in `block in <main>'
	from CheckActionMailer.rb:29:in `each'
	from CheckActionMailer.rb:29:in `<main>'

Googleで調べた結果、ActiomMailerでISO-2022-JPを扱うにはmail-iso-2022-jpが良いとのこと。

なので、mail-iso-2022-jpを導入し、先のチェックスクリプトでmail-iso-2022-jpを呼び出したところ、他は何も変えなくても ISO-2022-JP のメールをちゃんと扱えるようになった。

require 'rubygems'
require 'action_mailer'
require 'mail-iso-2022-jp'
〜以下、略〜

なので、Redmineをインストールしたディレクトリに Gemfile.localを作成し、中身を以下のようにした。

gem 'mail-iso-2022-jp'

で、 bundle install

現在、様子見中。