iPhoneのパケット代をTwitterに自動投稿するRubyスクリプト

面白そうなので作ってみた。

[2010-5-26 追記] 最新版があるよ

最新版のコードはTwitterにパケット代を投稿するpacketterを、My SoftBankがリニューアルしたのでまた更新 - 今日覚えたことにあるのでそっちを使うといいよ。

追記ここまで。

これは何?

iPhoneの(っていうかSoftBankの)現在までの今月分のパケット代をMy SoftBankから取得して、そのままTwitterに自動投稿するスクリプト

つまり、このスクリプトを定期的に実行するようにしておけば、定期的に自分のパケット代がTwitterにポストされ、自分やフォロワーがそれを見るわけだ。

何の役に立つかはイマイチわからないけど。どうせ定額だし。

[2010-2-3 追記] パケット通信制限との関連

ソフトバンクはヘビーユーザーに対するパケット通信制限をしているらしい。

これによると、1ヶ月で1,000万パケット使うと制限される場合があるとのこと。この辺の考え方を表にしてみた。

制限 1日あたり
パケット数 1,000万パケット 約33万パケット
データ量 約1.2GB 約42MB
金額 210万円 7万円
  • 1ヶ月=30日
  • 1パケット=128バイト
  • 1パケット=0.21円 (My SoftBankでの表示はたぶんこれで計算している)

として計算している。ちなみにこれはiPhoneの話。他は違うので注意してね。

追記ここまで。

packetter.rb

コードは以下。書きなぐった感じでごめん。

require 'rubygems'
require 'mechanize'
require 'open-uri'
require 'net/http'

my_softbank = {
  :user_id => 'my_softbank_id',
  :password => 'p@ssw0rd',
  :pin => '9999',
}

twitter = {
  :user_id => 'twitter_user_id',
  :password => 'p@ssw0rd',
}

# logger
#require 'logger'
#WWW::Mechanize.log = Logger.new('packetter.txt')
#WWW::Mechanize.log.level = Logger::DEBUG

# setup
puts 'setup...'
agent = WWW::Mechanize.new
agent.follow_meta_refresh = true
agent.user_agent = 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_0 like Mac OS X; ja-jp) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5A345 Safari/525.20'

# login
puts 'login...'
agent.get('https://mb.softbank.jp/scripts/japanese/sss/user/login.jsp')
agent.page.form_with(:name => 'loginForm'){|form|
  form.action = '/scripts/japanese/sss/user/loginCheck.jsp'
  form.field_with(:name => 'userId').value = my_softbank[:user_id]
  form.field_with(:name => 'password').value = my_softbank[:password]
  form.click_button
}

# jumo to customerservice
puts 'jumo to customerservice...'
agent.get('https://mb.softbank.jp/scripts/japanese/sss/ref/obicip.jsp')
agent.page.form_with(:name => 'newForm'){|form|
  form.click_button
}

# verify pin
puts 'verify pin...'
agent.get(
  'https://www.customerservice.mb.softbank.jp/obi/x/authhlr.do?' +
  [
    'wcohid=5',
    "authHLRRequireDto.HLR=#{my_softbank[:pin]}",
    'method=%8E%9F%82%D6',
    'jskytid=1',
    'sid=T9A1',
    'pid=J01P',
    'method=',
    'idex=',
    'dummy=',
  ].join('&')
)

# jump to pricemonth
puts 'jump to pricemonth...'
agent.page.link_with(:href => /pricemonth/).click

# packet fee
fee = agent.page.search('div[@align="right"]').last.inner_text.delete('^0-9,円')
puts "packet fee : #{fee}"

# post
puts 'post...'
Net::HTTP.version_1_2
Net::HTTP.start('twitter.com', 80) do |http|
  req = Net::HTTP::Post.new('/statuses/update.xml')
  req.basic_auth twitter[:user_id], twitter[:password]
  req.body = 'status=' + URI.encode("今日までのSoftBankパケット通信料 : #{fee}")
  res = http.request(req)
end

puts 'finished.'

使い方

事前にMy SoftBankにユーザー登録しておいてね。当たり前だけど。

My SoftBankのIDとパスワードと、さらに契約時に決めた4桁の暗証番号(pin)をpacketter.rbの冒頭に設定する。同様に、TwitterアカウントのIDとパスワードも設定しておく。

あとは、gemでMechanizeをセットアップした状態のRuby環境で、このスクリプトを実行すれば、動作する。

処理が正常に終われば、以下のような感じでパケット代がTwitterにポストされる。

今日までのSoftBankパケット通信料 : 157,708円

なくうかん on Twitter: "今日までのSoftBankパケット通信料 : 157,708円"

仕組み

RubyのMechanizeを使ってMy SoftBankのサイトに入っていって、パケット代が表示されるページまで進み、そこの文字を取得してTwitterにポストしている。

いくつかハマった点があったのでメモ。

  • PC用のMy SoftBankにアクセスすると、htmlが異様に複雑で大変だった。だからuser_agentをiPhoneのものに偽装してiPhone用のMy SoftBankにアクセスした。
  • ログインページのformタグは、action属性が空欄になっていて、submit時にJavaScriptでセットするようになっていた。MechanizeはJavaScriptまでは実行してくれないので、action属性を固定でセットしてsubmitした。
  • 途中、metaタグのRefreshを使っているページがあったので、follow_meta_refreshをtrueにした。
  • httpsのページにmetaタグのRefreshがあると、なぜかhttpのページにジャンプしてしまう。たぶんMechanizeかどこかのバグだと思う。注意が必要。
  • 途中、ページロード直後にJavaScriptでformをsubmitするだけのページがあり、そこを経由しないとMy SoftBankが正しく動作しないところがあった。
  • 暗証番号を認証するためのリクエストは、query_string内のパラメータ順が非常に大事らしく、ちょっと順番が違うだけでメニューに戻されるような仕様だった。そしてMechanizeが生成するパラメータの順番ではダメだったので、自前でquery_stringを組み立てた。

できあがったコードはたいしたことは無いんだけど、やり方を調査するのが大変だった。あれだね、SoftBankは料金プランはシンプルかもしれないけど、料金サイトの作りはかなり複雑だわ。

注意

契約してるプランなどで、My SoftBankの画面構成が異なる可能性があって、人によってはうまく動かないこともあるかも知れない。そんなときは、最後の方でXPathで金額を取り出してるところを自分に合うように直せばいけると思う。