このエントリーをはてなブックマークに追加

Memo

Instagram APIでおうちごはんカレンダー作ってみた

2015/02/09
Memo

ouchigohan

仕事でInstagram APIを使うことになったので、勉強がてら以前から作ってみたかった「おうちごはんカレンダー」を作ってみました。

できたもの

我が家のおうちごはん(JavaScript版)
我が家のおうちごはん(PHP版)
みんなのおうちごはん

我が家のおうちごはん 2つは、どちらも私が@mei331のアカウントで投稿している写真の中から#おうちごはんタグのついたものだけを抽出してカレンダー状に表示しているものです。

みんなのおうちごはん はInstagramの写真すべてから、#おうちごはんタグのついたものだけを抽出し、並べています。

Instagram APIについて

Instagram APIを使う場合、Instagram Developer に登録する必要があります(※Instagram Developerへの登録にはInstagramアカウントが必要です)
また、登録の際に携帯の電話番号が必要になります(SMSで認証番号が届きます)

Developer登録をすると、アプリケーション登録が可能になります。
アプリケーション登録→クライアントID、クライアントシークレットを取得→アクセストークンの取得 までできて、ようやくAPIを使用することができます。

少し面倒ですが、一度Developer登録をしてしまえば、アプリケーション登録はすぐにできますし、アクセストークンの取得もスムーズにできます。詳しい登録の仕方は以下を参考にしてください。

Instagram APIでwebサービスを作りたい全ての人に向けて書きました

我が家のおうちごはん(JavaScript版)解説

Instagram APIをJavaScriptで使えるようにするjQueryプラグインなどもありますが、ソースを見たらクライアントID、クライアントシークレット、アクセストークンが丸見えになってしまうという危険性があります。安全な方法として、JavaScriptでアクセストークンなどの書かれたPHPを叩く→PHPが結果を返す→PHPの返した結果をJavaScriptで受け取る、というやり方があります。JavaScript版はその方法で制作しました。

以下で書かれている方法がとても参考になります。

コピペなしでInstagramの画像を表示するよ! | marimelody.net

JavaScript(jQuery)でPHPにデータを渡す方法

今回制作したカレンダーでは、指定した年月のデータを取得して表示させています。Instagram APIでは、ユーザーのデータを期間を指定して取得できますが、アクセストークンなどと一緒にリクエストする必要があります。なのでPHP側にどの年月を指定したか情報を送る必要があったので、以下のような方法をとりました。

JavaScript(jQuery)

$.ajax({
	url: "PHPファイルのURL",
	type:"POST",
	data:{//phpに送信したいデータ
		'year' : '2015',
		'month' : '2'
	},
	dataType:'json',
	success: function(j_data){
	//成功した場合の処理
	},
	error :function(){
	//失敗した場合の処理
	}
});

PHP

//POSTリクエストの場合のみ受付
if($_SERVER['REQUEST_METHOD'] == 'POST'){
	//リクエストURL
	$request_url = "https://api.instagram.com/v1/users/self/media/recent/";
	$inYear = $_POST['year'];
	$inMonth = $_POST['month'];
	$minTime = strtotime($inYear.'-'.$inMonth.'-01 0:0:0');	//エポック秒変換
	$maxTime = strtotime($inYear.'-'.$inMonth.'-31 23:59:59');
	//パラメータを配列形式で指定(その後、配列形式のパラメータを文字列に変換)
	$params = array(
		'access_token' => "アクセストークン",
		'count' => '50',
		'min_timestamp' => $minTime,	// 指定月の1日
		'max_timestamp' => $maxTime,	// 指定月の31日
	);
	$query = http_build_query($params);
	 
	//出力
	echo @file_get_contents("{$request_url}?{$query}");
	//終了
	exit;
}

jQueryの$.ajaxをつかって、data:{name:value}の形でPHP側にデータを送ることができました。

我が家のおうちごはん(PHP版)解説

解説と言っても、参考サイトのサンプルをベースに制作したので「Instagram APIの使い方まとめ(サンプルコード付)」をぜひ参考にしてください。

UNIX TIMESTAMP(エポック秒)の変換について

Instagram APIでは日付がすべてUNIX TIMESTAMP(エポック秒)で格納されているので、変換には少しコツが要ります。

PHPの場合

//Y-m-dからエポック秒へ
strtotime(date(Y-m-d));

//エポック秒(timestamp)をY-m-dへ
date(Y-m-d, timestamp);

//エポック秒(timestamp)から1ヶ月後のエポック秒(timestamp)を取得
strtotime(date("Ymd",timestamp)."+1 month");

JavaScriptの場合

//Y-m-dからエポック秒へ
var date = new Date(Y,m-1,d);
var timeStamp = date.getTime();

//エポック秒(timestamp)をY-m-dへ
var date = new Date(timestamp*1000);
var inDate = date.getFullYear() + '-' + date_format( date.getMonth() + 1 ) + '-' + date_format( date.getDate() );

JavaScriptは日付周りがすこし複雑なので、以下のサイトを参考にしてください。

JavaScript による日付・時刻・時間の計算・演算のまとめ – hoge256 blog

みんなのおうちごはん 解説

みんなのおうちごはん の方は、Instagram全体からハッシュタグで検索した結果を返します。

ハッシュタグを検索する

ハッシュタグで絞り込む場合は、ハッシュタグが存在するかどうかをまず確認します。以下の方法でハッシュタグを検索できます。

$params = array(
	'access_token' => "アクセストークン",
	"q" => "おうちごはん",
);
$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>";
}

実行結果はこちら

ハッシュタグで絞り込むときはエンコードする

実際にハッシュタグで絞り込む場合、リクエストURLにタグ名を含むため、日本語の場合はURLエンコードしてください。

$search_tags = urlencode("おうちごはん");
$request_url = "https://api.instagram.com/v1/tags/{$search_tags}/media/recent";
画像をさらに読み込むには

最初にデータを取得した際、一番最後のメディアIDを取得しておき、さらに読み込む場合はmax_tag_idを指定すればOKです。

if($_POST['next']){
	$params = array(
		'access_token' => "アクセストークン",
		'count' => 40,
		'max_tag_id' => $_POST['next'],
	);
}else{
	$params = array(
		'access_token' => "アクセストークン",
		'count' => $disCnt,
	);
}

$query = http_build_query($params);
 
//JSONデータを取得し、オブジェクト形式に変換
$obj = json_decode(@file_get_contents("{$request_url}?{$query}"));

//次ページ用ID
$nextID = $obj->pagination->next_max_id;

//個々のメディア情報
foreach((array)$obj->data as $item){
// …データを出力…
}
// さらに読み込むボタンの出力
echo '<div id="nextback"><form action="phpファイル" method="post"><input type="hidden" name="next" value="'.$nextID.'" /><p><button type="submit">さらに読み込む…</button></p></form></div>';
ユーザー絞り込み

指定されたユーザーの画像の中からおうちごはんタグのついたものだけを表示しています。しかし、これにはちょっとコツが要ります。
Instagramにはユーザーを示す名前が3種類あります。日本語などで表記される名前(full_name)、urlなどに使われるユーザーネーム(username)、そして内部で処理するのに必要なユーザーID(id)です.
ユーザーIDは内部処理用のため、普段は分からないようになっています。なので、ユーザー名で絞り込む場合はユーザーネームからユーザーIDを調べる必要があります。

//ユーザーIDを調べる
$getID = $_GET['id'];
$userRequest = "https://api.instagram.com/v1/users/search?q={$getID}&access_token={アクセストークン}";
$userObj = json_decode(@file_get_contents("{$userRequest}"));
$userID = $userObj->data[0]->id;
今回利用したjQueryプラグイン

今回は、ソーシャルボタンに「jQuery.socialbutton」を使用しました。かなり便利でラクチンです。すばらしい。使い方は以下を参考にしてください。

SNSのボタンをまとめて配置する【jQuery連載08】 | HTML5でサイトをつくろう

もう一つ。画像のキャプションの長さがバラバラなので、打開策として画像の高さに合わせてスクロールすることにしたんですが、通常のスクロールバーではすごくださいので、「Perfect Scrollbar」を採用しました。とてもよいです。使い方は以下を参考にしてください。

[JS]ページのデザインに影響を与えないパーフェクトなスクロールバーの超軽量スクリプト -Perfect Scrollbar | コリス

さいごに

やはり、勉強するには何かを作るにかぎるなぁと思います。今回つくったサイトはいつか作りたいなぁと思っていたものだったので、ちょうどよかったです。特にみんなのおうちごはんは、夕飯メニューが決まらないときに見ると、すごく参考になると思います。ぜひ使ってくださいね。

みんなのおうちごはん

さーこれでInstagram APIを使う案件もばっちりだ!仕事しよー。

*参考サイト
コピペなしでInstagramの画像を表示するよ! | marimelody.net
Instagram APIの使い方まとめ(サンプルコード付)
jQuery:Ajaxを使用してPOST送信でデータ取得 | raining
javascriptでクエリ文字列を取得する – Qiita
JavaScript による日付・時刻・時間の計算・演算のまとめ – hoge256 blog

Category : MemoTags : , , , , ,

関連記事

7 Responses

  • pupu より:

    すごいですね!
    自分の投稿のハッシュタグだけ絞り込む方法をもう少し教えてもらえないでしょうか?
    おうちごはんのJquery版では、PHPの方にどういうように書いてあるのかが分からなくて…何度も読み返して参考にされてるサイトも見たんですが。

    • Mei Koutsuki より:

      pupuさん

      コメントありがとうございます。
      JavaScript版は、我が家のおうちごはんのソースをそのまま使ってもらっても大丈夫です。
      JavaScript版で使用しているPHPは、記事に書いてある通りにしか書いていないので、アクセストークンさえ取得できれば、そのままコピペで使えます。

      アクセストークンはhttp://syncer.jp/instagram-api-matomeの「アプリケーションの登録」から「アクセストークンの取得」までを順番通りやることで可能ですよ。

  • castail より:

    はじめまして。
    castailと申します。

    Instagram APIを使用し画像を特定枚数づつ表示したいと思うもののうまくいかずこちらの記事にたどり着きました。

    どうかアドバイスを頂戴したくコメントさせて頂きました。

    希望する仕様は下記の通りです。
    [1]初期読み込み時10枚表示
    [2]「さらに読み込む」ボタンをトリガーに10枚づつ追加表示
    [3]最後のグループ表示時に読み込みボタン非表示

    teratailで下記の通り質問し回答を頂き読み込みボタンでの次グループの読み込みまではうまくいきました。
    https://teratail.com/questions/7896

    ただこちらの方法では、
    [1]初期読み込み時10枚表示
    [2]「さらに読み込む」ボタンをトリガーに10枚づつ追加表示
    は実現できたのですが下記不具合が生じます。

    (1)初期枚数は正常に表示
    (2)hogeボタン押下
    (3)間を抜かして最古のグループが表示される(hogeボタンは表示されたまま)
    (4)hogeボタン押下
    (5)「parsererror」エラー文が表示される

    具体的には、
    10枚ずつ表示設定、全27枚ずつの場合
    (1)最初の10枚は正常に表示
    (3)間を抜かして21〜27枚目が表示される
    状態です。

    こちらを正常に途中部分も読み込みつつ、
    [3]最後のグループ表示時に読み込みボタンは非表示
    も実現したいと考えております。

    同様の内容をteratailでも追加質問をしているのですが
    まだ回答をいただけない状態です。
    https://teratail.com/questions/8071

    何卒ご回答の程よろしくお願いいたします。

    • Mei Koutsuki より:

      castailさん

      コメントありがとうございます。リンク先のソースなどを確認しました。

      まず、間を抜かして21〜27枚目が表示されてしまう件です。
      サンプルで書いてもらった var url=”” の「?count=3」を省略していませんか?
      countの指定をしない場合、デフォルトで画像を20枚読み込むようになっています。
      そのため、次のグループを読み込むのに必要な「data.pagination.next_url」の値が、21枚目からのURLになってしまうのです。
      11枚目からのURLが欲しいのであれば var url=”https://api.instagram.com/v1/users/self/media/recent?count=10″ としてください。

      次に、parsererrorが表示されてしまう件です。
      parsererrorはデータが無いという意味で表示されます。なので、最古のグループが表示されたら更に読み込むボタンを表示しないようにすることで回避できると思います。

      最古のグループを表示したらボタンを表示しないようにする方法ですが、最古のグループであれば「data.pagination.next_url」の値が「null」になるので、nullの場合は表示しないという処理をすればよいかと思います。

      私の書き方とリンク先の書き方が違うので、ソースなどは提示できませんが、参考になれば幸いです。

  • ぱんだ より:

    はじめまして
    ぱんだともうします!

    大変わかりやすいので、自分のポートフォリオサイトの参考にさせて頂いております!
    ちなみに写真の最大表示件数がどうしても33件から増やすこそができないのですが、こちらはインスタグラムAPIの仕様なのでしょうか?

    • Mei Koutsuki より:

      ぱんださん

      はじめまして。お返事遅くなってスミマセン。
      そうですね、Instagramの最大表示件数は33が上限のようです。
      見栄え的な問題でもっと表示させたいのであれば、AutopagerやInfinite Scrollなどでスクロールしながらどんどん表示する、というのも面白いかもしれませんよ。

  • かえる より:

    初めまして。
    私もInstagramのAPIを利用して#ハッシュタグの取得したページを作成したく、こちらのページにたどり着きました。

    PHPの知識がほぼなく苦戦もしているのですが、
    サンプルコードを利用して、ユーザーネームと一緒にアイコンも取得し表示する事はできますでしょうか?

    教えていただければ幸いです!
    宜しくお願い致します。

pupu にコメントする




About

中の人:Mei Koutsuki (@mei331)
神奈川でweb作ったり、お洋服つくったりしてる黒いひつじさん。ロリィタ系webクリエイター。12年9月に一児の母となり、自宅で子育てしながらお仕事してます。
>> もっと詳しく