Rubyで日本語メールを送信する方法

先日、Rubyからメールを送信する方法で、適当にサンプルコード組んで適当なテストで適当に性能がいいメーラーで読んでたので発覚しなかったんですが。日本語メールを送ると文字化け化けになってしまいました。

なにやら検索キーワードを解析してるとそのような方面からも足跡がちらほらあったのでこれはまずいと思いつつ調べました。

メールって無くなればいいのにね・・・ボソっ

メールで情報を受け取ることが大好きな人のために、プログラムで死ぬほど送りつけるためのサンプルコードをw
今回は日本語対応版です。・・・毎度のことですけど動けばOKの適当コーディングです。1秒間に1000万通以上送らないといけないんだ!という業者な方はCで書いてくださいww

期待のパッケージ惨殺編

それではいってみましょう。前回のRubyからメールを送信する方法で使ったActionmailerというライブラリを今回も使うんですが 調べると・・・
ここに
よたらぼ(2006-05-05)

ActionMailerについても、標準ではUTF-8のメールになってしまいますが、Ruby-GetText-PackageをインストールするだけでISO2022JPに変換されてメールされるようになります。

こんな期待させてくれる言葉が!こいつは入れないとだめですね。このgettextというやつを探します
コマンドから

gem search --remote gettext
gettext (1.9.0, 1.8.0, 1.7.0, 1.6.0, 1.5.0, 1.4.0, 1.3.0, 1.2.0, 1.1.1, 1.1.0, 1.0.0)
    Ruby-GetText-Package is a libary and tools to localize messages.

ありました
入れます

Select which gem to install for your platform (i386-mswin32)
 1. gettext 1.9.0 (mswin32)
 2. gettext 1.9.0 (ruby)
 3. gettext 1.8.0 (mswin32)
 4. gettext 1.8.0 (ruby)
 5. Skip this gem
 6. Cancel installation

Windowsなんで1を選んでおきます、コンパイル済みってやつね

Successfully installed gettext-1.9.0-mswin32

さっそく送ってみましょう・・・

ハイ!化けますね
インストールするだけでは、ちょっと過剰表現だったようですwこのライブラリはRuby on Railsを総合的に日本語化するときに使えるようですね。今回みたいにactionmailerだけチョイと使うぶんにはだめなよう

メンドクセェけど自前でやります

自給の選択編

日本語のメールはISO-2022でエンコードして送る決まりになっているようです。このISO-2022は一般的にJISと呼ばれるやつらしく 日本工業規格ではJIS X 0208と呼ばれるやつ

しらねーよ。シフトJISなら知ってるけどね。シフトJIS漢字コードここを読んだところ、この規格・・・アルファベット部のコードと漢字部のコード値が被る部分があって、文字列中に切り替え用のデータを突っ込まないと解釈をミスるという困ったちゃん?、つまりバイト単位で切ったり貼ったりするとおかしくなるコードなのかな?Rubyは文字列を単なるバイト列として捕らえている節があるのでね

ま、とにかくそういう使えない規格にわざわざ変更して送らないといけないわけだ、「社会のルールはマジだりー」

じゃ送ってやる! MySQLで接続したときも文字コード変換でお世話になりましたねkconv

require "kconv"
・・・
mySubjectJis = Kconv.tojis(mySubjectSJis)

件名だけじゃなくて本文もこんな感じで変換すりゃいいね

次はcontent-typeだ。ブラウザとかでも使うあれ、こいつがデフォルトでUTF8になっているので日本語と解釈させるためにISO-2022にする、つまりメーラーの日本語スイッチをオンにするおまじないというわけだ

このデフォルト値がインスタンス変数default_charsetに格納されているので継承時に塗りつぶしてしまう

@@default_charset = 'iso-2022-jp'

総合するとこうなる

require "kconv"
require 'action_mailer'

$KCODE = "u"

class HogeMailer < ActionMailer::Base
    @@default_charset = 'iso-2022-jp'
    def hogeMessage(recipient, mySubject, myBody)
        from 'hoge.hoge@hoge.com'
        recipients recipient
        subject Kconv.tojis(mySubject)
        body Kconv.tojis(myBody)
    end
end

ActionMailer::Base.smtp_settings = { :address => 'smtp.hoge.com',
                                     :port => 25,
                                     :domain => 'hoge.com',
                                     :user_name => 'hoge',
                                     :password => 'moge',
                                     :authentication => :login}

HogeMailer.deliver_hogeMessage('moge@moge.jp', "日本語件名テスト", "日本語本文テスト")

はいめでたし。日本語一つで一苦労だな・・・・
Ruby/メールを送信する - 俺の基地

文字コード超研究

文字コード超研究