メールで Twitter、OAuth (続き)

前回(メールで Twitter、OAuth - Rubyとか Illustratorとか SFとか折紙とか)はコマンドラインからのツイート投稿する所で力尽きてしまったのでその続き。

みたいな

json

まあ json ということに。Ruby は 1.8系なので何か必要(1.9系なら json は標準添付ライブラリ)。
取敢えず「sudo gem install json」しましょう。そして

[2279] irb -r <前回のトークン設定スクリプト>
irb(main):001:0> require 'json/pure'
=> true
irb(main):002:0> r = HsTweet.get '/statuses/friends_timeline.json?count=2'
=> #<Net::HTTPOK 200 OK readbody=true>
irb(main):003:0> rj = JSON.parse r.body

それで「rj[0]['text']」でツイート、「rj[0]['user']['screen_name']」でその発言者が取れる。rj[0].keys とかでハッシュのキーが見られるの便利。

.rss/nokogiri

.rss 書式で取ってきて Nokogiri で解析とかも良いかも、screen_name 込みのツイートが取れるのが良い

irb(main):001:0> require 'nokogiri'
=> true
irb(main):002:0> r = HsTweet.get '/statuses/friends_timeline.rss?count=20'
=> #<Net::HTTPOK 200 OK readbody=true>
irb(main):003:0> rn = Nokogiri.parse r.body

それで「rn.search('//title').map{|t| t.inner_text}」とかかな。

とはいえ投稿 update が .rss 書式に対応していないので場合分けちょっとつらい。

前からのスクリプト

もとのソースはこの辺(メールで Twitter、リファクタリング続き - Rubyとか Illustratorとか SFとか折紙とか)かな。そこから主に request と reply、さらに update メソッドを書き換える。

require '<前回のトークン設定スクリプト>'
require 'json/pure'

まずは require、rubygems や oauth の require はその<前回のトークン設定スクリプト>で済まされてる事になる。

そしてプライベートメソッド request と reply

    def request(to, post, args)
      arg_str = args.inject([]) do |res, k_v|
        res << "#{k_v[0]}=#{CGI.escape NKF.nkf('-Jw', k_v[1])}"
      end.join('&amp;')
      HsTweet.send post, "#{Path}#{to}.json?#{arg_str}"
    end # def request(to, args)

    def reply(response)
      res_json = JSON.parse(response.body)
      res_json = res_json.kind_of?(Array) ? res_json : [res_json]
      result = res_json.inject([response.to_s]) do |res, tweet|
        res << "#{tweet['user']['screen_name']}: #{tweet['text']}"
      end # result = res_json.inject([response.to_s]) do |res, tweet|
      smtp_res = Net::SMTP.start('localhost',25) do |smtp|
        smtp.send_mail <<-EOM, @recipient, @sender
From: #{@recipient}
To: #{@sender}
Subject: #{@recipient.split('@').first}
Date: #{Time.now}
Message-Id: <#{Time.now.to_i}.#{@recipient}>

#{NKF.nkf('-Wj', result.join("\n"))}
        EOM
      end # smtp_res = Net::SMTP.start('localhost',25) do |smtp|
      return response, smtp_res
    end # def reply(response)

requestメソッドでは HsTweet を直接呼んでるのでユーザ選択とか関係無くなってる、自分専用。

        res << "#{k_v[0]}=#{CGI.escape NKF.nkf('-Jw', k_v[1])}"

requestの際、pathに引数を埋め込むようにしている、update の際もそうする事になる、ということで文字コード変換後さらに urlencode する。CGIライブラリはどこで入ってきてたのかな。

replyメソッドでは JSON.parse している。

      res_json = res_json.kind_of?(Array) ? res_json : [res_json]

updateの時の responseはハッシュ一つになるが、timeline系の responseはハッシュ複数の配列になる。それを識別して配列化してるんだけどもう少し良い書き方ないかな。
メール送信は Net::SMTP直書き、まあこんなものでしょう、送信結果も返すようにしている。

そして updteメソッド

   def update(lines)
      doing = lines[0].chomp
      reply request('update', :post, :status => doing)
    end # def update(lines)

これも reply するようにしたり。