2010年10月2日土曜日

OAuth/Twitter API で画像をアップロードする方法

「これで上手く行ったよ」という記事を検索で見つけられなかったため書きました。 このエントリーでは curl を使わずに HTTP リクエストを生書きして OAuth/Twitter API を叩きます。

目次

通常のHTTPのGET

いきなり画像のアップロードではなく、最初は簡単に GET メソッドを用いたサンプルをリクエストしてみます。

GET /index.html HTTP/1.1\r\n
Host: example.com\r\n
\r\n

\r\n は改行を意味します(それぞれキャリッジリターン、ラインフィード)。 最終行には空の \r\n を送り、終端であることを伝えます。

Twitter API の GET

Twitter API を叩く場合も内容に込み入った変化はありません。 Authorization: に各パラメータを列挙し、 Expect: を追加します。 接続先は http://api.twitter.com/1/statuses/user_timeline.xml で、ユーザのタイムラインを取得します。

GET /1/statuses/user_timeline.xml HTTP/1.1\r\n
Host: api.twitter.com\r\n
Authorizatoin: OAuth realm="http://api.twitter.com/", oauth_consumer_key="...", ...(略)\r\n
Expect:\r\n
\r\n

Twitter API の POST

次に POST の例として http://api.twitter.com/1/statuses/update.xml に接続してツイートします。

POST /1/statuses/update.xml HTTP/1.1\r\n
Host: api.twitter.com\r\n
Expect:\r\n
Content-Length: 370\r\n
\r\n
oauth_consumer_key=...&oauth_nonce=4f32feab49a2b65297da1827590be1ae&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1285900976&oauth_token=...&oauth_version=1.0a&status=%E5%A4%A7%E4%B8%88%E5%A4%AB%E3%81%A0%E3%80%81%E5%95%8F%E9%A1%8C%E3%81%AA%E3%81%84&oauth_signature=...

前回まで終端を表していた \r\n の空行の後ろに POST するデータを追加します。 認証に必要なデータはメッセージボディに含めるため、Authorization: は無くても叩けます。 Content-Length はメッセージボディの長さです。

Twitter API で画像をアップロード

最後に「画像のアップロード」は http://api.twitter.com/1/account/update_profile_image.xml に繋いで、プロフィール画像を更新します。

POST /1/account/update_profile_image.xml HTTP/1.1\r\n
Host: api.twitter.com\r\n
Expect:\r\n
Authorization: OAuth realm="http://api.twitter.com/", oauth_consumer_key="...", ...(略)\r\n
Content-Type: multipart/form-data; boundary=--poochin_boundary\r\n
Content-Length: 2272\r\n
\r\n
----poochin_boundary\r\n
Content-Disposition: form-data; name="image"; filename="test2.jpg"\r\n
Content-Type: image/jpeg\r\n
\r\n
����JFIFHH��C...(略)\r\n
----poochin_boundary--

先ほどの POST と違う点

  1. Authorization: を追加
  2. signature の作成に image データを含めない
  3. Content-Type: multipart/form-data の追加
  4. multipart/form-data 形式でメッセージボディを記述する

1. Authorization: を追加

先ほどの POST ではメッセージボディで認証用のデータを送れましたが、今回はその部分で画像データを送るため Authorization: を使います。

2. signature の作成に image データを含めない

画像をアップロードする時は signature の作成に image データは含めません。 含めるとあの恐ろしい Incorrect signature が出力されます。

3. Content-Type: multipart/form-data の追加

画像アップロード系の API では multipart/form-data 形式で送信します。 "Note that this method expects raw multipart data, not a URL to an image." - http://dev.twitter.com/doc/post/account/update_profile_image そのため Content-Type に multipart/form-data と記述します。 また boundary を定義します(参考: エンコードのタイプとファイル送信)。 この例では boundary=--poochin_boundary としておきます。

4. multipart/form-data 形式でメッセージボディを記述する

メッセージボディを multipart/form-data 形式で記述します。

--(boundary)\r\n
Content-Disposition: form-data; name="name"; filename="filename"\r\n
Content-Type: (Mime-Type)\r\n
\r\n
(ファイルの中身)\r\n
--(boundary)--

先頭に boundary を書きます。 boundary=--poochin_boundary と定義したので ----poochin_boundary を書く。 終端の boundary は --(boundary)-- と書くので ----poochin_boundary-- と書きました。

name="name" の部分はパラメータ名 filename="filename" を指定するとこのデータをファイルのアップロードと解釈してくれます。

Content-Type: は指定しなくてもアップーロード出来ますが、指定する場合は Mime-type を記述します。

「(ファイルの中身)」はそのままのデータを送ります(UrlEncodeもしない)。

以上が Twitter で画像をアップロードする際の注意点です。

参考までに上記の3通りを実行するコードを github にアップロードしました。 github - eduwitter_lite.php


参照.

TwitterAPIでimageが上手く扱えない [d.hatena.ne.jp/Kome_Mizuchi]
Update profile image API using OAuth [groups.google.co.jp]

Form content types [www.w3.org]
Requestの署名(signature の作成 #9.1) [tzmtk.pbworks.com]
もいちどイチから! HTTP基礎訓練中 連載インデックス [www.atmarkit.co.jp/]

0 件のコメント:

コメントを投稿