さて、最終的に、OAuth 認証ヘッダを作成して、Bot として動作できそうなところに来ました。
実は、私が管理しているのは、「節気さんシリーズ」といいまして、単純に生成したメッセージを(とりあえず、メッセージを生成するまでの過程はそれなりに複雑)単純にポストするだけのものです。
ですから、Twitter へのリクエストは、POST http://api.twitter.com/1/statuses/update.xml のみです。(一応レスポンスのコードはチェックしていますが)
まず、非常におおざっぱに言いますと、Basic 認証であろうと、OAuth 認証であろうと、送信するヘッダ、ボディはほとんど同じです。
Authorization: Basic (Basic 認証ヘッダ)が
Authorization: OAuth (OAuth 認証ヘッダ)に変わるだけです。
というわけで、OAuth 認証ヘッダを生成できれば、Botとして動作可能というわけです。
----------- OAuth 認証ヘッダ作成プログラム -----------------
こんなのを作りました。
ヘッダファイル : create_oauth.h : http://www.axis.blue/tec/create_oauth.h
ソースファイル : create_oauth.cpp : http://www.axis.blue/tec/create_oauth.cpp
※上記のソースの中で、
#include <system.hpp>
#include <Classes.hpp>
の2行と、
void makeNonce() にある、 AnsiString time = Now().FormatString("yyyy/mm/dd-hh:nn:ss");
int UnixTime(TDateTime aTime) や、void makeTimeStamp() にある、Now() や、TDateTime 型は、Turbo C++ の処理系に依存しています。
別の処理系では、
AnsiString time = Now().FormatString("yyyy/mm/dd-hh:nn:ss");
は、単純に、time = "aaajajajajaja"; // ランダムな文字
とかで良いはずです。
時刻系のものは、なんとか、Unix Time を算出してください。(Visua C++ なら、CTime が使える気がします。
さらに、AnsiString も、処理系依存です。
こちらは、ほぼ、std::string で書き直せると思います。
これが、OAuth 認証ヘッダの生成に使うソースになります。
------------- 具体的にポスト ----------------------------
まず、単純に、abcd という文字をポストすることにします。
ボディは、 status=abcd です。
また、基本情報として、
OAuthDataDef mine =
{
"My_API_Name", // これは実際には使いません
"my_Consumer_key", // 実際には、入手した Consumer_key 以下同じ
"my_Consumer_secret",
"my_Access_Token",
"my_Access_Token_Secret"
};
と元になるキーを定義しておきます。
また、Body は、
char *body = "status=abcd";
とでもしておきます。
さて、このあと、
makeNonce(); // Nonce の生成
makeTimeStamp(); // timestamp の生成
AnsiString key = mine.Consumer_secret;
key += "&";
key += mine.Access_Token_Secret;
// ここまで、HMAC-SHA1 の鍵生成
AnsiString baseString = makeBaseString(mine, body);
// Base string を生成して
makeSignHere(baseString, key);
// シグネチャーを作って、
AnsiString oauthHeadder = makeHeadder(mine, body);
// OAuth 認証ヘッダを生成
となります。
create_oauth の内部構造が整理できていないので、呼び出しはこの順番でなければなりません。
※例によって、AnsiString は、処理系依存です。これも、std::string で置き換えられると思います。
ここまでで、OAuth ヘッダが生成できました。あとは、これを送信するだけです。
すでに、コネクションが成立したという前提で、(さらに、server->SendTo() でテキストが送信できるという前提で)
まず、"Content-Length: を生成します。
const char * CRLF = "\x0d\x0a";
AnsiString lenHeader = "Content-Length: ";
lenHeader += std::strlen(body);
lenHeader += CRLF;
で、
server->SendText("POST http://api.twitter.com/1/statuses/update.xml HTTP/1.1" CRLF);
server->SendText("Host: api.twitter.com" CRLF);
server->SendText("Content-type: application/x-www-form-urlencoded" CRLF);
oauthHeadder += CRLF;
server->SendText(oauthHeadder);
server->SendText(lenHeader);
server->SendText(CRLF);
server->SendText(line);
server->SendText(CRLF);
となります。
あとは、レスポンスを待つことになります。
【補足】
上記の例では、単純化するため、送信テキストを、"abcd" にしました。
しかし実際には、日本語を送信することが多いでしょう。
たとえば、
status=おはよう
であれば、UTF-8 で、URLエンコードしますから、実際に送るテキストは、
status=%E3%81%8A%E3%81%AF%E3%82%88%E3%81%86
になります。
シグネチャーを作成するための Base Text では、ここからさらに ERL エンコードされるので、Base Text の中では、
status%3D%25E3%2581%258A%25E3%2581%25AF%25E3%2582%2588%25E3%2581%2586
となります。
このあたり、最初ちょっと気がつきませんでした。
2010年05月16日
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/38139016
この記事へのトラックバック
http://blog.sakura.ne.jp/tb/38139016
この記事へのトラックバック
