WordPressで自分のチャンネルのYoutube動画一覧をAPIを使って表示させる方法 - inokawablog

    WordPressで自分のチャンネルのYoutube動画一覧をAPIを使って表示させる方法

    YouTube Data API(v3)を使って自分のチャンネルの動画を表示させます。

     

    Youtube Data API (v3)のAPI仕様書がこちらです。日本語で丁寧に描かれているのでとても読みやすいです。APIドキュメントはものによっては非常に読みにくいものもあるので、読みやすいAPIのドキュメントがあるGoogleは大変丁寧だと思います。

     

    cURLを使ったものとwp_remote_getを使ったものを書いてあります。私が実際に使用しているのはwp_remote_getです。

     

    まずはこちらAPIを取得してください。

     

    cURL

    まずはcURLの方法

    functions.php

    cURLの実行の関数です。エラー処理などはお好きにどうぞ。

    function exec_curl($url, $add_options = null)
    {
    		if (empty($url)) {
    				return false;
    		}
    		$curl = curl_init();
    		$options = [
    				CURLOPT_URL => $url,
    		];
    		if (!empty($add_options)) {
    				$options += $add_options;
    		}
    		curl_setopt_array($curl, $options);
    		$response = json_decode(curl_exec($curl), true);
    		curl_close($curl);
    		return $response;
    }

    表示側

    $options = [
    		CURLOPT_HEADER =>  false,
    		CURLOPT_RETURNTRANSFER =>  true,
    		CURLOPT_TIMEOUT =>  15,
    ];
    $next_page_code = '';
    if (!empty(wp_unslash( $_GET['youtube_per_page'] ))) {
    	$next_page_code = wp_unslash( $_GET['youtube_per_page'] );
    }
    if (!empty($next_page_code)) {
    	$youtube_options['pageToken'] = $next_page_code;
    }
    $youtube_api_url = "https://www.googleapis.com/youtube/v3/search?".http_build_query($youtube_options, '&');
    $youtube_items = exec_curl($youtube_api_url,$options);
    							
    $http = is_ssl() ? 'https' : 'http' . '://';
    $url = $http . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
    							
    if ($youtube_items['nextPageToken']) {
    	$url = $url . $youtube_items['nextPageToken'];
    }
    ?>
    <?php if ($youtube_items['items']): ?>
    	<?php foreach($youtube_items['items'] as $item){
    		echo '<div class="youtube-movie"><iframe width="560" height="315" src="https://www.youtube.com/embed/' . $item['id']['videoId'] . '" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>';
    	} ?>
    	<?php if ($youtube_items['nextPageToken']): ?>
    		<a href="<?php echo 'http://inokawablog.local/youtube/?youtube_per_page=' . $youtube_items['nextPageToken']; ?>">次のページ</a>
    	<?php endif; ?>
    <?php else: ?>
    	<p>動画を取得することができませんでした。</p>
    <?php endif; ?>

     

    “次へ”を実装したかったのですが、1日のリクエスト数に達してしまうと表示できなくなってしまうので、表示する数を制限して”もっとみる”のリンクを出してチャンネルに飛ばす方が良いと思います。

     

    “次へ”を実装する場合は、こうなります。

    if (!empty($next_page_code)) {
        $youtube_options['pageToken'] = $next_page_code;
    }

    レスポンスの中に”nextPageToken”という項目があるので、その値が存在する場合にその値をurlにパラメータとして付与して、APIを叩くと次のページの動画を取得することができます。

    WordPressでurlに付与されたパラメータを取得するときは、

    if (!empty(wp_unslash( $_GET['youtube_per_page'] ))) {
        $next_page_code = wp_unslash( $_GET['youtube_per_page'] );
    }

    $_GETでurlからパラメータを取得して、wp_unslashで不要なバックスラッシュを除去します。

    APIで動画一覧も表示できて、リロードしたらこんなエラーが、

    'message' => string 'The request cannot be completed because you have exceeded your <a href="/youtube/v3/getting-started#quota">quota</a>.'

     

    403エラーなのでアクセス拒否されているのですが、APIの403って認証できてるけど、権限ないよって感じですよね。

    何だこれ。さっきまで取れていたのに。エラーの解決法探したんですがよくわからないので、とりあえず放置。wp_remote_getの方ではエラーが出なかったのでそちらを使っています。

     

     

    wp_remote_get

    最初はcURLを使っていたのですが、WordPressにはwp_remote_getというリクエスト用の関数が用意されています。

    https://codex.wordpress.org/Function_Reference/wp_remote_get

     

    ということでwp_remote_getを使用して、これを使うと、

    表示側

    <?php
    	$youtube_api_key = 'API KEY'; //API KEY
    	$youtube_channel_id = 'チャンネルID'; //チャンネルID
    	$youtube_options = array(
    			'key' => $youtube_api_key,
    			'part' => 'snippet',
    			'maxResults' => '8',
    			'type' => 'video',
    			'order' => 'date',
    			'channelId' => $youtube_channel_id,
    	);
    	$result = wp_remote_get("https://www.googleapis.com/youtube/v3/search?".http_build_query($youtube_options, '&'));
    	$youtube_items = json_decode($result['body'],true);
    	if ( ! is_wp_error( $result ) && $result['response']['code'] === 200 ) :
    ?>
    	<?php foreach($youtube_items['items'] as $item){
    		echo '<div class="youtube-movie"><iframe width="560" height="315" src="https://www.youtube.com/embed/' . $item['id']['videoId'] . '" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>';
    	} ?>
    	<a id="go-to-youtube-channel" href="youtubeチャンネルのリンク">もっとみる</a>
    <?php else: ?>
    	<p>動画を取得することができませんでした。</p>
    <?php endif; ?>

     

    コード解説

    $youtube_options = array(
    		'key' => $youtube_api_key,
    		'part' => 'snippet',
    		'maxResults' => '8',
    		'type' => 'video',
    		'order' => 'date',
    		'channelId' => $youtube_channel_id,
    );

    $youtube_optionsでapiで動画を持ってくるオプションを設定します。

    searchオプションの設定項目はここのページにまとまっています。

    maxResultsで持ってくる動画の最大数を設定します。設定するところはそこくらいでいいと思います。

     

    そして、wp_remote_getにurlを渡します。レスポンスのbodyに内容が入っています。

    レスポンスの内容はここののページにまとめられています。

    レスポンスのbodyですがstringで返ってくるのでjson_decodeで配列にしています。

     

    functions.phpに書く必要がなくなり、短くなるのでいいですね。

    便利ですでにあるものは積極的に使って行きましょう。

     

     

     

    余談

    cURLでちょっと詰まったところ。

    cURLを叩いてjson_decodeでreturnした結果をforeachで回そうと思ったら、

    Fatal error: Uncaught Error: Cannot use object of type stdClass as array

    というエラーが。objectをforeachで回していてこのエラーが出ていたみたいです。

    そもそもなんでjson_decodeしているのにobjectがreturnされているのかと思って、functions.phpに書いたcURLをみてみると、

    json_decode(curl_exec($curl));

    になっていました。正しくはこちらです。

    json_decode(curl_exec($curl), true);

     

    json_decodeは第二引数をtrueで渡すと連想配列の形で返してくれるんですよね。今回いつもクラスでまとめて使っているcURLの処理をコピペした時にちょっと手直ししたのですが、その時に変えてしまったようですね。

    最初arrayでキャストしてたんですが入れ子になった部分まではキャストされないのでエラーが出てしまいました。cURLでobjectが帰ってきたらjson_decodeを疑えば良いとわかりました。

     

    単純なミスは気をつけていきたいです。でも実際こーゆー小さいことに時間を取られたりするんですよね。