2010/05/08

シェルスクリプトからOAuth認証できるクライアントを作ったよ

ーーーーーーーーーー
この記事は古いです
ここを開いて一番上に出てきた記事に最新版が貼ってあります、たぶん
ーーーーーーーーーー

なんだか6月頃にBasic認証が廃止になるみたいですね
ということでとりあえすタイムラインの表示のみ実装してみました
今のとこ投稿はできないです

使い方は以下のshtter.shとtimeline.xslを同じディレクトリに置いて

$ ./shtter.sh init

で認証、URLが表示されたらブラウザで開いてPINをコンソールに入力してください
成功すれば上の方のAKEY、ASECRET、ID、NAMEが書き換えられます
次から引数なしで実行すればタイムラインが取得できるはずです

UrlEncodeって関数があるけどRFC的に全然正しくないのとか気にしない


shtter.sh (last update 2010/05/18)
This script lisence is GPL.

#!/bin/sh

CKEY="U3DhP7CpPx0bNCzdAFShg"
CSECRET="eAQ13OTo7BhroXQc5dA5oOqEuXhAf7yABVKpkbR7so"
AKEY=""
ASECRET=""
ID=""
NAME=""

GetRequestToken()
{
URL="http://twitter.com/oauth/request_token"

NONCE="`date +%s%N | md5sum | cut -c1-32`"
TIMESTAMP="`date +%s`"
PARAM="oauth_consumer_key=$CKEY&oauth_nonce=$NONCE&oauth_signature_method=HMAC-SHA1&oauth_timestamp=$TIMESTAMP&oauth_token=&oauth_version=1.0"

EURL="`UrlEncode $URL`"
EPARAM="`UrlEncode $PARAM`"
QUERY="GET&$EURL&$EPARAM"
HASH="`echo -n $QUERY | openssl sha1 -hmac "$CSECRET&" -binary | base64`"
HASH=`UrlEncode $HASH`

RTOKEN="`wget -q -O - \"$URL?$PARAM&oauth_signature=$HASH\"`"
if [ "$RTOKEN" == "" ]; then
echo "can not get request token"
exit 1
fi

RKEY="`echo $RTOKEN | sed 's/.*oauth_token=\([^&]*\).*/\1/'`"
RSECRET="`echo $RTOKEN | sed 's/.*oauth_token_secret=\([^&]*\).*/\1/'`"

echo "$RKEY $RSECRET"
}

GetAccessToken()
{
RKEY="$1"
RSECRET="$2"
PIN="$3"

URL="http://twitter.com/oauth/access_token"

NONCE="`date +%s%N | md5sum | cut -c1-32`"
TIMESTAMP="`date +%s`"
PARAM="oauth_consumer_key=$CKEY&oauth_nonce=$NONCE&oauth_signature_method=HMAC-SHA1&oauth_timestamp=$TIMESTAMP&oauth_token=$RKEY&oauth_verifier=$PIN&oauth_version=1.0"

EURL="`UrlEncode $URL`"
EPARAM="`UrlEncode $PARAM`"
QUERY="GET&$EURL&$EPARAM"
HASH="`echo -n $QUERY | openssl sha1 -hmac "$CSECRET&$RSECRET" -binary | base64`"
HASH=`UrlEncode $HASH`

ATOKEN="`wget -q -O - \"$URL?$PARAM&oauth_signature=$HASH\"`"
if [ "$ATOKEN" == "" ]; then
echo "can not get access token"
exit 1
fi

AKEY="`echo $ATOKEN | sed 's/.*oauth_token=\([^&]*\).*/\1/'`"
ASECRET="`echo $ATOKEN | sed 's/.*oauth_token_secret=\([^&]*\).*/\1/'`"
ID="`echo $ATOKEN | sed 's/.*user_id=\([^&]*\).*/\1/'`"
NAME="`echo $ATOKEN | sed 's/.*screen_name=\([^&]*\).*/\1/'`"

echo "$AKEY $ASECRET $ID $NAME"
}

GetTimeLine()
{
URL="http://api.twitter.com/1/statuses/home_timeline.xml"

NONCE="`date +%s%N | md5sum | cut -c1-32`"
TIMESTAMP="`date +%s`"
PARAM="oauth_consumer_key=$CKEY&oauth_nonce=$NONCE&oauth_signature_method=HMAC-SHA1&oauth_timestamp=$TIMESTAMP&oauth_token=$AKEY&oauth_version=1.0&status="

EURL="`UrlEncode $URL`"
EPARAM="`UrlEncode $PARAM`"
QUERY="GET&$EURL&$EPARAM"
HASH="`echo -n $QUERY | openssl sha1 -hmac "$CSECRET&$ASECRET" -binary | base64`"
HASH=`UrlEncode $HASH`

DIR="`dirname $0`"
TIMELINE="`xsltproc $DIR/timeline.xsl \"$URL?$PARAM&oauth_signature=$HASH\"`"
echo $TIMELINE | sed 's/__BR__\s*/\n/g'
}

UrlEncode()
{
echo "$@" | sed 's/&/%26/g; s/+/%2B/g; s/\//%2F/g; s/:/%3A/g; s/=/%3D/g'
}

case "$1" in
"init")
RTOKEN="`GetRequestToken`"
RKEY="`echo $RTOKEN | cut -d ' ' -f1`"
RSECRET="`echo $RTOKEN | cut -d ' ' -f2`"

echo "open this url in your browsser and input pin"
echo "http://twitter.com/oauth/authorize?oauth_token=$RKEY"
echo -n "pin > "
read PIN

ATOKEN="`GetAccessToken \"$RKEY\" \"$RSECRET\" \"$PIN\"`"
AKEY="`echo $ATOKEN | cut -d ' ' -f1`"
ASECRET="`echo $ATOKEN | cut -d ' ' -f2`"
ID="`echo $ATOKEN | cut -d ' ' -f3`"
NAME="`echo $ATOKEN | cut -d ' ' -f4`"

sed -i "1,/^AKEY/ s/^\(AKEY=\)\".*\"/\1\"$AKEY\"/" "$0"
sed -i "1,/^ASECRET/ s/^\(ASECRET=\)\".*\"/\1\"$ASECRET\"/" "$0"
sed -i "1,/^ID/ s/^\(ID=\)\".*\"/\1\"$ID\"/" "$0"
sed -i "1,/^NAME/ s/^\(NAME=\)\".*\"/\1\"$NAME\"/" "$0"
;;
*)
GetTimeLine
;;
esac


timeline.xsl (last update 2010/05/18)

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" encoding="UTF-8" />

<xsl:template match="/statuses/status">
<xsl:value-of select="user/screen_name" />: <xsl:value-of select="text" />__BR__
</xsl:template>

</xsl:stylesheet>

0 件のコメント:

コメントを投稿