Instagram APIでwebサービスを作りたい全ての人に向けて書きました
- 2014.07.08(Tue) 07:00
- WEB制作
写真共有SNSとして、確固たる地位を築いた「Instagram」。今回は、この「Instagram APIの使い方」を初心者向けにまとめて、日本語マニュアルを作成してみました。有名人、一般人、そして企業が投稿した何十億もの写真を利用して、webサービスを作ってみませんか?
「APIって何…」という方でも、「データを取得して動かす面白さ」を体験してもらえるように、コピペで使えるサンプルコードを多数用意しました。ぜひ、この機会にInstagramのAPIで何か始めてみてはいかがでしょうか!?
Instagram Developers Instagram
目次
- アプリケーションを登録する
- クライアントID、クライアントシークレットを使ってOAuth認証をする
- ユーザー [User]
- ユーザープロフィールを取得する
- ユーザーをキーワード検索する
- フォローしているユーザーを取得する
- フォロワーを取得する
- リクエスト(フォロー申請)しているユーザーを取得する
- 「ユーザーリスト」のJSONデータ
- サンプルプログラム
- メディア [Media]
- タイムラインを取得する
- ユーザーのタイムラインを取得する
- ライクを付けた作品を取得する
- 人気上昇中の作品を取得する
- 「位置情報」と「投稿時期」で作品検索する
- タグで作品を取得する
- 「場所ID」で作品を検索する
- 「ジオID」で作品検索する
- 「メディアリスト」のJSONデータ
- サンプルプログラム
- 埋め込み用HTMLコードを生成しよう!
- 写真にタグ付けされたユーザーのアイコンを重ねてみよう!
- つながり [Relationship]
- コメント [Comment]
- ライク [Like]
- メタデータの検索
- リアルタイムAPI
- リアルタイム通知に指定できる条件
- リアルタイム通知を登録する
- リアルタイム通知の登録状況を確認する
- リアルタイム通知を削除する(取り消す)
- リアルタイム通知を受け取る!
- 「X-Hub-Signature」を利用した認証をする
- サンプルプログラム
- 「Enforce signed header」を有効にする
- Instagram APIを利用したwebサービスいろいろ
- INUSTAGRAM
- jLeaguram
- IROSTAGRAM
- Bijostagram
- photoll
- i-am-cc.org
- 1/365gram
- Marimelody wears dress in November.
- ネット上にあるInstagram APIの解説記事について
- Instagram APIでwebサービスを作ろう!
1アプリケーションを登録する
この「APIまとめコーナー」ではお馴染みになっていますが…、InstagramのAPIを利用するためには、まず「アプリケーションの登録」を行なう必要があります。APIの利用に必要な「クライアントID」「クライアントシークレット」を取得しましょう。
1-1アカウントを取得する
アプリケーションを登録するには、Instagramのユーザーアカウントが必要です。まだ持っていない方は取得して下さい。WEB版にはアカウントの登録機能がありません。ユーザーアカウントは「iOSアプリ」「Androidアプリ」のいずれかを下記からダウンロードして、登録して下さい。
iOS版 Instagram
Android版 Instagram
1-2アプリケーションを登録する
アカウントを用意したら、アプリケーションを登録していきます。開発者向け画面の右上にあるメニューを見て下さい。まずは「ログイン」から、用意したユーザーアカウントでログインします。次に「アプリケーションを管理」から、アプリケーション管理画面に進んで下さい。下記リンクからもアクセスできます。
ログイン Instagram
アプリケーションを管理 Instagram
1-3開発者プロフィールを登録する
初回の方は、開発者プロフィールの登録画面に進みます。webサイトと電話番号、APIを利用する目的を入力し、API利用規約に同意の上、「登録」をクリックします。サンプル画像はクリックで拡大できます。Instagram APIの利用規約については、下記ページをご確認下さい。
API Terms of Use Instagram
1-4管理画面を確認する
「アプリケーションを管理」という画面に進みました。ここが、Instagram APIを利用する上で拠点となるページなので、1クリックでアクセスできるようにブックマークしておくと便利です。ここには登録したアプリが掲載されていきます。まずは1つ目のアプリを登録してみましょう。「新しいアプリを登録」をクリックして下さい。
1-5アプリ情報を入力する
アプリの情報入力画面に移動します。APIを使ってどんなアプリを作成するのか、情報を入力していきます。初回は個人的なテスト用アプリだと思うので、サンプル画像のように大まかな内容でかまいません。「OAuth redirect_uri」には、後ほど作成する「アプリ認証用プログラム」の設置先URLを入力して下さいね。全て入力したら、Captcha(画像の文字をフォームに入力する)を設定後、「Register」をクリックします。画像はクリックで拡大できます。
なお、セキュリティ上の問題から「Disable implicit OAuth」にはチェックを入れておき、また、「まだ未段階」という意味で「Enforce signed header」にはチェックを入れないでおいて下さい。
非常にざっくり説明すると、前者にチェックを入れるとクライアント側(Javascriptなど)だけで認証することができなくなります。後者にチェックを入れると、APIリクエストに「独自の署名」が必要になります。後者について興味のある方は「Enforce signed headerを有効にする」の章をご参考下さい。webサービスのユーザーが増え始め、人気サービスになってから意識すればいいレベルのことだと思います。2つの設定は、いつでも変更できます。
1-6クライアントID、クライアントシークレットを確認する
アプリの登録に成功すると、一覧画面に登録したアプリの情報が加わります。この内、「クライアントID(CLIENT ID)」「クライアントシークレット(CLIENT SECRET)」が、APIリクエストの上で必要になってくるので、誰にも知られないように管理(メモ)して下さいね!画像はクリックで拡大できます。
2クライアントID、クライアントシークレットを使ってOAuth認証をする
前章までで、APIの利用に必要な「クライアントID」「クライアントシークレット」を取得しました。続いてこの章では、それらを利用して、ユーザーデータの読み込みなどするために必要な「アクセストークン」を取得します!これらを取得するには「アプリ認証」を行なう必要があります。
2-1Instagramのアプリ認証について
Instagramの「アプリ認証」は、OAuth2.0という規格を採用しています。詳しい流れなどについては、下記ページの公式ドキュメントをご参考下さい。
Authentication Instagram
2-2スコープ(パーミッション)について
Instagram APIには、scopeというパラメータがあります。これは、アプリがユーザーデータにどの程度アクセスできるのか、その「権限」を定めるもので、ユーザーがアプリに許可を与えるかどうかの判断基準にもなります。Instagram APIでwebサービスを作成する際は、適切なscopeを設定しましょう。
| スコープ | 説明 |
|---|---|
| basic | ユーザーに関するデータを読み込むことができます。 |
| comments | コメントを書き込んだり、削除したりできます。 |
| relationships | フォローしたり、アンフォローしたりできます。 |
| likes | 作品にライクを付けたり、取り消したりできます。 |
スコープを設定する方法
スコープを設定するには、ユーザーを「アプリ認証画面」にリダイレクトさせる際の、リクエストURLのscopeパラメータに含めます。複数指定する際は半角スペースをURLエンコードした半角プラス(+)で区切って下さい。
https://...&scope=basic+comments+likes&redirect_uri=...
2-3OAuth2.0認証をするPHPのサンプルプログラム
早速ですが、OAuth2.0認証を利用して、Instagramでアプリ認証を行なうためのサンプルプログラムを紹介します。3〜6行目を設定の上、プログラムを起動して下さい。
$redirect_uriには、「アプリ登録」の際に「OAuth redirect_uri」に入力したURLと同じものを設定して下さい。scopeを設定する際の区切り文字は、URLエンコード済みの+で区切って下さいね。最初はテスト用なので全ての権限を持たせましょう。
PHP版のサンプルプログラム
<?php
//クライアントID・クライアントシークレット・リダイレクトURI・スコープ
$client_id = "7271052d1526476e9ec1f3b4edfb5dea";
$client_secret = "095ac41c924242d2b6c85b30926e9169";
$redirect_uri = "http://syncer.jp/test.php";
$scope = "basic+comments+relationships+likes";
//セッションスタート
session_start();
//[ステップ1] アプリ認証画面でリクエストトークンを取得
if(!isset($_GET['code']) || !is_string($_GET['code']) || empty($_GET['code'])){
//CSRF対策
session_regenerate_id(true);
$_SESSION['state'] = $state = sha1(uniqid(mt_rand(),true));
//ユーザーをアプリ認証画面に飛ばす
header("Location: https://api.instagram.com/oauth/authorize/?client_id={$client_id}&redirect_uri=".rawurlencode($redirect_uri)."&scope={$scope}&response_type=code&state={$state}");
exit;
}
//[ステップ2] リクエストトークンとアクセストークンの交換
if(!isset($_SESSION['state']) || empty($_SESSION['state']) || !isset($_GET['state']) || empty($_GET['state']) || $_SESSION['state'] != $_GET['state']) exit;
//セッション終了
$_SESSION = array();
session_destroy();
//アクセストークンを取得し、JSONをオブジェクト形式に変換
$obj = json_decode(@file_get_contents(
'https://api.instagram.com/oauth/access_token',
false,
stream_context_create(
array('http' => array(
'method' => 'POST',
'content' => http_build_query(array(
'client_id' => $client_id,
'client_secret' => $client_secret,
'grant_type' => 'authorization_code',
'redirect_uri' => $redirect_uri,
'code' => $_GET['code'],
)),
))
)
));
//ユーザーID・ユーザーネーム・ユーザーアイコン・アクセストークン
$user_id = $obj->user->id;
$user_name = $obj->user->username;
$user_picture = $obj->user->profile_picture;
$access_token = $obj->access_token;
//出力
echo "<img src=\"{$user_picture}\" width=\"100\" height=\"100\"><br/>@{$user_name}(ID:{$user_id})さんのアクセストークンは<mark>{$access_token}</mark>です!";
2-4Instagramのアプリ認証の流れ
それでは、サンプルプログラムを使って、Instagramのアプリ認証の流れを見ていきましょう。サンプルプログラムがこのイメージ通りに動かない場合は、設定項目を見直して下さい。
アプリ認証画面
プログラムを起動すると、ユーザーは必要なパラメータを付けて指定のURL(アプリ認証画面)にリダイレクトされ、ここで、アプリの連携を許可します。設定した「アプリ名」や「権限(scope)」がアプリ説明の部分に反映されています。アプリを許可する場合は「Authorize」をクリックして下さい。
アクセストークンの発行
ユーザーは「許可」をすると、リクエストトークン(code)をパラメータに付けて$redirect_uriにリダイレクトされます。それを受けて、サンプルプログラムはリクエストトークンを付けたパラメータ($_GET["code"])を指定のURLに送ってアクセストークンを取得し(リクエストトークンとアクセストークンの交換)、ブラウザにアクセストークンを出力しています。この「アクセストークン」は、以降のサンプルプログラムで利用するので、誰にも知られないように管理(メモ)して下さい。
Instagram APIを利用して、不特定多数のユーザー向けにwebサービスを作成する場合は、ブラウザに出力するのではなく、ユーザーIDとアクセストークン(念のため暗号化)を関連づけて、データベースに保存するシステム作りが必要になってきます。
Instagramの「ユーザーネーム」と「ユーザーID」の違いについて
Instagramのユーザーデータには、「名前」「ユーザーネーム」「ユーザーID」という異なるデータが含まれています。これからAPIを利用する上で、これらの概念を混同しないように、ざっくりですが説明をしておきます。
まず「名前」は主にブラウザに出力される名前で、私の場合だったら「あらゆ」です。次に「ユーザーネーム」ですが、これは「外向けのID」と言えば分かりやすいでしょうか。Twitterでいう「スクリーンネーム(@arayutw)」のことです。主にプロフィールページのパーマリンクURLやタイムライン上のラベルなどに利用されます。私の場合だったら「arayutw」です。このユーザーネームは一意ですが変更可能です。
最後に、開発者にとって最も重要なのが「ユーザーID」です。これは、「外向け」の「ユーザーネーム」に対して、実質的なIDで、ユーザーのあらゆるデータがこのIDを元に管理されていて、このIDは変更されることがありません。ユーザーに関するデータの呼び出しは基本的にこの「ユーザーID」を指定することになります。私の場合は「1349593219」です。
3ユーザー
前章までで、「クライアントID」「クライアントシークレット」「アクセストークン」を取得してきました。ここからは、それらを利用して、API経由で色々なデータを取得してみましょう。「ユーザーデータ」に関する公式ドキュメントは下記ページをご参考下さい。
User Endpoints Instagram
3-1ユーザープロフィールを取得する
まずは「ユーザープロフィール」の取得方法を紹介します。
リクエスト方法
ユーザープロフィールを取得するには、下記のように組み立てたURLに、GETメソッドでリクエストを送ります。パラメータには「アクセストークン」を指定して下さい。なお、「ユーザーID」にselfを指定すると、「アクセストークンの持ち主」のデータを取得することができて手軽です。
[GET] https://api.instagram.com/v1/users/{ユーザーID}/?access_token={アクセストークン}
取得できるJSONデータ
取得できるJSONデータの構造は下記の通りです。dataプロパティにプロフィール情報が、その中のcountプロパティには「数」に関する情報が含まれています。青文字でコメントを付けてあります。
{
"meta": {
"code": 200 //ステータスコード
},
"data": {
"id": "295878252" //ユーザーID
"username": "arayutw", //ユーザーネーム
"bio": "こんにちは!!", //プロフィール文
"website": "http://syncer.jp", //ウェブサイト
"profile_picture": "http://ima...", //アイコン画像URL
"full_name": "あらゆ", //名前
"counts": {
"media": 21, //写真、動画の合計投稿数
"follows": 0 //フォロー数
"followed_by": 2, //フォロワー数
},
}
}
PHPのサンプルプログラム
下記がユーザープロフィールを取得するためのサンプルプログラムです。3〜4行目の$access_tokenと$user_idを指定して、起動してみて下さい。
<?php
//アクセストークン・取得するユーザーID
$access_token = "1349193219.f92b5f0.e164315a6e2d46e8bdfda261890d3afb";
$user_id = "1349593219"; //[self]でアクセストークンの持ち主
//サンプルID(人気かつ私が好きな有名人ID)
//有吉弘行 487111998
//長澤まさみ 1126358805
//JSONデータを取得し、オブジェクト形式に変換
$obj = json_decode(@file_get_contents("https://api.instagram.com/v1/users/{$user_id}/?access_token={$access_token}"));
//ユーザーID・ユーザーネーム・名前・アイコン・WEBサイト・投稿数・フォロー数・フォロワー数
$id = $obj->data->id;
$screen = $obj->data->username;
$name = $obj->data->full_name;
$icon = $obj->data->profile_picture;
$bio = $obj->data->bio;
$web = $obj->data->website;
$media = $obj->data->counts->media;
$follow = $obj->data->counts->follows;
$follower = $obj->data->counts->followed_by;
//出力
echo "<img src=\"{$icon}\" width=\"100\" height=\"100\"><br/>{$name} @{$screen}(ID:{$id})<br/>投稿数:{$media}、フォロー:{$follow}人、フォロワー:{$follower}人<br/>{$bio}<br/><a href=\"{$web}\">{$web}</a>";
プログラムの実行結果
上記のように、$user_idで指定したユーザーのプロフィールを簡易ではありますが、出力します。Instagramと連携したwebサービスを作成する場合、アイコンやフォロー(フォロワー)数など、重要なデータになってきそうですねー。
3-2ユーザーをキーワード検索する
指定したキーワードでユーザーを検索することができます。2014年7月現在、InstagramのWEB版にはユーザーを検索する機能がないので、単純にこのAPIを利用した検索システムを公開するだけでも立派なwebサービスになりますよ!ただ、日本語キーワードには対応していないようです…。ユーザーを検索するには下記URLに、GETメソッドでリクエストを送ります。
[GET] https://api.instagram.com/v1/users/search
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| q | [必須] キーワード
※ 日本語非対応 |
| count | 取得件数
- [初期値] 20 |
3-3フォローしているユーザーを取得する
指定したIDのユーザーがフォローしているユーザーリストを取得します。下記URLに、GETメソッドでリクエストを送って下さい。relationshipsの権限が必要です。
[GET] https://api.instagram.com/v1/users/{ユーザーID}/follows
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| cursor | 指定したカーソルのページ(○〜○件目)を取得する
※paginationプロパティに含まれる |
| count | 取得件数
- [初期値] 20 |
3-4フォロワーを取得する
指定したIDのユーザーの、フォロワーリストを取得します。下記URLに、GETメソッドでリクエストを送って下さい。relationshipsの権限が必要です。
[GET] https://api.instagram.com/v1/users/{ユーザーID}/followed-by
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| cursor | 指定したカーソルのページ(○〜○件目)を取得する
※paginationプロパティに含まれる |
| count | 取得件数
- [初期値] 20 |
3-5リクエスト(フォロー申請)しているユーザーを取得する
Instagramでは、プロフィールを非公開にしているユーザーをフォローするのに、「リクエスト」を送って承認される必要があります。このAPIでは、自分にリクエストを送っているユーザーリストを取得することができます。「アクセストークンの持ち主」のデータしか取得できないのでご注意下さい。下記URLに、GETメソッドでリクエストを送って下さい。relationshipsの権限が必要です。
[GET] https://api.instagram.com/v1/users/self/requested-by
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| cursor | 指定したカーソルのページ(○〜○件目)を取得する
※paginationプロパティに含まれる |
| count | 取得件数
- [初期値] 20 |
3-6ユーザーリストのJSONデータ
この章で紹介してきたリクエストで取得できるJSONデータの構造は全て同じで、下記の通りになっています。dataプロパティに配列形式で、キーワードにマッチした個々のユーザーデータが格納されています。
cursorは「次ページ」を表すキーです。next_urlのようにパラメータに付けてリクエストすることで、今取得したリストの「次ページ」にあたるデータを取得することができます。
{
"pagination": { //ページネーション(次ページ情報)
"next_url":"https://api.instagram.com/v1/users/1126358805/follows?access_token=295878252.7271052.4e4c3523631545b89678933af444c3fd&count=20&cursor=1404623365815", //次ページのリクエストURL
"next_cursor":"1404623365815" //次ページのカーソル
},
"meta": {
"code": 200 //ステータスコード
},
"data": [
{
"username": "nice", //ユーザーネーム
"bio": "", //紹介文
"website": "", //WEBサイト
"profile_picture": "http://ima...jpg", //アイコン
"full_name": "Eunice Cr", //名前
"id": "94739" //ユーザーID
},
...
]
}
3-7サンプルプログラム
ユーザーリストを取得するためのPHPプログラムは下記の通りです。$request_urlにリクエストURLを、$paramsにパラメータを連想配列形式で指定して、起動します。まず初回は、access_tokenだけを指定してみて下さい。
<?php
//リクエストURL
$request_url = 'https://api.instagram.com/v1/users/search';
//パラメータを配列形式で指定(その後、配列形式のパラメータを文字列に変換)
$params = array(
'access_token' => "295878252.7271052.4e4c3523631545b89678933af444c3fd",
'q' => "japan",
'count' => "5",
);
$query = http_build_query($params);
//JSONデータを取得し、オブジェクト形式に変換
$obj = json_decode(@file_get_contents("https://api.instagram.com/v1/users/search?{$query}"));
//出力
echo "<h1>取得結果</h1>";
//個々のユーザー情報
foreach($obj->data as $item){
//ユーザーID・ユーザーネーム・名前・WEBサイト・紹介文・アイコン
$id = $item->id;
$username = $item->username;
$name = $item->full_name;
$website = ($item->website) ? "<br/><a href=\"{$item->website}\">$item->website</a>" : '';
$bio = ($item->bio) ? "<br/>{$item->bio}" : '';
$icon = $item->profile_picture;
//出力
echo "<p><img src=\"{$icon}\" width=\"100\" height=\"100\"/><br/>{$name}(@{$username}、ID:{$id}){$bio}{$website}</p>";
}
プログラムの実行結果
プログラムを実行すると、キーワードにマッチしたユーザーの一覧が上記図のように表示されます。画像はクリックで拡大することができます。
4メディア
投稿した写真と動画、いわゆる「メディア」のリストデータを取得してみましょう。Instagram APIを利用する上で、最も利用する機会が多いAPIだと思います。メディアリストを取得するには、数種類の方法が存在します。まずはそれらの違いを説明していきます。
Media Endpoints Instagram
4-1タイムラインを取得する
まず自分と自分がフォローしているユーザーのメディアリスト、いわゆるタイムラインのデータを取得する方法です。下記URLに、GETメソッドでリクエストを送ります。
[GET] https://api.instagram.com/v1/users/self/feed
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| count | 取得件数
- [初期値] 20 |
| min_id | 指定したメディアIDより「未来」に投稿されたメディアを取得 |
| max_id | 指定したメディアIDより「過去」に投稿されたメディアを取得 |
4-2ユーザーのタイムラインを取得する
指定したユーザーだけのメディアリストを取得するのにも利用します。下記のように組み立てたURLに、GETメソッドでリクエストを送ります。なお、ユーザーIDにselfを指定すると、「アクセストークンの持ち主」のデータを取得します。
[GET] https://api.instagram.com/v1/users/{ユーザーID}/media/recent/
| パラメータ | 説明 |
|---|---|
| access_token | [どちらか必須] アクセストークン |
| client_id | [どちらか必須] クライアントID |
| count | 取得件数
- [初期値] 20 |
| min_id | 指定したメディアIDより「未来」に投稿されたメディアを取得 |
| max_id | 指定したメディアIDより「過去」に投稿されたメディアを取得 |
| min_timestamp | 指定したUNIX TIMESTAMPより「未来」に投稿されたメディアを取得 |
| max_timestamp | 指定したUNIX TIMESTAMPより「過去」に投稿されたメディアを取得 |
4-3ライクを付けた作品を取得する
「アクセストークンの持ち主」が、ライクを付けたメディアリストを取得することができます。下記URLに、GETメソッドでリクエストを送って下さい。likesの権限が必要です。
[GET] https://api.instagram.com/v1/users/self/media/liked
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| count | 取得件数
- [初期値] 20 |
| max_like_id | 指定したメディアID(ライクを付けたもの限定)より「過去」に投稿されたメディアを取得 |
4-4人気上昇中の作品を取得する
Instagram全体で、人気が上昇しているメディアリストを取得することができます。下記URLに、GETメソッドでリクエストを送って下さい。
[GET] https://api.instagram.com/v1/media/popular
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
4-5「位置情報」と「投稿時期」で作品検索する
「位置情報」「投稿時期」から絞り込んだメディアリストです。下記URLに、GETメソッドでリクエストを送って下さい。
[GET] https://api.instagram.com/v1/media/search
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| lat | 緯度 (経度とセット) |
| lng | 経度 (緯度とセット) |
| distance | 検索する範囲を「メートル」で指定 (緯度、経度とセット)
- [初期値] 1000 - [最大値] 5000 |
| min_timestamp | UNIX TIMESTAMPを指定すると、それより「未来」を検索
- [初期値] 5日前 ※ max_timestampと組み合わせる場合、7日間を超えてはいけない |
| max_timestamp | UNIX TIMESTAMPを指定すると、それより「過去」を検索
- [初期値] なし ※ min_timestampと組み合わせる場合、7日間を超えてはいけない |
4-6タグで作品を取得する
指定した「タグ」が付いたメディアリストを取得することができます。下記URLにGETメソッドでリクエストを送ります。「タグ名」については「タグ名を検索する」の項をご参考下さい。
[GET] https://api.instagram.com/v1/tags/{タグ名}/media/recent
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| count | 取得件数
- [初期値] 20 |
| min_tag_id | 指定したメディアIDより「未来」に投稿されたメディアを取得 |
| max_tag_id | 指定したメディアIDより「過去」に投稿されたメディアを取得 |
4-7「場所ID」で作品を検索する
指定した「場所ID」が付いたメディアリストを取得することができます。下記URLにGETメソッドでリクエストを送ります。「場所ID」については「場所IDを検索する」の項をご参考下さい。
[GET] https://api.instagram.com/v1/locations/{場所ID}/media/recent
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| min_id | 指定したメディアIDより「未来」に投稿されたメディアを取得 |
| max_id | 指定したメディアIDより「過去」に投稿されたメディアを取得 |
| min_timestamp | 指定したUNIX TIMESTAMPより「未来」に投稿されたメディアを取得 |
| max_timestamp | 指定したUNIX TIMESTAMPより「過去」に投稿されたメディアを取得 |
4-8「ジオID」で作品検索する
指定した「ジオID」が付いたメディアリストを取得することができます。「ジオID」とは、Instagramの「リアルタイムAPI」の「Geography」を利用する際に設定した位置範囲を反映したIDのことです。詳しくは「リアルタイム通知を登録する」内の「Geography」の項をご参考下さい。下記URLにGETメソッドでリクエストを送ります。
[GET] https://api.instagram.com/v1/geographies/{ジオID}/media/recent
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| count | 取得件数
- [初期値] 20 |
| min_id | 指定したメディアIDより「未来」に投稿されたメディアを取得 |
4-9「メディアリスト」のJSONデータ
3種類の取得方法のどれも、取得できるJSONデータの構造は下記の通りです。dataプロパティの中に、投稿日順(未来→過去)にソートされたメディアリストのデータが含まれています。「写真」と「動画」のデータが混在していて、「動画」の場合だけ、videoプロパティが存在し、それ以外は同じ構造になっています。
キャプションは、「投稿者による1つ目のコメント」の扱いで、「コメントID」が付与されます。例えば、作品投稿時にキャプションを付けていなくても、作品投稿者がコメント欄にコメントを投稿すれば、1つ目のコメントが「キャプション」と認識されます。
{
"pagination": { //ページネーション(次ページ情報)
"next_url":"https://api.instagram.com/v1/users/295878252/media/recent?access_token=295878252.7271052.4e4c3523631545b89678933af444c3fd&count=20&max_id=657824365424071902_295878252", //次ページのリクエストURL
"next_max_id":"657824365424071902_295878252" //次ページのMAX ID
},
"meta": {
"code": 200 //ステータスコード
},
"data": [ //個々のメディアデータ(配列形式)
{
"id": "720185501884273958_295878252", //メディアID
"attribution": null,
"tags": [ //タグ(配列形式)
"タグ2",
"タグ"
],
"type": "image", //メディアタイプ(写真=image、動画=video)
"location": {
"latitude": 35.79829193, //緯度
"longitude": 139.774303845, //経度
"name": "舎人公園(とねりこうえん)", //場所名
"id": 222253553 //場所ID
},
"comments": { //作品に付いたコメント情報
"count": 2, //コメント数
"data": [ //個々のコメントデータ(配列形式で最新8件まで)
{
"created_time": "1404606991", //投稿時間
"text": "コメントでございます。", //コメントテキスト
"from": {
"username": "arayutw", //ユーザーネーム
"profile_picture": "http://ima...", //アイコン画像URL
"id": "295878252", //ユーザーID
"full_name": "あらゆ" //名前
},
"id": "758220856965125930" //コメントID
},
...
]
},
"filter": "Normal", //加工フィルターの種類
"created_time": "1400072823", //メディアの投稿時間
"link": "http://instagram.com/p/qFwSMlMtds/", //メディアページのURL
"likes": {
"count": 2, //メディアへのライク数
"data": [ //ライクを付けた個々のユーザーデータ(配列形式)
{
"username": "arayutw", //ユーザーネーム
"profile_picture": "http://ima...", //アイコン画像URL
"id": "295878252", //ユーザーID
"full_name": "あらゆ" //名前
},
...
]
},
"images": { //メディアの画像情報(「動画」の場合はサムネイル情報)
"low_resolution": { //306x306
"url": "http://sco...", //画像URL
"width": 306, //幅
"height": 306 //高さ
},
"thumbnail": { //150x150
...
},
"standard_resolution": { //640x640
...
}
},
"videos": { //メディアの動画情報(「写真」の場合は存在しない)
"low_bandwidth": null,
"low_resolution": { //480x480
"url": "http://scon...mp4", //動画URL
"width": 480, //幅
"height": 480 //高さ
},
"standard_resolution": { //640x640
...
}
},
"users_in_photo": [ //タグ付けされたユーザー情報(配列形式)
{
"position": { //写真内の位置座標
"y": 0.4296875, //Y座標(「高さ」にこの値をかける)
"x": 0.7453125 //X座標(「幅」にこの値をかける)
},
"user": { //タグ付けされたユーザー
"username": "syncerjp", //ユーザーネーム
"profile_picture": "http://phot...jpg", //アイコン画像URL
"id": "1349593219", //ユーザーID
"full_name": "ハナ" //名前
}
},
...
],
"caption": { //作品のキャプション(1つ目の投稿者コメント)
"created_time": "1404606730", //キャプションの作成日
"text": "コメントです。", //キャプションテキスト
"from": { //キャプション作成者の情報
"username": "arayutw", //ユーザーネーム
"profile_picture": "http://ima...jpg", //アイコン画像URL
"id": "295878252", //ユーザーID
"full_name": "あらゆ" //名前
},
"id": "758218671791462046" //コメントID
},
"user_has_liked": false, //自分(アクセストークンの持ち主)がライクしてるか?
"user": { //メディア投稿者の情報
"username": "arayutw", //ユーザーネーム
"website": "", //WEBサイト
"profile_picture": "http://ima...jpg", //アイコン画像URL
"full_name": "あらゆ", //名前
"bio": "私の名前はあらゆです。", //紹介文
"id": "295878252" //ユーザーID
}
},
...
]
}
4-10サンプルプログラム
メディアリストを取得するPHPのサンプルプログラムを用意しました。リクエストURLを$request_urlに、パラメータを$paramsに連想配列形式でセットしてから起動してみて下さい!
<?php
//リクエストURL
$request_url = "https://api.instagram.com/v1/users/self/media/recent/";
//パラメータを配列形式で指定(その後、配列形式のパラメータを文字列に変換)
$params = array(
'access_token' => "295878252.7271052.4e4c3523631545b89678933af444c3fd",
'count' => "24",
);
$query = http_build_query($params);
//JSONデータを取得し、オブジェクト形式に変換
$obj = json_decode(@file_get_contents("{$request_url}?{$query}"));
//個々のメディア情報
foreach($obj->data as $item){
//ID・リンク・投稿時間・コメント数・ライク数・フィルター・タグ・埋め込み用HTMLコード
$id = $item->id;
$link = $item->link;
$created = date('Y/m/d H:i',$item->created_time);
$comments = (isset($item->comments->count)) ? $item->comments->count : 0;
$likes = (isset($item->likes->count)) ? $item->likes->count : 0;
$filter = $item->filter;
$tags = (isset($item->tags) && $item->tags) ? implode('、',(array)$item->tags) : 'なし…';
$embed = "<iframe src=\"{$link}embed/\" width=\"612\" height=\"710\" frameborder=\"0\" scrolling=\"no\" allowtransparency=\"true\"></iframe>";
//メディアファイルのURL(画像・動画)
$image_file = $item->images->standard_resolution->url;
$image_width = $item->images->standard_resolution->width;
$image_height = $item->images->standard_resolution->height;
$movie_file = (isset($item->videos->standard_resolution->url)) ? "<br/>動画ファイルURL:".$item->videos->standard_resolution->url : '';
//写真にタグ付けされたユーザー達の情報
$users = $users_embed = '';
foreach($item->users_in_photo as $userdata){
//ユーザーID・ユーザーネーム・名前・アイコン・X座標・Y座標
$tag_user = $userdata->user->id;
$tag_username = $userdata->user->username;
$tag_name = $userdata->user->full_name;
$tag_icon = $userdata->user->profile_picture;
$tag_icon_width = 75;
$tag_icon_height = 75;
$x_position = ($image_width * $userdata->position->x) - ($tag_icon_width / 2);
$y_position = ($image_height * $userdata->position->y) - ($tag_icon_height / 2);
$users .= "<br/>{$tag_name}(@{$tag_username})さんが、[X:{$x_position}][Y:{$y_position}]の位置に映ってます!";
$users_embed .= "<img src=\"{$tag_icon}\" width=\"{$tag_icon_width}\" height=\"{$tag_icon_height}\" style=\"position:relative;top:{$y_position}px;left:{$x_position}px;\">";
}
//場所情報
$geo = '';
if(isset($item->location) && $item->location){
//緯度・経度・名前
$lat = $item->location->latitude;
$lon = $item->location->longitude;
$name = $item->location->name;
$geo = "<br/>場所:<a href=\"https://www.google.co.jp/maps/@{$lat},{$lon},17z\" target=\"_blank\">{$name}</a>";
}
//画像[ユーザーがタグ付けされてる場合はアイコンを重ねる]
echo ($users) ? "<div style=\"min-height:{$image_height}px\"><img src=\"{$image_file}\" width=\"{$image_width}\" height=\"{$image_height}\" style=\"position:absolute\">{$users_embed}</div>" : "<img src=\"{$image_file}\" width=\"{$image_width}\" height=\"{$image_height}\">";
//出力
echo "<br/>メディアID:{$id}<br/>投稿日時:{$created}<br/>タグ:{$tags}<br/>ライク数:{$likes}人、コメント数:{$comments}<br/>リンクURL:<a href=\"{$link}\" target=\"_blank\">{$link}</a>{$geo}{$users}<br/>画像ファイルURL:{$image_file}{$movie_file}<br/>埋め込み用HTML:{$embed}<hr/>";
}
プログラムの実行結果
画像をクリックし、拡大してみて下さい。個々のメディアに付与された情報が簡易的に出力されます。よろしければ、これらのデザインをカスタマイズするなどして、ご利用下さいね。
4-11埋め込み用HTMLコードを生成しよう!
Instagramには、上記のような埋め込み用コンテンツが用意されています。下記埋め込み用HTMLコードの赤文字部分を、APIで取得できる「メディアページのURL」とそのまま差し替えることで、既に適切にデザインされた画像や動画を出力することができます。
<iframe src="{メディアページのURL}embed/" width="612" height="710" frameborder="0" scrolling="no" allowtransparency="true"></iframe>
4-12写真にタグ付けされたユーザーのアイコンを重ねてみよう!
Instagramには、写真の好きな位置にユーザーをタグ付けできる機能があり、APIを利用して、それらタグ付けされたユーザー達のデータを取得することができます。IDや名前だけではなく「写真のどの位置にタグ付けされたか」を示す、「X座標」「Y座標」を取得することができるので、上記のように、その位置にユーザーアイコンを重ねる、といった遊び要素を実現できます。
取得できる「X座標」「Y座標」の値は、それぞれ「0.7453125」「0.4296875」といったように割合になっています。例えば、表示する画像のサイズが640x640ならば、まずは、それぞれを掛け合わせて640 * 0.7453125 = 477、640 * 0.4296875 = 275と、ピクセル値を算出しましょう。
算出したそれぞれのピクセル値のまま位置指定すると、指定した位置には、アイコンの「左端上端」がきます。これをアイコンの中心が来るようにするには、アイコンの幅、高さ、それぞれの2分の1の値を引いてあげましょう。具体的には次のような計算になります。
[X座標] (640 * 0.7453125) - (アイコンの幅 / 2) [Y座標] (640 * 0.4296875) - (アイコンの高さ / 2)
このように取得できた「X座標」「Y座標」と、スタイルシートのposition、top、leftを組み合わせることで、上記サンプルのように、適切にアイコンを配置することができます。この機能はサンプルプログラムにも備わっているので、参考にしてみて下さい。ちなみに本家Instagramアプリだと、アイコンではなく、名前テキストが配置されていますね。
CSS : positionの「absolute」「relative」「fixed」のリファレンス CSS Lecture
positionを利用した、写真とアイコンの重ね合わせをするのに最適な情報が、丁寧に解説されています。
5つながり
この章では、特定のユーザーとの「つながり」を調べたり、フォロー、アンフォローなどする方法を紹介していきます。
Relationship Endpoints Instagram
5-1指定したユーザーとの「つながり」を調べる
指定したユーザーと自分(アクセストークンの持ち主)の間にはどのような「つながり」があるのか、下記URLにGETメソッドでリクエストを送ることで調べることができます!relationshipsの権限が必要です。
[GET] https://api.instagram.com/v1/users/{ユーザーID}/relationship
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
取得できるJSONデータ
取得できるJSONデータは下記の通りです。outgoing_statusには「自分から指定ユーザーに対して」の、incoming_statusには「指定ユーザーから自分に対して」の「つながり」の情報が格納されています。
{
"meta": {
"code": 200 //ステータスコード
},
"data": {
"outgoing_status": "none", //自分から見た指定ユーザーへの関係
"incoming_status": "none" //指定ユーザーから見た自分への関係
"target_user_is_private": false, //指定ユーザーは非公開アカウントか?
}
}
outgoing_statusの値
| パラメータ | 説明 |
|---|---|
| follows | 自分は指定ユーザーをフォローしている |
| requested | 自分は指定ユーザーにフォローリクエストをしている |
| none | 何の関係もない |
incoming_statusの値
| パラメータ | 説明 |
|---|---|
| followed_by | 自分は指定ユーザーからフォローされている |
| requested_by | 自分は指定ユーザーからフォローリクエストをされている |
| blocked_by_you | 指定ユーザーは、自分にブロックをされている |
| none | 何の関係もない |
サンプルプログラム
「つながり」を調べるPHPのサンプルプログラムを用意しました。$access_tokenと$user_idをセットしてから起動してみて下さい!
<?php
//アクセストークン・指定ユーザー・サンプルユーザーID
$access_token = "";
$user_id = "1349593219";
//ジャスティン・ビーバー 6860189
//ビヨンセ 247944034
//池澤あやか(ガチでギークな女優) 10597660
//JSONデータを取得し、オブジェクト形式に変換
$obj = json_decode(@file_get_contents("https://api.instagram.com/v1/users/{$user_id}/relationship?access_token={$access_token}"));
//出力内容を設定
$data = array(
'follows' => 'フォローしています!',
'requested' => 'フォローリクエストしています!',
'none' => '特に何もないみたいです…。',
'followed_by' => 'フォローされています!',
'requested_by' => 'フォローリクエストされています!',
'blocked_by_you' => 'ブロックを受けてるみたいです。(あなたがこのユーザーをブロックしている)',
);
//出力
echo "<p>自分はこのユーザーに対して、{$data[$obj->data->outgoing_status]}</p><p>このユーザーは自分に対して、{$data[$obj->data->incoming_status]}</p>";
プログラムの実行結果
プログラムを実行すると、このように、指定ユーザーとの「つながり」が表示されます。イマイチ使いどころに悩むAPIではありますが、特定ユーザーとの関係を厳密に調べたい場合に重宝するかもしれませんね。サンプル画像はクリックすると拡大できます。
5-2指定したユーザーとの「つながり」を変更する
指定したユーザーをフォロー(アンフォロー)したり、ブロック(アンブロック)したりと、「つながり」を変更することができます。下記URLに、POSTメソッドでリクエストを送ります。relationshipsの権限が必要です。
[POST] https://api.instagram.com/v1/users/{ユーザーID}/relationship
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| action | [必須] 「つながり」をどう変更するか?
- [follow] フォローする - [unfollow] フォローを解除する - [block] ブロックする - [unblock] ブロックを解除する - [approve] フォローリクエストを受け入れる - [ignore] フォローリクエストを無視する |
取得できるJSONデータ
このリクエストが成功すると、下記構造のJSONデータを取得できます。dataプロパティには、リクエスト後の関係を示すデータが格納されています。このデータに関しては、前項をご参考下さい。
{
"meta": {
"code": 200 //ステータスコード
},
"data": { //処理後の関係
"incoming_status": "none"
}
}
サンプルプログラム
以上を踏まえて、用意したのが下記のサンプルプログラムです。$user_idと$paramsをセットしてから起動してみて下さい!サンプルに私のユーザーIDを設定してますので、煮る(フォローする)なり焼く(ブロックする)なりお試し下さい…。「リクエストに成功しました!」とブラウザに出力されたら、Instagramで関係が変更されているか確認してみて下さいね!
<?php
//相手のユーザーID・サンプルID(私が好きな有名人のID…)
$user_id = "295878252";
//パラメータを連想配列形式で指定(その後、配列形式のパラメータを文字列に変換)
$params = array(
'access_token' => "295878252.7271052.4e4c3523631545b89678933af444c3fd",
'action' => "follow",
);
//POSTリクエストを送信し、返ってきたJSONデータをオブジェクト形式に変換
$obj = json_decode(@file_get_contents(
"https://api.instagram.com/v1/users/{$user_id}/relationship",
false,stream_context_create(array('http' => array(
'method' => 'POST',
'content' => http_build_query($params),
)))
));
//ステータスコードが200だったら成功
if(isset($obj->meta->code) && $obj->meta->code == 200) echo "リクエストに成功しました!";
6コメント
Instagram APIでは作品の投稿はできませんが、コメントの投稿ができます。この章では、APIを通して、コメントリストを取得する方法、そしてコメントを投稿する方法を紹介します。
Comment Endpoints Instagram
6-1コメントの取得
指定した作品のコメントリストを取得します。「メディアリスト」で取得するJSONにも、コメントデータが含まれますが、最新の8件までしか含まれません。このAPIでは、全てのコメントリストを取得することが可能です。commentsの権限が必要です。
[GET] https://api.instagram.com/v1/media/{メディアID}/comments
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
取得できるJSONデータ
コメントリストのJSONデータは下記の通りです。
{
"meta": {
"code": 200 //ステータスコード
},
"data": [ //個々のコメントデータ(配列形式)
{
"created_time": "1404650980", //投稿時間
"text": "可愛いです。", //コメントテキスト
"from": {
"username": "sakoy_village", //ユーザーネーム
"profile_picture": "http...jpg", //アイコン
"id": "1418245620", //ユーザーID
"full_name": "" //名前
},
"id": "758589860481258843" //コメントID
},
...
]
}
サンプルプログラム
「つながり」を調べるPHPのサンプルプログラムを用意しました。$media_idと$access_tokenをセットしてから起動してみて下さい!サンプルで、私の作品のメディアIDをセットしています。気軽にお試し下さい。
<?php
//メディアID・アクセストークン
$media_id = "758589601164219993_295878252";
$access_token = "295878252.7271052.4e4c3523631545b89678933af444c3fd";
//JSONデータを取得し、オブジェクト形式に変換
$obj = json_decode(@file_get_contents("https://api.instagram.com/v1/media/{$media_id}/comments?access_token={$access_token}"));
//個々のコメント情報
foreach($obj->data as $item){
//ID・リンク・投稿時間・コメント数・ライク数・フィルター・タグ・埋め込み用HTMLコード
$id = $item->id;
$created = date('Y/m/d H:i',$item->created_time);
$text = $item->text;
$user_id = $item->from->id;
$user_username = $item->from->username;
$user_fullname = (isset($item->from->full_name) && $item->from->full_name) ? $item->from->full_name : '';
$user_icon = $item->from->profile_picture;
//出力
echo "<img src=\"{$user_icon}\" width=\"75\" height=\"75\"/><br/>{$user_fullname}<a href=\"http://instagram.com/{$user_username}\" target=\"_blank\">@{$user_username}</a>(ID:{$user_id})<br/>「{$text}」({$created})<hr/>";
}
プログラムの実行結果
このように、指定した作品に付けられたコメントの一覧を出力します。まだ機能が十分とは言えないWEB版のInstagram。例えば、これを補うための専用ブラウザサービスなどを作成する際は、コメントリストを取得するAPIが役に立ちそうですね。
6-2コメントの投稿
Instagram APIでコメントを投稿するには、Instagram TEAMに申請を送り、リクエストURLへアクセスする許可を得る必要があります。申請は下記ページから行なうことができます。本格的なwebサービスを構築する方は、ぜひこの機能を利用してみて下さい。commentsの権限が必要です。
Request access to comments POST endpoint Instagram
これは自動で大量に宣伝投稿するようなスパムを防ぐためですね。どうやらテスト用に試すことは無理そうなので、残念ながら私はこのAPIを実行していませんが、投稿方法だけを掲載しておきます。あくまでも「恐らくこれでできる」という内容ですので、ご了承下さい。
[POST] https://api.instagram.com/v1/media/{メディアID}/comments
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| text | [必須] コメントテキスト |
取得できるJSONデータ
コメントの投稿リクエストに成功すると、下記のJSONデータが返却されます。ステータスコードで成功判定をしましょう。
{
"meta": {
"code": 200 //ステータスコード
},
"data": null
}
サンプルプログラム
コメントを投稿するための、PHPのサンプルプログラムです。コメントの投稿には申請・許可が必要であり「テスト投稿ができない」という理由から、動作確認はしていないことをご理解下さい。
<?php
//メディアID
$media_id = "758589601164219993_295878252";
//パラメータを連想配列形式で指定(その後、配列形式のパラメータを文字列に変換)
$params = array(
'access_token' => "295878252.7271052.4e4c3523631545b89678933af444c3fd",
'text' => "この作品、素晴らしいと思います!",
);
//POSTリクエストを送信する
@file_get_contents(
"https://api.instagram.com/v1/media/{$media_id}/comments",
false,stream_context_create(array('http' => array(
'method' => 'POST',
'content' => http_build_query($params),
)))
);
6-3コメントの削除
コメントを「投稿」するためには申請・許可が必要ですが、コメントの「削除」は自由にできます。そのためには、下記URLにDELETEメソッドでリクエストを送って下さい。コメントを投稿した「メディアID」に加えて、コメント自体のIDも必要です。commentsの権限が必要です。
[DELETE] https://api.instagram.com/v1/media/{メディアID}/comments/{コメントID}
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
取得できるJSONデータ
コメントの削除リクエストに成功すると、下記のJSONデータが返却されます。投稿と同様で、ステータスコードで成功判定をすることになりますねー。
{
"meta": {
"code": 200 //ステータスコード
},
"data": null
}
サンプルプログラム
コメントを削除するための、PHPのサンプルプログラムを用意しました。3〜5行目をセットしてから起動してみて下さい。削除に成功すれば「リクエストに成功しました!」というメッセージが表示されるので、実際に削除されたか確認してみて下さいね!
<?php
//メディアID・コメントID・アクセストークン
$media_id = "758589601164219993_295878252";
$comment_id = "758594273065227884";
$access_token = "295878252.7271052.4e4c3523631545b89678933af444c3fd";
//DELETEリクエストを送信し、返ってきたJSONデータをオブジェクト形式に変換
$obj = json_decode(@file_get_contents(
"https://api.instagram.com/v1/media/{$media_id}/comments/{$comment_id}?access_token={$access_token}",
false,stream_context_create(array('http' => array(
'method' => 'DELETE',
)))
));
//ステータスコードが200だったら成功
if(isset($obj->meta->code) && $obj->meta->code == 200) echo "リクエストに成功しました!";
7ライク
APIを経由して、作品に「ライク」を付けたり消したりすることができます。この章では、「ライク」に関する操作を解説していきます。
Like Endpoints Instagram
7-1ライクを付ける
指定した作品にハートマークの「ライク」を付けます。下記のように組み立てたURLにPOSTメソッドでリクエストを送ります。likesの権限が必要です。
[POST] https://api.instagram.com/v1/media/{メディアID}/likes
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
取得できるJSONデータ
ライクを付けるのに成功すると、下記のJSONデータを取得できます。投稿の時と同じで、ステータスコードで成功判定を行なって下さい。
{
"meta": {
"code": 200 //ステータスコード
},
"data": null
}
サンプルプログラム
「ライク」を付けるためのPHPのサンプルプログラムを用意しました。$media_idと$access_tokenをセットしてから起動してみて下さい!初期で設定してあるメディアIDは「私の作品」ですので、お気兼ねなく、お試し下さい。
<?php
//メディアID・アクセストークン
$media_id = "758589601164219993_295878252";
//パラメータを連想配列形式で指定
$params = array(
'access_token' => "295878252.7271052.4e4c3523631545b89678933af444c3fd",
);
//POSTリクエストを送信し、返ってきたJSONデータをオブジェクト形式に変換
$obj = json_decode(@file_get_contents(
"https://api.instagram.com/v1/media/{$media_id}/likes",
false,stream_context_create(array('http' => array(
'method' => 'POST',
'content' => http_build_query($params),
)))
));
//ステータスコードが200だったら成功
if(isset($obj->meta->code) && $obj->meta->code == 200) echo "リクエストに成功しました!";
7-2ライクを取り消す
逆に「ライク」を取り消すには、下記URLにDELETEメソッドでリクエストを送って下さい。聞き慣れないメソッドかもしれませんが、POSTメソッドを送る処理と内容はほとんど変わりません。likesの権限が必要です。
[DELETE] https://api.instagram.com/v1/media/{メディアID}/likes
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
取得できるJSONデータ
POSTメソッドやDELETEメソッドでリクエストを送るタイプのAPIは、JSONデータの構造が共通しているようです。こちらもステータスコードの200を成功判定の材料にして下さい。
{
"meta": {
"code": 200 //ステータスコード
},
"data": null
}
サンプルプログラム
ライクを取り消すための、PHPのサンプルプログラムを用意しました。3〜4行目をセットして起動して下さい。取り消しに成功すると「リクエストに成功しました!」というメッセージが表示されます!
<?php
//メディアID・アクセストークン
$media_id = "758589601164219993_295878252";
$access_token = "295878252.7271052.4e4c3523631545b89678933af444c3fd";
//DELETEリクエストを送信し、返ってきたJSONデータをオブジェクト形式に変換
$obj = json_decode(@file_get_contents(
"https://api.instagram.com/v1/media/{$media_id}/likes?access_token={$access_token}",
false,stream_context_create(array('http' => array(
'method' => 'DELETE',
)))
));
//ステータスコードが200だったら成功
if(isset($obj->meta->code) && $obj->meta->code == 200) echo "リクエストに成功しました!";
8メタデータの検索
指定した「タグ名」や「場所ID」でメディアリストを取得する方法は、既に説明しましたよね。これらを条件に作品検索する前提として、どのような「タグ名」「場所ID」がInstagramに登録されているのかを調べる必要があります。この章では、これら検索条件にできるメタデータを取得する方法を説明します。
Tag Endpoints Instagram
Location Endpoints Instagram
8-1「タグ名」を検索する
指定したキーワードにマッチする「タグ名」のリストを取得します。下記URLにGETメソッドでリクエストを送って下さい。
[GET] https://api.instagram.com/v1/tags/search
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| q | [必須] 検索キーワードを指定 |
取得できるJSONデータ
検索条件にマッチしたタグデータが、配列形式でdataプロパティに含まれています。nameに格納されている「タグ名」は、「タグで作品を取得する」で利用することができます。
{
"meta": {
"code": 200 //ステータスコード
},
"data": [ //キーワードにマッチした個々のタグデータ(配列形式)
{
"media_count": 14803848, //そのタグの投稿数
"name": "japan" //タグ名
},
...
]
}
サンプルプログラム
「タグデータ」を検索するためのサンプルプログラムです。$paramsにキーワードをセットして、起動してみて下さい。
<?php
//パラメータを連想配列形式で指定
$params = array(
'access_token' => "295878252.7271052.4e4c3523631545b89678933af444c3fd",
'q' => "japan",
);
$query = http_build_query($params);
//POSTリクエストを送信し、返ってきたJSONデータをオブジェクト形式に変換
$obj = json_decode(@file_get_contents("https://api.instagram.com/v1/tags/search?{$query}"));
//個々の場所データ
foreach($obj->data as $item){
//タグ名・投稿数
$name = $item->name;
$count = $item->media_count;
//出力
echo "<p>#{$name} ({$count})</p>";
}
プログラムの実行結果
プログラムを実行すると、キーワードにマッチしたタグデータ一覧が表示されます。ユーザーがタグ検索をして、候補の中から特定のタグを選び、そのタグに関連付いたメディアリストを表示するシステムを作れば、海外webサービスの「Hashgram」と同等のものを作成できます。
ちなみに「Hashgram」は日本語に対応していません。国内向けに「ハッシュタグ検索」にフォーカスを当てたwebサービスを作成すれば、それなりに需要があるんじゃないでしょうか!?
Hashgram Hashgram
ハッシュタグから写真、動画を検索できるwebサービス。
8-2「場所ID」を検索する
キーワードや位置座標、foursquareのIDなど豊富な条件から、「場所ID」のリストを取得することができます。そのためには、下記URLにGETメソッドでリクエストを送って下さい。検索条件の優先度は「Facebook Place ID」「foursquare ID」「位置情報(緯度・経度・範囲)」の順になっています。
[GET] https://api.instagram.com/v1/locations/search
| パラメータ | 説明 |
|---|---|
| access_token | [必須] アクセストークン |
| lat | 緯度 (経度とセット) |
| lng | 経度 (緯度とセット) |
| distance | 検索する範囲を「メートル」で指定 (緯度、経度とセット)
- [初期値] 1000 - [最大値] 5000 |
| facebook_places_id | Facebook PlaceのID
[例] https://www.fa.../156209334451244 [リンク] |
| foursquare_id | foursquare v1(旧バージョン)のvenue ID (非推奨) |
| foursquare_v2_id | foursquare v2(現行バージョン)のvenue ID
[例] https://ja.fou.../4b6ff24df964a52001012de3 [リンク] |
取得できるJSONデータ
検索条件にマッチした場所データが、配列形式でdataプロパティに含まれています。なお、ここで調べた「場所ID」は「場所IDで作品を検索する」で利用することができます。
{
"meta": {
"code": 200 //ステータスコード
},
"data": [ //検索条件にマッチした個々の場所データ(配列形式)
{
"latitude": 35.801474673, //緯度
"id": "5081481", //場所ID
"longitude": 139.792191773, //経度
"name": "白旗塚史跡公園" //場所名
},
...
]
}
サンプルプログラム
「場所データ」の一覧を取得するためのサンプルプログラムです。$paramsに場所の検索条件となるパラメータをセットしてから、起動して下さい。
<?php
//パラメータを連想配列形式で指定
$params = array(
'access_token' => "295878252.7271052.4e4c3523631545b89678933af444c3fd",
'lat' => "35.8011280",
'lng' => "139.7926630",
'distance' => "4500",
);
$query = http_build_query($params);
//POSTリクエストを送信し、返ってきたJSONデータをオブジェクト形式に変換
$obj = json_decode(@file_get_contents("https://api.instagram.com/v1/locations/search?{$query}"));
//個々の場所データ
foreach($obj->data as $item){
//ID・名前・緯度・経度
$id = $item->id;
$name = $item->name;
$latitude = $item->latitude;
$longitude = $item->longitude;
//出力
echo "<p>{$name} (場所ID:{$id} / <a href=\"https://www.google.co.jp/maps/@{$latitude},{$longitude},17z\" target=\"_blank\">地図</a>)</p>";
}
プログラムの実行結果
プログラムを実行し、検索に成功すると、場所データの一覧が表示されます。ユーザーに場所検索から特定の場所を選択させ、それを受けて場所IDを元にメディアリストを出力するようにすれば、「バショスタグラム(仮)」みたいな「場所からInstagramの写真を検索できるwebサービス」が作れますねー。ネーミングセンスへの苦情は受け付けません…。
9リアルタイムAPI
Web Hookというシステムをご存知でしょうか?通常、APIは、開発者側がサービス(Instagram)側に向かってリクエストを送り、データを受け取るものですが、この機能を利用すれば、設定したイベントが発生した時に、サービス側が開発者側の指定したURLに対して、通知(リクエスト)を送ってくれるようになります。
Instagram APIにもこのWeb Hookに似た通知機能、「リアルタイムAPI」が存在します。この章ではInstagramのリアルタイムAPIの使い方を、分かりやすいように紹介していきます!
Real-time Photo Updates Instagram
9-1リアルタイム通知に指定できる条件
まずは、どのようなイベントが発生した時に通知を送ってくれるのかを見てみましょう。開発者は、下記4種類のイベント(通知条件)を設定することができます。
| イベント名 | 説明 |
|---|---|
| Users | アプリを認証している「ユーザー」が新しい作品を投稿した時 |
| Tags | 指定した「タグ名」が付けられた作品が投稿された時 |
| Locations | 指定した「場所ID」が付けられた作品が投稿された時 |
| Geographies | 指定した「位置範囲内」で作品が投稿された時 |
9-2リアルタイム通知を登録する
それでは実際に、「リアルタイムAPI」の通知を受けるために、イベントを設定してみましょう。設定方法は、下記URLにPOSTメソッドでリクエストを送信します。各イベントにより、必要となるパラメータが違うので、それぞれ紹介していきます。
[POST] https://api.instagram.com/v1/subscriptions/
Users
アプリを認証している全ユーザーのいずれかが新しい写真を投稿した時に、Instagram側から通知を受け取ることができます。Usersを設定するには、下記のパラメータを指定します。
| パラメータ | 説明 |
|---|---|
| client_id | [必須] クライアントID |
| client_secret | [必須] クライアントシークレット |
| object | [必須] "user"を指定 |
| aspect | [必須] "media"を指定 |
| verify_token | [必須] 「合い言葉」となるキーを指定 |
| callback_url | [必須] 通知を受け取るプログラムが設置してあるURL |
Tags
指定した「タグ名」を付けた作品が投稿された時に、Instagram側から通知を受け取ることができます。対象は、アプリを認証しているユーザーだけではなく、Instagramの全ユーザーです。Tagsを設定するには、下記のパラメータを指定します。
| パラメータ | 説明 |
|---|---|
| client_id | [必須] クライアントID |
| client_secret | [必須] クライアントシークレット |
| object | [必須] "tag"を指定 |
| aspect | [必須] "media"を指定 |
| object_id | [必須] 通知対象となる「タグ名」を指定 |
| verify_token | [必須] 「合い言葉」となるキーを指定 |
| callback_url | [必須] 通知を受け取るプログラムが設置してあるURL |
Locations
指定した「場所ID」に関連付いた作品が投稿された時に、Instagram側から通知を受け取ることができます。対象はTagsと同様、Instagramの全ユーザーです。Locationsを設定するには、下記のパラメータを指定します。
| パラメータ | 説明 |
|---|---|
| client_id | [必須] クライアントID |
| client_secret | [必須] クライアントシークレット |
| object | [必須] "location"を指定 |
| aspect | [必須] "media"を指定 |
| object_id | [必須] 通知対象となる「場所ID」を指定 |
| verify_token | [必須] 「合い言葉」となるキーを指定 |
| callback_url | [必須] 通知を受け取るプログラムが設置してあるURL |
Geography
「場所ID」ではなく、開発者が独自に設定した「位置範囲内」のGEOデータが付いた作品が投稿された時に、Instagram側から通知を受け取ることができます。対象はInstagramの全ユーザーです。Geographyを設定するには、下記のパラメータを指定します。
| パラメータ | 説明 |
|---|---|
| client_id | [必須] クライアントID |
| client_secret | [必須] クライアントシークレット |
| object | [必須] "geography"を指定 |
| aspect | [必須] "media"を指定 |
| lat | [必須] 「緯度」を指定 |
| lng | [必須] 「経度」を指定 |
| radius | [必須] 「範囲」をメートルで指定 |
| verify_token | [必須] 「合い言葉」となるキーを指定 |
| callback_url | [必須] 通知を受け取るプログラムが設置してあるURL |
「リアルタイム通知」を登録する流れ
通常のAPIとは違い、少しだけややこしいのが、このリアルタイムAPIの悩みどころ…。ということで、簡単に流れを紹介していきます。まずは上記で説明した通り、適切にリクエストを送信します。問題は、その後の流れです。
リクエストを送ると、Instagram側は、リクエストを送ってきたプログラムを待たせておいてその間に、「callback_urlに指定したURL」に対して、GETメソッドで、下記の3つのパラメータを送ってきます。PHPなら$_GET['hub_verify_token']などで、それぞれ受け取れますね。
[GET] ...?hub_verify_token=...&hub_challenge=...&hub_mode=...
| パラメータ | 説明 |
|---|---|
| hub_verify_token | こちらがverify_tokenに設定した「合い言葉」となるキー |
| hub_challenge | Instagram側が発行した確認用のキー |
| hub_mode | 値は必ず、"subscribe" |
これを受けて、開発者のプログラム側(callback_urlに指定したURL)は、送られてきた「確認用のキー」を、Instagram側にレスポンスで返してやる必要があります。「”レスポンスで返す”ってなんやねん!馬鹿野郎!」と思った方、大変申し訳ございません。具体的には、echoで出力してやるだけなんです。
//送られてきた「確認用のキー」をレスポンスで返す = 出力する echo $_GET['hub_challenge'];
はい、これだけ。これを受けてInstagram側は、「よし、こいつ(開発者側)のプログラムは正常に動いてるな、それなら通知を開始してやろう」となるわけです。こうしてやっと、先ほどから待たせていた、「最初にリクエストを送ってきたプログラム」に対して、「登録受け付けたで!」というJSONデータを返却し、ここで晴れて登録が完了します。
取得できるJSONデータ
登録を受け付けた際に返却されるJSONデータは下記の通りです。objectには「通知の種類」を表すコードが、object_idには、Tagsならタグ名、Locationsなら場所IDというように、条件に指定した「値」が含まれています。
ここで重要なのが、「Geography」の場合です。独自に設定した位置範囲の情報は、1つのIDとして登録され、「ジオID」となり、object_idに格納されます。この「ジオID」は言わば、独自に作った「場所ID」みたいなものですが、「場所ID検索」ではメディアリストを取得できません。代わりに「ジオID検索」で取得することができるようになります。
{
"meta": {
"code": 200 //ステータスコード
},
"data": {
"object": "tag", //通知の種類 [user / tag / location / geography]
"object_id": "yamada", //通知の条件 [タグ名 / 場所ID / ジオID]
"aspect": "media",
"callback_url": "http://syn...php", //通知を送るURL
"type": "subscription",
"id": "8101428" //通知ID
}
}
サンプルプログラム
下記がInstagramで「リアルタイムAPI」を登録するための、サンプルプログラムです。3〜6行目、そして17〜25行目を調整して下さいね。$callback_urlにはこのプログラムのURLを指定して下さい。
<?php
//クライアントID・クライアントシークレット・コールバックURL・合い言葉となるキー
$client_id = "7271052d1526476e9ec1f3b4edfb5dea";
$client_secret = "095ac41c924242d2b6c85b30926e9169";
$callback_url = "http://syncer.jp/test.php";
$verify_token = "aikotoba";
//登録時の、Instagram側の確認用アクセスを受ける
if($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_GET['hub_verify_token']) && $_GET['hub_verify_token'] == $verify_token && isset($_GET['hub_challenge']) && isset($_GET['hub_mode']) && $_GET['hub_mode'] == 'subscribe'){
//確認用のキーを返却する
echo $_GET['hub_challenge'];
exit;
}
//パラメータを連想配列形式で指定(サンプルはGeographyの場合)
$params = array(
'client_id' => $client_id,
'client_secret' => $client_secret,
'object' => "geography",
'aspect' => "media",
'lat' => "35.798535",
'lng' => "139.7940011",
'radius' => "1000",
'verify_token' => $verify_token,
'callback_url' => $callback_url,
);
//POSTリクエストを送信し、返ってきたJSONデータをオブジェクト形式に変換
//JSONデータが返ってくる前に待たされて、8〜13行目が行なわれる
$json = @file_get_contents(
"https://api.instagram.com/v1/subscriptions/",
false,stream_context_create(array('http' => array(
'method' => 'POST',
'content' => http_build_query($params),
)))
);
$obj = json_decode($json);
//結果を出力する
echo (isset($obj->data->id)) ? "<p>リアルタイム通知を登録しました。通知IDは<mark>{$obj->data->id}</mark>です。</p>" : "<p>登録に失敗しました…。パラメータがおかしいか、重複登録です。</p>";
echo '<p>登録したデータ</p><pre>'.json_encode(json_decode($json),JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)."</pre><br/>[<a href=\"https://api.instagram.com/v1/subscriptions?client_id={$params['client_id']}&client_secret={$params['client_secret']}\" target=\"_blank\">登録状況を確認する…</a>]";
プログラムの実行結果
プログラムに、受けたい通知タイプのパラメータを適切に設定して起動すれば、上記のように登録することができます。上記は「Geography」を登録した場合のサンプルです。object_idに格納されている6088330が、指定した位置範囲を反映した「ジオID」です。「通知ID」と混同しないように気を付けて下さい。
9-3リアルタイム通知の登録状況を確認する
現在、Instagramにどれくらいのリアルタイム通知を登録しているのか、確認するためには、下記のURLにアクセスして下さい。現在の登録状況を示したJSONデータが返ってきます。
[GET] https://api.instagram.com/v1/subscriptions?client_id={クライアントID}&client_secret={クライアントシークレット}
ちなみに、JSONデータは通常、インデント(改行など)されておらず、とても見づらいです。手前味噌ではありますが、JSONデータを見やすく整形するには下記のオンラインツールをご利用下さい。
JSON整形ツール Syncer
9-4リアルタイム通知を削除する(取り消す)
Instagramのリアルタイム通知を取り消す方法を紹介します。下記URLに、DELETEメソッドでリクエストを送信します。
[DELETE] https://api.instagram.com/v1/subscriptions
| パラメータ | 説明 |
|---|---|
| client_id | [必須] クライアントID |
| client_secret | [必須] クライアントシークレット |
| object | [どちらか必須] 削除するタイプ
- [all] 全ての通知を削除 - [user] Usersを削除 - [tag] 全てのTagsを削除 - [location] 全てのLocationsを削除 - [geography] 全てのGeographyを削除 |
| id | [どちらか必須] 削除する通知ID |
サンプルプログラム
リアルタイム通知を削除するためのサンプルプログラムです。$paramsをセットしてから、プログラムを起動して下さい!
<?php
//パラメータを配列形式で指定(その後、配列形式のパラメータを文字列に変換)
$params = array(
'client_id' => "7271052d1526476e9ec1f3b4edfb5dea",
'client_secret' => "095ac41c924242d2b6c85b30926e9169",
'object' => "all",
);
$query = http_build_query($params);
//POSTリクエストを送信し、返ってきたJSONデータをオブジェクト形式に変換
$obj = json_decode(@file_get_contents(
"https://api.instagram.com/v1/subscriptions?{$query}",
false,stream_context_create(array('http' => array(
'method' => 'DELETE',
)))
));
//ステータスコードが200だったら成功
if(isset($obj->meta->code) && $obj->meta->code == 200) echo "削除リクエストに成功しました!<br/>[<a href=\"https://api.instagram.com/v1/subscriptions?client_id={$params['client_id']}&client_secret={$params['client_secret']}\" target=\"_blank\">登録状況を確認する…</a>]";
9-5リアルタイム通知を受け取る!
最後に、Instagram APIの「リアルタイム通知」を受け取る方法を紹介します。リアルタイム通知は設定したイベントが起こったタイミングで、callback_urlで指定したURLに対して、POSTメソッドで下記のJSONデータを送信してきます。
[ //個々の通知データ(配列形式) { "subscription_id": "1", //通知ID "object": "user", //通知の種類 [user / tag / location / geography] "object_id": "1234", //通知の内容 [ユーザーID / タグ名 / 場所ID / ジオID] "changed_aspect": "media", "time": 1297286541, //イベント発生日時 "data": { "media_id": "759036190747972777_295878252" //投稿されたメディアID } }, ... ]
このJSONデータは、特定のPOSTパラメータに含まれているわけではないため、下記のように「読み込み専用のストリーム」にアクセスして取得することが可能です。
//読み込み専用のストリームにアクセスし、JSONデータを取得
$json = @file_get_contents('php://input');
//JSONデータをオブジェクト形式に変換
$obj = json_decode($json);
あとは、例えばUsersだったら、object_idに含まれる「ユーザーID」を参照して、「このユーザーが更新したから、このユーザーのデータを取りに行って、色々と更新!」というように、自身が運営するwebサービスなどの仕様に合わせて、システムを作っていって下さいね。
9-6「X-Hub-Signature」を利用した認証をする
さて、Instagram側から通知がJSONデータとして送られてくるのはいいですが、「誰が送ってきたか分からない」のはセキュリティ的に怖いですよね…。実際に、通知を受け取るプログラムの設置URLを知っていれば、悪意のある誰でもがInstagramを装ってJSONデータを送りつけることが可能です。
そういった問題を解決する方法として、「X-Hub-Signatureを利用した認証システム」が存在します。ざっくり言うと、開発者側とInstagram側しか知り得ない「クライアントシークレット」を元にした署名で、Instagramが偽物じゃないことを確認する認証方法です。
具体的な認証方法
通知で送られてくるリクエストのヘッダー内の、x-hub-signatureを参照すると、そこに「署名」が含まれています。次のように確認することができます。
$headers = getallheaders(); $hub_signature = $headers['x-hub-signature'];
この「署名」は、次のように、HMAC方式を使用して生成したハッシュ値($hash)と、同じ値になります。$jsonは「受け取ったJSONデータ」、$client_secretは「クライアントシークレット」です。
$hash = hash_hmac( 'sha1' , $json , $client_secret )
つまり、次の条件を満たせば、「クライアントシークレット」を知っているInstagram側からの通知であると判断できますねー。
$hub_signature = $hash
9-7リアルタイム通知を受け取るサンプルプログラム
以上を踏まえて、「X-Hub-Signature」を利用した認証システムを取り入れた、Instagramのリアルタイム通知を利用する全体的なプログラムは下記の通りです。14〜36行目に、通知を受け取った後の処理を加えていって下さいね。40〜45行目は、通知を登録する際のパラメータ設定です。よろしければ、お使い下さい!
<?php
//クライアントID・クライアントシークレット・コールバックURL・合い言葉となるキー
$client_id = "7271052d1526476e9ec1f3b4edfb5dea";
$client_secret = "095ac41c924242d2b6c85b30926e9169";
$callback_url = "http://syncer.jp/test.php";
$verify_token = "aikotoba";
//登録時の、Instagram側の確認用アクセスを受ける
if($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_GET['hub_verify_token']) && $_GET['hub_verify_token'] == $verify_token && isset($_GET['hub_challenge']) && isset($_GET['hub_mode']) && $_GET['hub_mode'] == 'subscribe'){
//確認用のキーを返却する
echo $_GET['hub_challenge'];
exit;
//Instagram側からの通知を受け取る
}elseif($_SERVER['REQUEST_METHOD'] == 'POST'){
//署名の確認
$headers = getallheaders();
$hub_signature = $headers['x-hub-signature'];
//読み込み専用のストリームにアクセスし、JSONデータを取得、オブジェクト形式に変換
$json = @file_get_contents('php://input');
$obj = json_decode($json);
//署名が正しいか確認し、不正なら終了
$hash = hash_hmac('sha1',$json,$client_secret);
if($hub_signature != $hash) exit;
//通知を受けて処理を開始
foreach($obj as $item){
//投稿されたメディアID
$media_id = $item->data->media_id;
//ここから色々と処理して下さい〜
}
exit;
}
//パラメータを連想配列形式で指定(サンプルはUsersの場合)
$params = array(
'client_id' => $client_id,
'client_secret' => $client_secret,
'object' => "user",
'aspect' => "media",
'verify_token' => $verify_token,
'callback_url' => $callback_url,
);
//POSTリクエストを送信し、返ってきたJSONデータをオブジェクト形式に変換
//JSONデータが返ってくる前に待たされて、8〜13行目が行なわれる
$json = @file_get_contents(
"https://api.instagram.com/v1/subscriptions/",
false,stream_context_create(array('http' => array(
'method' => 'POST',
'content' => http_build_query($params),
)))
);
$obj = json_decode($json);
//結果を出力する
echo (isset($obj->data->id)) ? "<p>リアルタイム通知を登録しました。通知IDは<mark>{$obj->data->id}</mark>です。</p>" : "<p>登録に失敗しました…。パラメータがおかしいか、重複登録です。</p>";
echo '<p>登録したデータ</p><pre>'.json_encode(json_decode($json),JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)."</pre><br/>[<a href=\"https://api.instagram.com/v1/subscriptions?client_id={$params['client_id']}&client_secret={$params['client_secret']}\" target=\"_blank\">登録状況を確認する…</a>]";
10「Enforce signed header」を有効にする
「アプリ登録」の際、「まだ未段階なので"Enforce signed header"にはチェックを入れないでおいて下さい」と、ちょっと無責任気味にお願いしたあの件です。せっかくなので解説します。
Restrict API Requests Instagram
10-1「Enforce signed header」とは何か?
Instagram APIではユーザーデータを変更するための下記リクエストにおいて、通常のリクエストに加えて、「適切な署名を発行しないとリクエストを受け付けない!」というセキュリティ設定ができます。
[POST] /users/{user_id}/relationship (つながり変更)
[POST] /media/{media_id}/comments (コメント投稿)
[DEL] /media/{media_id}/comments/{comment_id} (コメント削除)
[POST] /media/{media_id}/likes (ライク)
[DEL] /media/{media_id}/likes (アンライク)
これによって、仮にユーザーのアクセストークンが流出してしまった場合でも、犯人は「署名」が作れない限り、上記のリクエストを実行することができないようになります。大幅なセキュリティ向上が望めるわけですねー。
10-2「Enforce signed header」における「署名」の作成方法
この「署名($signature)」は「クライアントシークレット($client_secret)」と「サーバーのIPアドレス($ip)」を元に、具体的には次のように作ることができます。
$signature = hash_hmac( 'sha256' , $ip , $client_secret , false )
こうして出来上がった「署名($signature)」を|で区切って「IPアドレス($ip)」と一緒にし、X-Insta-Forwarded-Forと名付けたリクエストヘッダーに値として設定することで、「署名による認証」をクリアすることが可能です。
X-Insta-Forwarded-For: $ip|$signature
10-3サンプルリクエスト
それでは、この署名を作成し、リクエストを送る方法を紹介します。あるメディアにライクを付けるという想定だと、次のようになります。11〜16行目と22行目が、肝ですね。よろしければ、参考にして下さい!
//メディアID・アクセストークン
$host = 'syncer.jp';
$client_secret = "095ac41c924242d2b6c85b30926e9169";
$media_id = "758589601164219993_295878252";
//パラメータを連想配列形式で指定
$params = array(
'access_token' => "295878252.7271052.4e4c3523631545b89678933af444c3fd",
);
//IPアドレスを求める
$ip = gethostbyname('syncer.jp');
//署名の作成
$signature = (hash_hmac('sha256', $ip, $client_secret, false));
$header = join('|', array($ip, $signature));
//POSTリクエストを送信し、返ってきたJSONデータをオブジェクト形式に変換
$obj = json_decode(@file_get_contents(
"https://api.instagram.com/v1/media/{$media_id}/likes",
false,stream_context_create(array('http' => array(
'header' => "X-Insta-Forwarded-For: {$header}\r\n",
'method' => 'POST',
'content' => http_build_query($params),
)))
));
11Instagram APIを利用したwebサービスいろいろ
InstagramのAPIを利用して、どのようなwebサービスが作られているのか。紹介していきます。これから制作するサービスの参考にしてみて下さい。
11-1INUSTAGRAM
犬の画像をただひたすらに閲覧できるのが、この「イヌスタグラム」です。「タグで作品を取得する」か「リアルタイムAPI」辺りを利用して、「DOG」「犬」などのタグが付いた写真を取得、紹介しているんだと思います。Instagram APIを最もオーソドックスに使ったwebサービスと言えるんじゃないでしょうか。これの姉妹サイトとして「ネコスタグラム」もありますが、犬派の私はこちらを紹介しました。
NEKOSTAGRAM NEKOSTAGRAM
Instagram APIを使ってねこ大好き専用の「Nekostagram」を作ってみた アインシュタインの電話番号
INUSTAGRAM INUSTAGRAM
二匹目のどじょうを狙っていぬ大好き専用の「Inustagram」を作ってみた アインシュタインの電話番号
11-2jLeaguram
動物じゃなく「夜景」「廃墟」など、他のカテゴリにも応用できそうですねー。と思っていたところ、発見したのがこのサイト。「サッカー」に関連した写真を専門に見ることができるwebサービスです。「スポーツ」という発想はありませんでした。
jLeaguram jLeaguram
Jリーグとinstagramのサービス「jLeaguram」をローンチしました ymzkmct's blog
「サッカー」に関連した写真を専門に見ることができるwebサービスです。
11-3IROSTAGRAM
こちらは、「色」からInstagramの写真を検索できるwebサービスです。Instagramから写真を取得するのに加えて、「色分析をして分類する」という独自の処理を組み合わせている例ですねー。
IROSTAGRAM IROSTAGRAM
11-4Bijostagram
さらには「美女」を専門にした、男性にとっては、まさに「神サービス」も存在しました(笑)。と、それだけではなく、こちらのサービスはただ美女の画像を集めるというだけではなく、顔画像認識と、タグ、コメント内容の解析を駆使し、プログラムに機械学習をさせながら、日々、精度を向上させているそうです。なるほど、このサイトで表示される写真は、本当にテーマ通りのものばかりです。
Instagramは投稿作品が豊富にあるのが魅力な反面、釣りタグや、関係ないタグ付けなどが横行していて、例えば、特定のタグを指定しても関係ない写真ばかり取得してしまうのが悩みの種でもあります。そんな中、こういった「自動で取捨選択するシステム作り」が実現されているのを見ると、俄然やる気が出てきませんか?個人的に、このサイトはシステム面が気になって見に行ってしまうサイトです。
Bijostagram Bijostagram
きれいなおねいさんのあつめかた:Bijostagramのはなし。 TMBのおぼえがき
まだまだ「ソラスタグラム」「ウミスタグラム」「チンチラグラム」「オサカナグラム」「カピバラグラム」などなど、世の中に需要はたくさんあると思うので、みなさんも、ぜひ作成してみてはいかがでしょうか?
11-5photoll
こちらは「撮影スポット」の情報をシェアするSNS、「photoll」です。ローンチしたばかりで、ユーザーによる投稿が少ない状況を、APIを利用してInstagramから関連作品を引っ張ってくることによって、補っています。Instagram APIをサービスのメインではなく、補助的役割として活用している例ですね。
この巨大な規模のSNSは、なんと個人で作成したらしいです。こういうサービスって、これだけ大きいと上手く回り出すまでが大変なんですが、個人的に頑張ってほしいと思っているサイトです。全然関係ないんですが、短いドメインって美しいですよね。
photoll photoll
【1人でWebサービス開発】新米Railsエンジニアが無謀にも写真共有サイトを作りました milestoner
11-6i-am-cc.org
Instagramに「クリエイティブ・コモンズ・ライセンス」を設定することができるwebサービスです。ユーザーはこのサイトに登録し、ライセンスを明示することで、作品を他人に利用してもらうことが可能になります。その精神もアイデアも大変素晴らしいInstagram APIの活用方法だと思います。
Set your Instagram free! i-am-cc.org
11-71/365gram
Instagramに投稿した写真をカレンダー形式で振り返ることができるwebサービス。TwitterでいうTwilogみたいなタイプです。こうやって見せ方を変えるだけでも大変魅力になるんだなーと、センスが足りずに真似できない自分は思うのでした。
1/365gram 1/365gram
11-8Marimelody wears dress in November.
こちらも面白いwebサイトを発見したのでご紹介。11月のファッション、「ノベンバコーデ」を紹介しているサイトです。このサイトは作者の方がInstagramに投稿した11月の写真を一覧形式で表示しています。APIはwebサービスを作成する用途だけでなく、個人的なライフログや情報をまとめるための手段としても活用されるべきで、とても良い事例だと思いました。
Marimelody wears dress in November. Marimelody wears dress in November.
Instagram APIを利用してノベンバコーデまとめページを作ったよ。 marimelody.net
12ネット上にあるInstagram APIの解説記事について
InstagramのAPIは大変人気で、ネット中に「使い方」についての素晴らしい記事がありました。ただ、その中で気になったのが「jQueryでInstagram APIを使う」という趣旨の記事です。これらの記事の中には、サーバーサイド(phpとかPerlとか)を通さずにクライアントサイド(Javascript)だけで処理を完了させているものが多数あります。
そのJavascript(jQuery)のソースコードを確認すると、当然ですがアクセストークンが丸見えになる仕様でした。これは大変危険な使い方だと思います。パーミッションの設定によっては、アクセストークンを見た悪意ある人物が勝手にフォローしたりコメントを削除したりライクを付けたり、といったことが可能になります。
「Enforce signed headerによる署名」を利用すれば、「変更関連(POST、DELETE)の悪戯」は防げますが、記事中でそういった点に触れられていることもなく、「アクセストークンが丸見えになる危険性」については想定外なんだと推察します。
ネット上にある「使い方」を参考にする際は、今回の例だったら「アクセストークンが丸見えになるとはどういうことか」というように、リスクを意識するようにして下さい。このページの記事だって、素人が書いていることなので、問題点が含まれてないという保証は全くありません。むしろ「APIを動かすためのサンプル」という趣旨なので、エラー処理など一切なく、仮にそのままwebサービスに流用すると様々な不具合が発生するはずです。あくまでも下地としてご利用下さい…。
13Instagram APIでwebサービスを作ろう!
いかがでしたか?長々と読んでいただき、ありがとうございました。Instagram APIを利用すれば、これからでも、まだまだ面白いwebサービスが生まれるんじゃないかとワクワクしています。webサービスじゃなくても、例えば、店舗運営者の方だったら、店の「場所ID」を条件に「リアルタイム通知」を受け取り、店舗に関連する写真をTumblrに投稿するシステムを作れば、自動で更新されていく店の宣伝ブログの出来上がり…。こういった使い方もありだと思います。
この記事が、これから生まれる素晴らしいwebサービスに一助になれば、幸いです!
この連載の記事一覧
- はてブAPIでwebサービスを作りたい全ての人に向けて書きました
- pocket APIでwebサービスを作りたい全ての人に向けて書きました
- Moves APIでwebサービスを作りたい全ての人に向けて書きました
- Tumblr APIでwebサービスを作りたい全ての人に向けて書きました
- Instagram APIでwebサービスを作りたい全ての人に向けて書きました
この記事へのコメント
感想、ご指摘などお気軽にお寄せ下さい。「関連記事を書いた」という方はご報告いただければリンクします。
記事の更新履歴
- 記事を公開しました。
2014/07/08 07:00
※Twitter、Facebook、はてな、いずれかのアカウントをお持ちの方は、本人認証(ログイン)を行なうことができます。
※本人認証をすることで、書き込みの待ち時間なし、画像アップロード、アイコンなどが利用できます。
※認証時にサービスと連携しますが、名前とアイコン以外の情報を読み込んだり、また書き込みを行なうことはありません。連携で要求する権限は「公開情報の読み取り」のみです。
コメントは、0件です。