Google Photo APIガイド

参照したサイト

こちら こちら こちら

APIの有効化

OAuth 同意画面の作成

  • 内部は選べないので外部を選択キャプチャ07
  • 設定項目
    • アプリケーション名は任意(とりあえずQuickstartにした)
    • アプリケーションロゴは無くても良い
    • サポートメールは初期値
    • その他の項目はさわらなくてもOK

認証情報の追加

  • コンソール画面に戻り左上の"ナビゲーションメニュー"-"APIとサービス"-"認証情報"と辿るキャプチャ02
  • 上部にある"認証情報の作成"をクリック→"OAuthクライアントIDを作成を選択"
  • OAuth クライアント ID の作成画面に変わるのでアプリケーションの種類をその他にする(名前は適当に)キャプチャ09

    ※使用しているgoogleアカウントによっては(古いアカウント?)の場合は画面が異なる場合があるのでその際はデスクトップアプリケーションにする(名前は適当に)キャプチャ08.1

  • 下部にある"作成"をクリック

  • "OAuth クライアントを作成しました"とポップアップ表示されるので、クライアントIDとクライアントシークレットを控える

認証用URLの作成

  1. 認証用コードの取得

     https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=<認証情報の追加で作成したクライアントID>&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/photoslibrary.readonly
    

    ※当初&access_type=offlineを付与していたが、アクセストークンの取得時に"invalid_grant"のエラーが出たため外した。
    参照さえ出来ればいいのでスコープはreadonlyにした。

    • 上記URLを作成してブラウザにコピペするとログイン画面に遷移するので該当するユーザーでログインする
      ※今回「このアプリは確認されていません」と警告ページに遷移してしまったがとりあえず"詳細"からQuickstart(安全ではないページ)に移動をクリックした。
    • 権限の付与のポップアップが表示されたら"許可"をクリック、その後表示されるコードを控ておく キャプチャ06

  2. アクセストークンの取得

    以下をcurlで実行

     curl -s --data "1.で取得したコード" --data "client_id=クライアントID" --data "client_secret=クライアントシークレット" --data "redirect_uri=urn:ietf:wg:oauth:2.0:oob" --data "grant_type=authorization_code" --data "access_type=offline" https://www.googleapis.com/oauth2/v4/token
    

    powershellでやるなら

     $uri = "https://www.googleapis.com/oauth2/v4/token"
     $body=@{
     "code"="1.で取得したコード"
     "client_id"="クライアントID"
     "client_secret" = "クライアントシークレット"
     "redirect_uri"="urn:ietf:wg:oauth:2.0:oob"
     "grant_type"="authorization_code"
     }
    
     $response = Invoke-RestMethod  -Uri $uri -Body $body -Method Post
     echo $response
    

    するとこのような結果が返ってくる

     {
     "access_token": アクセストークン,
     "expires_in": 3599,
     "refresh_token": "リフレッシュトークン",
     "scope": "https://www.googleapis.com/auth/photoslibrary.readonly",
     "token_type": "Bearer"
     }
    

    トークンには有効期限(expires_in ⇒ 1時間)があるので期限が切れたらrefresh_tokenの値で再取得が必要
    curlで取得するなら

     curl -s --data "refresh_token=リフレッシュトークン" --data "client_id=クライアントID" --data "client_secret=クライアントシークレット" --data "grant_type=refresh_token" https://www.googleapis.com/oauth2/v4/token
    

    powershellなら

     $uri = "https://www.googleapis.com/oauth2/v4/token"
     $body=@{
     "refresh_token"="リフレッシュトークン"
     "client_id"="クライアントID"
     "client_secret" = "クライアントシークレット"
     "grant_type"="refresh_token"
     }
     $response =  Invoke-RestMethod -Uri $uri -Body $body -Method Post
     echo $response.access_token
    

実行してみる

とりあえずcurlから

curl -s -H "Authorization: Bearer アクセストークン" https://photoslibrary.googleapis.com/v1/albums

するとたぶんjson形式で取得出来る

{
  "albums": [
    {
      "id": " ",
      "title": " ",
      "productUrl": " ",
      "mediaItemsCount": "1",
      "coverPhotoBaseUrl": " ",
      "coverPhotoMediaItemId": "AA-???"
    },
    {
      "id": " "
      "title": " "
      "productUrl": " "
      "mediaItemsCount": "9",
      "coverPhotoBaseUrl": " "
      "coverPhotoMediaItemId": "AAjku"
    },
    {
      "id": " "
      "title": " "
      "productUrl": " "
      "mediaItemsCount": "4",
      "coverPhotoBaseUrl": " "
      "coverPhotoMediaItemId": "AA-"
    }
  ]
}

powershellだこんな感じか


# Invoke-WebRequestだと
$response=Invoke-WebRequest https://photoslibrary.googleapis.com/v1/albums -Headers @{"Authorization" = "Bearer アクセストークン"}

echo $response.Content

# Invoke-RestMethodだと
Invoke-RestMethod -Uri https://photoslibrary.googleapis.com/v1/albums -Headers @{"Authorization" = "Bearer アクセストークン"}

echo $response.albums

特定のアルバムにあるアイテムの一覧

リファレンス

アルバムIDで抽出

$header = @{"Authorization" = "Bearer アクセストークン"
}
$body=@{
"albumId"="アルバムの一覧で取得したアルバムID"
}
$response =  Invoke-RestMethod -Uri https://photoslibrary.googleapis.com/v1/mediaItems:search -Headers $header -Body $body -Method Post

$response.mediaItems

日付範囲で抽出

$header = @{"Authorization" = "Bearer アクセストークン"
}
$body = '{"filters":{"dateFilter": {"ranges":[{"startDate": {"year":<年>,"month":<月>,"day":<日>},"endDate": {"year":<年>,"month":<月>,"day":<日>}}]}}}';
$response =  Invoke-RestMethod -Uri https://photoslibrary.googleapis.com/v1/mediaItems:search -Headers $header -Body $body -ContentType "application/json" -Method Post 
$response.mediaItems

※bodyに渡すjsonを直書きする場合は-ContentType "application/json"が必要になるらしい。
連想配列で行う場合は

$body = 
@{
    filters = @{
        dateFilter = @{
            ranges = @(
                @{
                startDate = 
                    @{year = 2020; month = 1; day = 1 
                    }        
                endDate =
                    @{year = 2020; month = 2; day = 10 
                    }
                }
                    )
                }
            }
} | ConvertTo-Json -Depth 100
$response =  Invoke-RestMethod -Uri https://photoslibrary.googleapis.com/v1/mediaItems:search -Headers $header -Body $body -ContentType "application/json" -Method Post 
# -Depthをつけないと正しくjsonが作成されない
# アルバムIDの連想配列ではRestMethodで-ContentType "application/jsonを入れなくても実行できたが、日付範囲の連想配列では入れないとエラーになった

複数ページに跨る場合

デフォルトでは一度のリクエストで抽出できる件数が恐らく25件なのでアルバムやアルバム内のアイテムがそれ以上ある場合はページサイズを増やすか、nextPageTokenを使用して残りを取得しなければならない RESTのページネーション

  • ページサイズの増やし方
    単純にbodyに追加すればよい(最大は100)

          $body=@{
          "albumId"=$albumID
          "pageSize" = 50
          }
    
  • nextPageTokenから取得
    例えばアルバム内に35アイテム存在する場合

      $header = @{"Authorization" = "Bearer $ACCESS_TOKEN"
      }
      $body=@{
      "albumId"=$albumID
      }
      $response =  Invoke-RestMethod -Uri https://photoslibrary.googleapis.com/v1/mediaItems:search -Headers $header -Body $body -Method Post
    

    $response.mediaItemsには25アイテム分格納されるため、残り10アイテムはnextPageTokenがなくなるまで以下を繰り返してやればよい

      $pagetoken = $response.nextPageToken
      $body=@{
      "albumId"=$albumID
      "pageToken" = $pagetoken
      }
      $response =  Invoke-RestMethod -Uri https://photoslibrary.googleapis.com/v1/mediaItems:search -Headers $header -Body $body -Method Post