4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Google Photos APIをPHPで使う

Last updated at Posted at 2020-06-01

Google Photos APIを使用して、Google Photoにアクセスするアプリを作成しています。
その過程でのAPIを利用するまでを記載します。

基本的にオフィシャルのリファレンスを参照していますが、そこから読み取りにくい部分などを具体的に紹介できたらと思っております。

Google Photos API

Laravelを使用したコードを記載していますが、Laravelに特化した部分は少ないと思いますので、
Laravel以外のフレームワークを使っている場合もご参考になればと思います。

準備

Laravelプロジェクト作成

$ composer create-project laravel/laravel googlephoto_sample --prefer-dist

Google Photos APIを有効にする

  • Google APIsのダッシュボードからプロジェクト作成 → APIとサービスを有効化 → Google Photos APIを選択
  • Google APIsのプロジェクトが作成済みなら Google Photos API このページから直接もできます

クライアントID作成

  • Google APIsのダッシュボードから「認証情報」を選択 → 認証情報を作成 → OAuthクライアントID
  • アプリケーションの種類は、ウェブアプリケーション
  • 承認済みのリダイレクトURIは、今回は取り合えず http://localhost/photo/redirect
  • 作成したクライアントIDの画面からJSONをダウンロード → credential.jsonにリネームしておく
  • ダウンロードしたcredential.jsonをLaravelプロジェクトのフォルダに入れておきます。

Google APIs Client, Google Photos API ライブラリのインストール

composer.json
    "require": {
        "google/apiclient": "^2.0",
        "google/photos-library": "^1.5"
    },
$ composer update

composer.jsonを編集せずに、直接コマンドラインかrcomposer require google/apiclient:"^2.0"みたいにやるとなぜか失敗します。

Google Photos APIを使ってみる

PhotoControllerという名前のコントローラーと、コントローラーから呼び出されるGooglePhotoServiceという名前のクラスを作成していきます。

認証URLの生成、表示

app\Services\GooglePhotoService.php
<?php
namespace App\Services;

use Google\Auth\Credentials\UserRefreshCredentials;
use Google\Photos\Library\V1\PhotosLibraryClient;

class GooglePhotoService
{
    private function createGoogleClient()
    {
        $client = new \Google_Client();
        $client->setApplicationName('GooglePhotoSample');
        $client->setScopes(\Google_Service_PhotosLibrary::PHOTOSLIBRARY_READONLY); 
        $client->setAuthConfig(base_path("credentials.json"));
        $client->setAccessType('offline');
        return $client;
    }

    public function createAuthUrl($redirectUri)
    {
        $client = $this->createGoogleClient();
        $client->setRedirectUri($redirectUri);
        return $client->createAuthUrl();
    }
}
app\Http\Controllers\PhotoController.php
<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\GooglePhotoService;

class PhotoController extends Controller
{
    public function start()
    {
        $service = new GooglePhotoService();
        $url = $service->createAuthUrl("http://localhost/photo/redirect");
        return view(start, [
            'url' => $url
        ]);
    }
}

resources\views\start.blade.php
<html>
<body>
  <div class="flex-center position-ref full-height">
    <div class="content">
      Step.1<br/>
      <a href="{{$url}}">{{$url}}</a>
    </div>
  </div>
</body>
</html>
routes\web.php
Route::get('/photo/start, 'PhotoController@start);

OAuthのリダイレクト先を作成

リダイレクト時に受け取ったauthCodeをもとにアクセストークンを取得する。
取得したアクセストークンを保存する処理は$saveTokenFunctionという名前のコールバック関数として定義する。

app\Services\GooglePhotoService.php
    public $saveTokenFunction = null;

    public function getAccessToken($authCode)
    {
        $client = $this->createGoogleClient();
        $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
        if ($this->saveTokenFunction != null) {
            call_user_func($this->saveTokenFunction, $accessToken);
        }
        return $accessToken;
    }
app\Http\Controllers\PhotoController.php
    public function saveToken($accessToken)
    {
        // 保存の処理は省略。データベースなどに保存
    }

    public function redirect(Request $request)
    {
        $authCode = $request->input('code');
        $service = new GooglePhotoService();
        $service->saveTokenFunction = [$this, 'saveToken'];
        $service->getAccessToken($authCode);
        return view('redirect', [
        ]);
    }
resources\views\redirect.blade.php
// 省略
routes\web.php
Route::get('/photo/redirect, 'PhotoController@redirect);

PhotosLibraryClientを生成

取得したアクセストークンで、PhotosLibraryClientを生成
アクセストークンの期限が切れたときのリフレッシュの処理も一緒に実装

app\Services\GooglePhotoService.php
    public function getPhotosLibraryClient($accessToken)
    {
        $client = $this->createGoogleClient();
        $client->setAccessToken(json_decode($accessToken, true));
        if ($client->isAccessTokenExpired())
        {
            $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
            if ($this->saveTokenFunction != null) {
                call_user_func($this->saveTokenFunction, $client->getAccessToken());
            }
        }

        $authCredentials = new UserRefreshCredentials(\Google_Service_PhotosLibrary::PHOTOSLIBRARY_READONLY, [
            "client_id" => $client->getClientId(),
            "client_secret" => $client->getClientSecret(),
            "refresh_token" => $client->getRefreshToken()
        ]);
        return new PhotosLibraryClient(['credentials' => $authCredentials]);
    }

PhotosLibraryClientを使用してGoogle Photoからアルバム情報を取得してみる

app\Http\Controllers\PhotoController.php
    public function listAlbums()
    {
        $accessToken = [] // 保存してあるアクセストークンを取得する処理
        // 例) $accessToken = UserToken::where('user_id', auth()->user()->id)->value('token');
        $service = new GooglePhotoService();
        $service->saveTokenFunction = [$this, 'saveToken'];
        $client = $service->getPhotosLibraryClient($accessToken);
        $pagedResponse = $client->listAlbums();
        $data = [];
        foreach ($pagedResponse->iterateAllElements() as $album) {
            $data[] = $album->getTitle();
        }
        return response()->json([
            "title" => $data
        ]);
    }
routes\web.php
Route::get('/photo/albums', 'PhotoController@listAlbums');

以上です

authCodeからAccessTokenを取得する処理を、なんとかAPIだけで完結させたかったのですが
できませんでした。今回は、このような形でウェブページを一度経由してその後APIで利用するという形になりました。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?