instagramAPI公開!OAuth触りました

ついに21歳になりました!itaniです。

みなさん!!
つい先日、iPhoneで気軽に写真を共有できるサービス「instagram」のAPIが一般公開されましたね。
というわけで、さっそくOAuthを触ってみたので自分なりにまとめてみました。

なにができるの?

instagramAPIを使えば以下のようなことが簡単にできます。

  • ユーザー情報を取得
  • ユーザーの写真を取得
  • 写真に対してコメントやいいねを投稿する
  • フォローしている人、フォローされている人を取得

上で挙げたものはほんの一例です。
まだ調査不足ですが、リアルタイム系のAPIも用意されています。面白そうですよね。

OAuthってなんだ!?

最近twitterやfacebookでよく聞く『OAuth認証』という言葉。
果たしてこれはなんなのか。お願いしますgoogle先生。

OAuth (オー オース) は、ブレイン・クックとクリス・メッシーナが始めたオープンプロトコルであり、デスクトップ、モバイル、WebアプリケーションなどにセキュアなAPI認可 (authorization) の標準的手段を提供する。(Wikipediaより)

うむ。難しい。
ものすごく簡単にざっくり言うと、
「ある外部サービスのあなたの情報を使ってアプリケーションを作りたいから、APIを叩かせてもらえないでしょうか?どうぞよろしくお願いいたします。」
みたいな感じです。
この時、認証を外部サービスにゆだねることで、ユーザーはアプリケーション側にパスワードを教えることなく認可させることができます。
これがOAuth認証です!(どーん!)
ざっくりしすぎていてわからなかったそこのあなた!!こちらを参照してください。→ゼロから学ぶOAuth

さっそくさわってみよう!!

アプリケーションの登録

OAuthをするためには、外部サービスにアプリケーションの登録が必要です。
以下のリンクからinstagramの開発者登録を行い、アプリケーションを登録しましょう。

instagram developer

Instagram_01_o.png

赤線を引いた部分をクリックしてアプリケーションを登録します。
この時ログインを求められますが、すでにinstagramのアカウントを所持している方は、そのアカウントでログインできます。
まだinstagramのアカウントを持っていない人は、これを機会に新規登録を行いましょう!
どちらにしろ初めての開発者登録の場合は、以下のような開発者登録画面が表示されます。

Instagram_02_o.png

自分のwebサイトや電話番号など、必要事項を記入すれば開発者登録は完了です。
開発者登録が完了したら、左側のメニューにある「Manage」をクリックしましょう。
以下のようなページが表示されると思います。

Instagram_03_o.png

まだ開発者登録をしたばかりですので、当然登録されているアプリケーションの数は0個です。
では早速、アプリケーションを登録してみましょう!
Register a New Client!!

Instagram_04_o.png

以下の情報を記入するだけで、アプリケーション登録は完了です。

  • アプリケーション名
  • 説明文
  • websiteのURL
  • OAuth認証後のリダイレクトURI

今回はサンプル用に「instagram_api_test」というアプリケーションを一つ作ってみました。
登録が完了すると以下のように、Manageページにアプリケーションが表示されます。

Instagram_05_o.jpg

ここで重要になってくるのが、「CLIENT ID」「CLIENT SECRFET」この2つです。
これさえそろえばこっちのものです。OAuth認証を行う準備は整いました。

APIを叩くには??

「アプリケーションの登録も完了したし、さっそくAPIを叩いてあんなことやこんなことをやってみよー。ぐへへ」という不埒な妄想に浸っているそこのあなた!!そうは問屋が卸しません。
APIを叩くには、アプリケーションに対する、ユーザー固有のaccess_tokenが必要になります。

access_tokenの取得

access_tokenを取得するためにはユーザーに認証してもらう必要があります。
そう。ここで出てくるのがOAuth認証です!
この認証は上の方でも述べましたがinstagram側で行ってもらいます。
ですので、まずは認証のためのURLを取得してユーザーにはさっさとそっちに行ってもらいましょう。

認証URL

https://api.instagram.com/oauth/authorize/?client_id=CLIENT ID&redirect_uri=REDIRECT URI&response_type=code

認証URLはたったこれだけです。
client_idやredirect_uriの値は、アプリケーションを登録した際に発行したものを指定します。
twitterとかではredirect_uriはアプリケーション側で好きに設定できましたが、instagramはそうもいかないみたいです。
アプリケーションを登録した際のredirect_uri以外のuriを設定した場合、Exceptionが返ってきます。
正しいURLでアクセスした場合、以下のようなページに遷移します。

Instagram_06_o.png

Scope
認証URLを生成するときに、scopeを指定することができます。
scopeとは、このアプリケーションに対するAPIの許容範囲のことです。
現在、instagramAPIのscopeは以下の4種類があるそうです。

basic
基本的なユーザ情報へのアクセスができる。(フォロー一覧、写真一覧etc.)
comments
写真に対してコメントを投稿・削除できる
relationships
他人をフォローしたり、自分のフォロワーから外したりすることができる
likes
写真に対していいね!の投稿・削除ができる

デフォルトではbasicが指定されています。
とりあえず全部指定してみよう。ということで試していましたが意外なところで落とし穴がありました。
ここ重要です。テストに出ます。
instagramの公式ドキュメントには、複数指定する場合は「+」でつなげてパラメーターで渡す。と書いてありましたが、その通りにやるとExceptionが返ってきます。
いろいろ試してみた結果、「+」でつなげるのではなく半角スペースが正しい模様です。

すみません。盛大に勘違いしていました。
指摘をいただいたので調べてみたところ、scopeを指定している部分では、phpのhttp_build_query()を使っていたので半角スペースは「+」にエンコードされていました。
つまり、僕が失敗していた原因は、「+」文字をさらにエンコードしていたために、Exceptionが返ってきてしまっていたわけです。
instagramのドキュメントはこれっぽっちも間違っておりませんでした!!

以下がscopeを全部指定した場合のURLと認証画面です。

https://api.instagram.com/oauth/authorize/?client_id=CLIENT ID&redirect_uri=REDIRECT URI&response_type=code&scope=basic+relationships+comments+likes

Instagram_07_o.png

認証画面にてユーザーがYesをクリックすると、instagram側は設定されているredirect_uriに遷移しようとします。
この時instagramはredirect_uriにcodeというパラメータを付与してくれます。
このcodeを使用してアプリケーション側はaccess_tokenを取得します。

Redirect URI

http://your-redirect-uri?code=CODE

access_token取得URL

https://api.instagram.com/oauth/access_token

access_tokenを取得するためには以下のパラメーターが必要です。

client_id=CLIENT ID
client_secret=CLIENT SECRET
grant_type=authorization_code
redirect_uri=YOUR-REDIRECT-URI
code=CODE

requestMethodはPOSTを指定しましょう。GETで取得しようとすると怒られます。
正しく取得できた場合には以下のようなjsonデータが返ってきます。

{
        "access_token": "*********************************************", 
        "user": {
                "username": "w650", 
                "profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_1370024_75sq_1296898384.jpg", 
                "id": "1370024", 
                "full_name": ""
        }
}

access_tokenと一緒に、ユーザー情報も返ってきました。嬉しい限りです。

これですべての準備が整った!!

ついに念願のaccess_tokenを手に入れました。
「これでAPI叩き放題だぜ。フゥワッフゥワッ!」と発狂しているそこのあなた!!

You are limited to 5000 requests per hour per access_token or client_id overall

なん・・・・だと・・・・。
どうやらinstagramは同じaccess_token、もしくは同じclient_idからのリクエストは、一時間の間に5000回までしか受け付けないそうですね。
access_tokenならまだしも、client_idで制限されちゃうのはつらいですね。
アプリケーションに一時間の間に5000人以上訪れたらアウトということでしょうか?
僕の翻訳間違いであってほしいです。

いざ!APIを叩いてみるべし!!

前置きがすごく長くなってしまいましたが、いよいよAPIを叩いてみようと思います。
instagramのAPIには大きく分けて以下のものに分類されるようです。

USERS
ユーザー関連のAPI
RELATIONSHIPS
フォロー、フォロワー関連のAPI
MEDIA
写真関連のAPI
COMMENTS
コメント関連のAPI
LIKES
いいね!関連のAPI
TAGS
タグ関連のAPI
LOCATIONS
位置情報関連のAPI

とはいえ、access_tokenを取得してしまえば、もう難しくはありません。
後はドキュメントに書いてある通りに、それぞれのAPIにaccess_tokenをパラメーターに含ませてやるだけです。

例えばこんな感じ。

https://api.instagram.com/v1/users/self/media/recent?access_token=**********************************

ドキュメントそのまんまですね。
これだけで自分の写真を新着順で取得できます。


stdClass Object
(
    [pagination] => stdClass Object
        (
            [next_url] => https://api.instagram.com/v1/users/1370024/media/recent?access_token=***********************&max_id=15127530
            [next_max_id] => 15127530
        )
 
    [meta] => stdClass Object
        (
            [code] => 200
        )
 
    [data] => Array
        (
            [0] => stdClass Object
                (
                    [tags] => Array
                        (
                        )
 
                    [type] => image
                    [location] => stdClass Object
                        (
                            [latitude] => 35.3209864
                            [id] => 66212
                            [longitude] => 139.5535169
                            [name] => 鎌倉どんぶりカフェ bowls
                        )
 
                    [comments] => stdClass Object
                        (
                            [count] => 0
                            [data] => Array
                                (
                                )
 
                        )
 
                    [filter] => X-Pro II
                    [created_time] => 1297424779
                    [link] => http://instagr.am/p/BhmsT/
                    [likes] => stdClass Object
                        (
                            [count] => 0
                            [data] => Array
                                (
                                )
 
                        )
 
                    [images] => stdClass Object
                        (
                            [low_resolution] => stdClass Object
                                (
                                    [url] => http://distillery.s3.amazonaws.com/media/2011/02/11/d4356b8de7c64ad09c09d9b7753d15ec_6.jpg
                                    [width] => 306
                                    [height] => 306
                                )
 
                            [thumbnail] => stdClass Object
                                (
                                    [url] => http://distillery.s3.amazonaws.com/media/2011/02/11/d4356b8de7c64ad09c09d9b7753d15ec_5.jpg
                                    [width] => 150
                                    [height] => 150
                                )
 
                            [standard_resolution] => stdClass Object
                                (
                                    [url] => http://distillery.s3.amazonaws.com/media/2011/02/11/d4356b8de7c64ad09c09d9b7753d15ec_7.jpg
                                    [width] => 612
                                    [height] => 612
                                )
 
                        )
 
                    [caption] => stdClass Object
                        (
                            [created_time] => 1297424782
                            [text] => 生姜焼きどーん!!
                            [from] => stdClass Object
                                (
                                    [username] => w650
                                    [profile_picture] => http://distillery.s3.amazonaws.com/profiles/profile_1370024_75sq_1296898384.jpg
                                    [id] => 1370024
                                    [full_name] => 
                                )
 
                            [id] => 30606942
                        )
 
                    [user_has_liked] => 
                    [id] => 25586451
                    [user] => stdClass Object
                        (
                            [username] => w650
                            [profile_picture] => http://distillery.s3.amazonaws.com/profiles/profile_1370024_75sq_1296898384.jpg
                            [id] => 1370024
                            [full_name] => 
                        )
 
                )
 
        )
 
)

一つの写真に対して、かなりの情報を返してくれますね。
位置情報や、いいね!やコメント。いろんなことができそうです。
next_urlにいたってはそのまま叩けば、2ページ目が取得できます。
簡単にページャが作れますね。至れり尽くせりです。

おわり

長くなっちゃったので、今日はここまでにします!
カッコいいViewerとか、位置情報入力して地図上に写真表示させるとか。なんかアプリケーション作ってみたいですね。
次はリアルタイム系のAPIに関してもっと調査してみようと思います!!

カヤックでは写真好きな技術者も募集しています!

追記

貴重な追加意見もいただいたので、追記しておきます。

  • クロール/キャッシュNG
  • アプリ名に「Instagram」は使えない

2011 3/2 Scopeの部分を修正しました。