8月 132009
http://shokai.mag.keio.ac.jp/block_nowbots/から使える。
(8月15日:URL変更しました)
とりあえずSinatraとOAuthの組み合わせを試してみたかったので、DBは使わないものを作りたかった。取得したOAuthのtokenなどはその場で捨てている。blockコマンドを送る権限だけを一時的に委譲してもらう。
以下技術的なことのメモ。
■OAuthアプリの登録
まずhttp://twitter.com/oauth_clientsでアプリを登録し、consumer keyとconsumer secretを取得する。
で、下のコード中のCONSUMER_KEY, CONSUMER_SECRETを書き換える。
■必要なライブラリ
必要なgemをインストールする。最新版にした。
sudo gem install oauth twitter sinatraそれぞれ0.3.5, 0.6.13, 0.9.4がインストールされた。
twitterは内部でoauthに依存していて、oauthはバージョン毎に関数がけっこう変わっている。このバージョンの組み合わせなら動く。
■動かす
そして起動。
ruby block-nowbots.rb -p 2692 -s mongrelthinだと複数クライアントから同時にアクセスした時1クライアントずつしか対応してくれなかったんだけど、mongrelは全クライアントに同時に応答してくれた。mongrelにいつのまにかそういう機能がついたのか、sinatraのバグでthinがthread処理されないのかはよくわからない。
sinatraもrailsと同じくデプロイまわりを工夫した方がよさそう。passenger使うのがいいのかな?
参考:
- OAuth関連
- Sinatra関連
block-nowbots.rb
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
require 'oauth'
require 'twitter'
HOST_AND_PORT = "localhost:2692"
CONSUMER_KEY = "your-consumer-key"
CONSUMER_SECRET = "your-consumer-secret"
BOTS = 'nishinipporinow,nippori_now,kanda_now,tabata_now,sugamo_now,komagome_now,shinokubo_now,mejiro_now,takadanobabanow,okachimachi_now,uguisudani_now,ikebukuro_now,otsuka_now,akiba_now,tokyo_now,harajuku_now,shibuya_now,shibuya_now,yoyogi_now,shinjuku_now,ebisu_now'
set :sessions, true
def consumer
OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET,
:site => "http://twitter.com")
end
template :layout do
'<html>
<body>
<h1>地名なうbotを全blockするOAuthアプリ</h1>
<%= yield %>
<hr style="margin-top: 100px" />
<a href="http://shokai.org">http://shokai.org</a><br /><a href="http://shokai.org/blog/archives/4698">解説</a>
</body>
</html>'
end
get '/' do
@request_token = consumer.get_request_token(:oauth_callback => "http://#{HOST_AND_PORT}/auth")
session[:request_token] = @request_token.token
session[:request_token_secret] = @request_token.secret
erb %{
<p><%= BOTS %><br />をblock設定します</p>
<p>OAuth認証してください</p>
<a href="<%= @request_token.authorize_url %>">認証する!</a>
}
end
get '/auth' do
@request_token = OAuth::RequestToken.new(consumer,
session[:request_token],
session[:request_token_secret])
@access_token = @request_token.get_access_token({},
:oauth_token => params[:oauth_token],
:oauth_verifier => params[:oauth_verifier])
session[:access_token] = @access_token.token
session[:access_token_secret] = @access_token.secret
erb %{
<p>認証成功</p>
<p><a href="/block_now_bots">地名なうbotをblockする</a>(全部で<%= BOTS.split(",").size*3 %>秒くらいかかる)</p>
<a href='/'>戻る</a>
}
end
get '/block_now_bots' do
oauth = Twitter::OAuth.new(CONSUMER_KEY, CONSUMER_SECRET)
oauth.authorize_from_access(session[:access_token], session[:access_token_secret])
twit = Twitter::Base.new(oauth)
BOTS.split(",").each{|bot|
twit.block(bot)
puts "block #{bot}"
sleep 3
}
erb %{
<p>たぶんblockしました</p>
<p><a href="http://twitter.com/yamanote_now/following">確認</a></p>
}
end