2011/01/02

AppEngine Java で絵文字入りメールを送信する

Google AppEngineで絵文字メールを送る方法を紹介します。AppEngineでは送信メールのエンコーディングを指定できない( issueへのリンク)ため、絵文字を送ることはできないと思っていたんですが、 @tmurakamiさんに、送る方法を教えてもらいました。ただし、今のところこの方法で動作確認が出来ているのは、auのW62T, W63H, W64Kのみです。また、AppEngineの振る舞いに依存しているため、今後も動くかどうかの保証はありません。また、メールをWebメール等に転送している場合、Webメール側(au oneとgmailで確認されています)ではメール全体が(絵文字部分だけでなく)正常に表示されないようです(ヘッダにあるエンコーディング情報とメールボディのエンコーディングが違うので無理も無いですが)。

方法は至ってシンプルで、JISエンコード済みのテキストを無理やりStringに入れるというものです。例えばスマイルマーク(ucs: ☺, au: )であれば、auでの文字コードは0x7656なので、以下のようにします。
String text = new String(
   new byte[]{0x1b, '$', 'B', 0x76, 0x56, 0x1b, '(', 'B'}
   , "ISO8859-1");
0x1b, '$', 'B'はJIS漢字を開始するエスケープシーケンス、0x1b, '(', 'B'はアスキー文字を開始するエスケープシーケンスです。こうやって作った文字列を、メールの本文に設定します。
MailService.Message m = new MailService.Message();
 m.setTextBody(text);
 // set sender, recipients and subject
 MailServiceFactory.getMailService().send(m);
ここでは触れませんが、JavaMailApiでは、ByteArrayDataSourceを使うと送れるそうです。

AppEngineはメールを送信する際、含まれているキャラクタを見て、エンコーディングを決定します。日本語が含まれていればISO2022JPを選択しますし、中国語であればBig5、UTF8になる場合もあります。上記のように制御コードが混じっていると、ISO8859-1として、そのまま送信するようです。そして実機ではエンコーディングを無視してISO2022JPとして表示するため、絵文字が表示できる、という仕組みです。ただしこのAppEngineの振る舞いは規定されているものではないので、今後も動き続ける保証はありません。

pos2witではこの方法を使って、絵文字の送信機能を実装しました(今のところauのみ)。ダッシュボードから有効にできるので、au携帯でお使いの方は是非試してみてください。また、今後他社の携帯も調査して、可能であれば対応する予定です。