twitterに「今起きた」と書くと早起き生活にポストされるRubyスクリプト


twitterが流行ってるみたいですね。ちょっと遊んでみたくなったのでコードを書きました。タイトルの通りですが、twitterに「今起きた」と書くと早起き生活(http://www.hayaoki-seikatsu.com/) にポストするスクリプトです。それPlaとかそれPraとかいわれてしまいそうですが、愛すべきRubyで愚直に書きました。

スクリプトを起動すると60秒毎(デフォルト)に自分のstatusをチェックします。新しいstatusがポストされて、しかもそれが「今起きた」だった場合に早起き生活の「今起きた」ボタンを押してくれます。起動時に既にポストされているstatusは無視します。WWW::Mechanizeを利用していますので、gem mechanize しておく必要があります。

ライフログ的な使い方をするtwitterはmashupのインタフェイスとして色々と応用ができそうですね。

私のURLは http://twitter.com/darashi です。よろしかったらぜひ。

ソースは以下に:

#!/usr/bin/ruby -Ku

require 'rexml/document'
require 'kconv'
require 'rubygems'
gem 'mechanize'
require 'mechanize'

# 設定など
hs_user = "" # 早起き生活ユーザ名  
hs_pass = "" # 早起き生活パスワード
tw_user = "" # twitterユーザ名
tw_pass = "" # twitterパスワード
wait_sec = 60

# 早起き生活クラス
class HayaokiSeikatsu
  def initialize(user, pass)
    @agent = WWW::Mechanize.new
    @user, @pass = user, pass
  end
  # ログインする
  def login
    page = @agent.get('http://www.hayaoki-seikatsu.com/')
    form = page.forms.action(/login.php$/).first
    form.text_mail = @user
    form.text_password = @pass
    page = @agent.submit(form)
    case page.body.toutf8 
    when /パスワードが間違っています。/m
      raise "incorrect password"
    when /指定のメールアドレスは登録されていません。/m
      raise "e-mail address not registered"
    end
    page
  end
  # 起床時刻を送信する。
  def imaokita(time=nil)
    page = login()
    unless time
      # いま起きた
      form = page.forms.select {|f| f.name.nil? }.first
      page = @agent.submit(form)
    else
      # 任意時刻
      form = page.forms.name("frm_add_risingtime").first
      form.select_hour = time.hour.to_s
      form.select_minutes = time.min.to_s
      form.select_year = time.year.to_s
      form.select_month = time.month.to_s
      form.select_date = time.mday.to_s
      page = @agent.submit(form)
    end
  end
end

# Twitterクラス
class Twitter
  def initialize(user, pass)
    @agent = WWW::Mechanize.new
    @user, @pass = user, pass
    @agent.basic_auth(@user, @pass)
    @most_recent_id = nil
  end
  # user_timelineを読み込む。前回呼ばれた以降に更新されたstatusを配列で返す。
  def timeline
    page = @agent.get('http://twitter.com/statuses/user_timeline.xml')
    doc = REXML::Document.new(page.body)
    results = []
    doc.each_element('/statuses/status') do |elem|
      id = elem.elements['id'].text.to_i
      time = Time.parse(elem.elements['created_at'].text)
      text = elem.elements['text'].text
      if @most_recent_id.nil? || id > @most_recent_id
        results << [id, time, text]
        @most_recent_id = id
      end
    end
    results
  end
end

hs = HayaokiSeikatsu.new(hs_user,hs_pass)

tw = Twitter.new(tw_user, tw_pass)
tw.timeline # 既にあるstatusは読み捨て
loop do
  sleep wait_sec
  begin
    statuses = tw.timeline # status取得
  rescue
    next
  end
    
  statuses.each do |id, time, text|
    p [id, time, text]
    if text =~ /^\s*(?:いま|今)(?:起|お)きた\s*$/
      hs.imaokita
      puts "送信しました"
    end
  end
end