Edited at

ラズパイでシステムの状況をツイッターにつぶやこう (2)

More than 1 year has passed since last update.


言い訳。

記事を次の日に書くって言って結局今日になったの、やる気不足ちゃんと怠けぐせ君が活躍したおかげです!ごめんねっ!


前回からの続きでやったこと。

前回: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リクエストの内容が以下のとおりです。


/1/statuses/update.jsonへの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コマンドで使えるらしいので、以下のようになりました。


hmac-sha1

K="秘密鍵"

M="署名したい文字列"

echo -n $K | openssl sha1 -hmac $K



じゃあ署名を作ってみよう

そして出来上がったコードがこちらです♪(三分クッキング的)


sig


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リクエストをすればいいだけです。

それでは次回は、とうとうツイートをしてみます。

たぶん一週間以内にはまた投稿します。

それではバイバイ!!-=Ξヾ(ヾ(ヾ(ヾ(ヾ(ヾ(*´▽`)ツ