Browse Month: August 2012

Ruby 1.9 で ISO-2022-JP メールを送る方法

とあるプログラムが、UTF-8 の文字コードで、大人の事情で添付ファイルがあり、その添付ファイルが ShiftJIS なメールを送信プログラムがありました。
このとき、次のような警告が表示されてしまいます。


Non US-ASCII detected and no charset defined.
Defaulting to UTF-8, set your own if this is incorrect.

しかも、このとき本文にプログラム上で本文を追加しているのですが、その本文が追加されなかったりと、いろいろと都合が増えてきたので、思い切って ISO-2022-JP に変更してみました。

ISO-2022-JP メールを送信するには、mail-iso-20220-jp gem を使うと、便利です。

上のような場合、次のようなコードにすると、文字化けや警告が表示されなくなり、幸せになれます。

Mail.deliver do |mail|
mail.charset = 'ISO-2022-JP'
from "naoya@example.com"
to "naoya@example.jp"
subject %(メールタイトル)
body %(メール本文)
mail.charset = 'Shift-JIS'
add_file "/tmp/attachment.csv"
end

# 2012.08.23 追記
上のコードだと Becky! で文字化けしまう現象が発生しました。上のコードだと、マルチパートの charset が Shift-JIS になってしまうためです。。。
正しいコードは、次のようになります。
添付ファイルの文字コードは、添付ファイルの実際のデータから文字コードを判定して、Content-Type の charset に追加しています。
あと、添付ファイル名が UTF-8 以外だと、おそらく添付ファイル名が文字化けするので、その場合は別途エンコードする必要があります。
今回、僕の方では UTF-8 な Ruby プログラムの中で日本語のファイル名を設定しているため、問題なかったりします。

require 'kconv'
MAIL_DEFAULT_CHARSET = 'ISO-2022-JP'
Mail.deliver do
@charset = MAIL_DEFAULT_CHARSET
from "naoya@example.com"
to "naoya@example.jp"
subject %(メールタイトル)
text_part do |v|
v.charset = MAIL_DEFAULT_CHARSET
body %(メール本文)
end
add_file "/tmp/attachment.csv"
self.attachments.each do |attachment|
attachment.charset = Kconv.guess(attachment.body.to_s).to_s
end
end

けっこうはまりましたが、ググるより、Ruby の mail gem のソースコードを読んだ方が、ずっと解決が早いことが分かりました・・・。