言い訳。
記事を次の日に書くって言って結局今日になったの、やる気不足ちゃんと怠けぐせ君が活躍したおかげです!ごめんねっ!
前回からの続きでやったこと。
前回:http://qiita.com/onokatio/items/ada23d4ff6af69a8a5df
前回はシェル変数に値を代入できたので、次はツイッターにつぶやくために署名を作ってます。
それでは本題のTwitterのツイート部分に行こう!
心意気
これ以前も、TwitterでのBot制作をしたことがありますが、すべて何らかのライブラリなりラッパーなりを使用しており、今回シェルだけでツイートをするのは相当の無理がありました。
だがしかし!そんなことこそやるのが醍醐味です。
「無駄に洗練された無駄のない無駄なコードこそが最高のコードである」と考える僕は、結局やることにしました。
いや、別にC++やPHPのライブラリを使って、数十バイトで作っても何のデメリットもありません。でも、ここまで来たら全部一行で書きたいじゃあないですか笑
予想
今まで使ったライブラリのように、アプリとユーザーのキーとシークレットの系4つを使って適当に署名したのを「/1/statuses/update.json」にPOSTすればいんじゃないの?
調べてわかったことと、そのまとめ
https://dev.twitter.com/oauth/overview/authorizing-requests
ココの解説サイト様を参考にさせてにしました。世の中にはまるで運営じゃないかと見違うぐらいAPIに精通する方がいらっしゃるのですね。
茶番はこれくらいにしてさっそく初めましょう。
自分なりに意訳してまとめてみたHTTPリクエストの内容が以下のとおりです。
Accept: */*
Connection: close
User-Agent: OAuth gem v0.4.4
Content-Type: application/x-www-form-urlencoded
Authorization:
OAuth oauth_consumer_key="Twitterアプリのカスタマーキー",
oauth_nonce="32ビットの乱数をBASE64したやつ",
oauth_signature="署名本体(後述)",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="署名した時のUNIX時間",
oauth_token="ユーザーのアクセストークン",
oauth_version="1.0"
Content-Length: 76
Host: api.twitter.com
status=testtweet
そして肝心の署名部分の作り方を一行で説明すると、
「httpリクエストの、署名部分以外の残り全てのヘッダの文字列連結」を「Twitterアプリのカスタマーシークレットと、ユーザーのアクセストークンシークレットの文字列連結」で署名する
ちなみに署名に必要な関数の名前がHMAC-SHA1と呼ばれるものらしいです。
HMAC-SHA1をシェルでやろう
調べてみると、opensslコマンドで使えるらしいので、以下のようになりました。
K="秘密鍵"
M="署名したい文字列"
echo -n $K | openssl sha1 -hmac $K
じゃあ署名を作ってみよう
そして出来上がったコードがこちらです♪(三分クッキング的)
CK="カスタマーキー"
CS="カスタマーシークレット"
AT="アクセストークン"
ATS="アクセストークンシークレット"
STATUS="つぶやきたい内容"
TIME=`date +%s`
# 32ビットのランダムな文字をbase64に突っ込む
NONCE=`head -c 32 /dev/urandom|base64|sed 's/\/\|=\|+//g'`
# 秘密鍵の生成
K='${CS}&${ATS}'
# 公式ドキュメントどおりに必要なヘッダを並べる
SIG="include_entities=true&oauth_consumer_key=${CK}&oauth_nonce=${NONCE}&oauth_signature_method=HMAC-SHA1&oauth_timestamp=${TIME}&oauth_token=${AT}&oauth_version=1.0&status=${STATUS}"
# エンコード
SIG=`curl -s -w '%{url_effective}\n' --data-urlencode ${SIG} -G ''|sed -e 's/\/\|?//g'`
# アドレスとPOSTの指定も追加
SIG='POST&https%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.json&'${SIG}
# 署名して、そのバイナリをbase64
SIG=`echo -n ${SIG}|openssl sha1 -hmac ${K} -binary|base64`
あとはこのSIGを使ってHTTPリクエストをすればいいだけです。
それでは次回は、とうとうツイートをしてみます。
たぶん一週間以内にはまた投稿します。
それではバイバイ!!-=Ξヾ(ヾ(ヾ(ヾ(ヾ(ヾ(*´▽`)ツ