携帯電話に絵文字入りメールをRailsから送信する。

本日、jpmobileを使って、絵文字入りのmailを携帯に対して送りたいと言う話がきました。
と言うわけで、Railsで絵文字入りメールを送る方法: ぐうたら技術屋のTipsを参照して
モジュールを作ってみた。


ActionMailer::Baseを上書きする。

class ActionMailer::Base
  def create!(*)
    super
    @mobile_filter = nil 
    @docomo_or_au = nil 
    dummy_controller = DummyController.new
    if @mail.to.to_s.split(/@/).size == 2
      if @mail.to.to_s.split(/@/)[1] =~ /docomo.ne.jp/
        dummy_controller.request.mobile = Jpmobile::Mobile::Docomo.new({})
        @mobile_filter = true
        @docomo_or_au = true
      elsif @mail.to.to_s.split(/@/)[1] =~ /ezweb.ne.jp/
        dummy_controller.request.mobile = Jpmobile::Mobile::Au.new({})
        @mobile_filter = true
        @docomo_or_au = true
      elsif @mail.to.to_s.split(/@/)[1] =~ /softbank.ne.jp/ || @mail.to.to_s.split(/@/)[1] =~ /vodafone.ne.jp/
        dummy_controller.request.mobile = Jpmobile::Mobile::Softbank.new({})
        @mobile_filter = true
      end 
    end

    if @mobile_filter
      mail_title = @docomo_or_au ? NKF.nkf("-xWs", @mail.subject) : @mail.subject
      mail_title = Jpmobile::Filter::Emoticon::Outer.new.to_external(mail_title, dummy_controller)
      @mail.subject = @docomo_or_au ? mail_title : Base64.b64encode(mail_title)
      @mail.body = @docomo_or_au ? NKF.nkf("-xWs", @mail.body) : @mail.body
      @mail.body = Jpmobile::Filter::Emoticon::Outer.new.to_external(@mail.body, dummy_controller)
      @mail.body = @docomo_or_au ? @mail.body : Base64.b64encode(@mail.body)
      @mail.set_content_type "text/plain; charset=#{@docomo_or_au ? 'Shift_JIS' : 'UTF-8'}"
      @mail.transfer_encoding = "base64" unless @docomo_or_au
    end 
    @mail
  end 


  class DummyController
    attr_accessor :request
    def initialize
      self.request = DummyRequest.new
    end 

    class DummyRequest
      attr_accessor :mobile
    end 
  end 
end

(9/25修正: id:walf443さんのコメントを受けて修正)
上のPGをlib/mobile_emoji_mail.rbとかで保存して、
config/enviroment.rbの最後の方に

require 'mobile_emoji_mail'

とかすれば動くはず。
ちなみにjpmobile必須です。


後、元サイトに書いてあるjpmobileの修正は必須。
一点目。lib/jpmobile/filter.rb

    case controller.request.mobile.to_s
    when Jpmobile::Mobile::Docomo.to_s
      table = Jpmobile::Emoticon::CONVERSION_TABLE_TO_DOCOMO
      to_sjis = true
    when Jpmobile::Mobile::Au.to_s
      table = Jpmobile::Emoticon::CONVERSION_TABLE_TO_AU
      to_sjis = true
    when Jpmobile::Mobile::Jphone.to_s
      table = Jpmobile::Emoticon::CONVERSION_TABLE_TO_SOFTBANK
      to_sjis = true
    when Jpmobile::Mobile::Softbank.to_s
      table = Jpmobile::Emoticon::CONVERSION_TABLE_TO_SOFTBANK
    end

to_sをつける形。(9/25追記:コードのミスによりそうなっており、必要無かった様です。)
svn logは

--- vendor/plugins/jpmobile/lib/jpmobile/filter.rb      (revision 1830)
+++ vendor/plugins/jpmobile/lib/jpmobile/filter.rb      (revision 1831)
@@ -154,17 +154,17 @@
           # 使用する変換テーブルの決定
           table = nil
           to_sjis = false
-          case controller.request.mobile
-          when Jpmobile::Mobile::Docomo
+          case controller.request.mobile.to_s
+          when Jpmobile::Mobile::Docomo.to_s
             table = Jpmobile::Emoticon::CONVERSION_TABLE_TO_DOCOMO
             to_sjis = true
-          when Jpmobile::Mobile::Au
+          when Jpmobile::Mobile::Au.to_s
             table = Jpmobile::Emoticon::CONVERSION_TABLE_TO_AU
             to_sjis = true
-          when Jpmobile::Mobile::Jphone
+          when Jpmobile::Mobile::Jphone.to_s
             table = Jpmobile::Emoticon::CONVERSION_TABLE_TO_SOFTBANK
             to_sjis = true
-          when Jpmobile::Mobile::Softbank
+          when Jpmobile::Mobile::Softbank.to_s
             table = Jpmobile::Emoticon::CONVERSION_TABLE_TO_SOFTBANK
           end


で、後2点目lib/jpmobile/emoticon.rb

[converted-0x1000].pack("U")

svn ログは

Index: vendor/plugins/jpmobile/lib/jpmobile/emoticon.rb
===================================================================
--- vendor/plugins/jpmobile/lib/jpmobile/emoticon.rb    (revision 1832)
+++ vendor/plugins/jpmobile/lib/jpmobile/emoticon.rb    (revision 1833)
@@ -87,7 +87,9 @@
           if sjis = UNICODE_TO_SJIS[converted]
             [sjis].pack('n')
           elsif webcode = SOFTBANK_UNICODE_TO_WEBCODE[converted-0x1000]
-            "\x1b\x24#{webcode}\x0f"
+            [converted-0x1000].pack("U")
           else
             # キャリア変換テーブルに指定されていたUnicodeに対応する
             # 携帯側エンコーディングが見つからない(変換テーブルの不備の可能性あり)。

こんな感じになりました。


参照元のエントリに感謝。