[Ruby][Twitter][API]RubyでTwitterにツイートをキメてみる
前回までのあらすじ
- http://d.hatena.ne.jp/kk_Ataka/20101121/1290271210:title
- http://d.hatena.ne.jp/kk_Ataka/20101130/1291125511:title
- http://d.hatena.ne.jp/kk_Ataka/20101207/1291733295:title
ターミナルからOAuth認証をキメて、タイムラインを見られるようになりました。最後にターミナルからツイートが出来れば一応Twitterの見る・書くがライブラリ無しでできたことになります。
ツイートする方法
- signatureを作成する。必要な値は以下のとおり。
- oauth_consumer_key
- oauth_nonce
- oauth_signature
- oauth_signature_method
- oauth_timestamp
- oauth_token
- oauth_version
- status New!
statusっていうのがツイートの本文ですね。signature作成するのにエスケープします。作成後のheaderはこんな感じ。[1]statusには「確認確認」って入ってます。
{
"oauth_nonce"=>"3c8293f9c5a0295148d428a26edb9f46",
"oauth_timestamp"=>"1295784908",
"oauth_signature_method"=>"HMAC-SHA1",
"oauth_consumer_key"=>"XXXXXXXXXXXXXXXXXXXXXX",
"oauth_token"=>"99999999-YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
"oauth_signature"=>"UKt1BmJ+UWNWrSmBuAyJ40iiCNY=",
"status"=>"%E7%A2%BA%E8%AA%8D%E7%A2%BA%E8%AA%8D",
"oauth_version"=>"1.0"
}
signature作成後
- signatureを作成したら、headerからstatusを消します
- 残ったheaderをアルファベット順に並べ、xxx=yyy,vvv=zzz……の形で連結します。連結後はこんな感じ
oauth_consumer_key=XXXXXXXXXXXXXXXXXXXXXX,oauth_nonce=341d852d61cdc3c22e3e847b0ab69d20,oauth_signature=MR5WEJ1qHuE49ozgRYduNJ%2BBiCs%3D,oauth_signature_method=HMAC-SHA1,oauth_timestamp=1295785315,oauth_token=99999999-YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY,oauth_version=1.0
- 連結した上記の値をAuthorizationヘッダに入れる。入れた後はこんな感じ。
"Authorization"=>"OAuth oauth_consumer_key=XXXXXXXXXXXXXXXXXXXXXX,oauth_nonce=341d852d61cdc3c22e3e847b0ab69d20,oauth_signature=MR5WEJ1qHuE49ozgRYduNJ%2BBiCs%3D,oauth_signature_method=HMAC-SHA1,oauth_timestamp=1295785315,oauth_token=99999999-YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY,oauth_version=1.0"
- Authorizationヘッダを作成したらhttp://api.twitter.com/1/statuses/home_timeline.jsonへPOST。また、ツイート本文を「status=本文」の形でくっつける
結果
以上で、Twitterにツイートが完了しました! おっぱいきたーー
[f:id:kk_Ataka:20110123215838j:image]
ソース
ソースはこんな感じです。
# -*- encoding: UTF-8 -*-
require 'openssl'
require 'uri'
require 'net/http'
require 'nkf'
require 'time'
# 署名
def sigunature(method,
consumer_secret,
oauth_token_secret,
url,
oauth_header=nil)
# sigunature_keyの作成
# リクエストトークン時は"CONSUMER_SECRET&"(アンドが入っている)
# アクセストークン時は"CONSUMER_SECRET&OAUTH_TOKEN_SECRET"として使用
sigunature_key = consumer_secret + "&"
if !oauth_token_secret.nil? then
sigunature_key += oauth_token_secret
end
param = sort_and_concat(oauth_header)
# メソッド + URL + パラメータ
value = method + "&" + escape(url) + "&" + escape(param)
# hmac_sha1
sha1 = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, sigunature_key, value)
# base64
base64 = [sha1].pack('m').gsub(/\n/, '')
return base64
end
# 文字列のエスケープ(: / = %をエスケープする。. _ -はそのまま)
def escape(value)
URI.escape(value, Regexp.new("[^a-zA-Z0-9._-]"))
end
# oauth_headerの情報をアルファベット順に並べ替え & で結合
def sort_and_concat(oauth_header)
oauth_header_array = oauth_header.sort
param = ""
oauth_header_array.each do |params|
for i in 1..params.length
param += params[i-1]
if i % params.length == 0
param += "&"
else
param += "="
end
end
end
param = param.slice(0, param.length-1)
end
# -------------------------------------------------------------
update_url = "http://twitter.com/statuses/update.json"
url = update_url
# コマンドプロンプトはutf8変換
text = escape(ARGV[0])
# text = escape(NKF.nkf('-w', ARGV[0]))
proxy = ARGV[1]
# Twitterで登録したらもらえる
consumer_key = "XXXXXXXXXXXXXXXXXXX"
consumer_secret = "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
# Twitterからもらえるリクエストトークン(最初は使わない)
oauth_token = "11111111-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
oauth_token_secret = "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"
# oauthパラメータたち(決め打ちのもの)
oauth_header = {
# Consumer Key
"oauth_consumer_key" => consumer_key,
# 一意な値
"oauth_nonce" => OpenSSL::Digest::Digest.hexdigest('MD5', "#{Time.now.to_f}#{rand}"),
# 署名方式(HMAC-SHA1)
"oauth_signature_method" => "HMAC-SHA1",
# リクエスト生成時のタイムスタンプのミリ秒
"oauth_timestamp" => Time.now.to_i.to_s,
# バージョン(1.0)
"oauth_version" => "1.0",
# アクセストークン
"oauth_token" => oauth_token
}
# headerにツイート追加
oauth_header["status"] = text
# 署名生成
oauth_header["oauth_signature"] = sigunature("POST",
consumer_secret,
oauth_token_secret,
url,
oauth_header)
# headerからツイート削除
oauth_header.delete("status")
# 署名エンコード
oauth_header["oauth_signature"] = escape(oauth_header["oauth_signature"])
param = sort_and_concat(oauth_header)
param = param.gsub('&', ',')
header = {
"Authorization" => "OAuth " + param
}
# POST
uri = URI.parse(update_url)
proxy_class = Net::HTTP::Proxy(proxy, 8080)
http = proxy_class.new(uri.host)
http.start do |http|
res = http.post(uri.path, "status=#{text}", header)
if res.code == "200" then
print "#{res.code} tweet: #{ARGV[0]}\n"
else
print "ERROR: #{res.code}\n #{res.body}\n"
end
end