参照したサイト
APIの有効化
- GoogleAPIコンソール画面から検索窓にphotoと入力
- 候補から"Photos Library API"を選択して"有効にする"をクリック
OAuth 同意画面の作成
認証情報の追加
- コンソール画面に戻り左上の"ナビゲーションメニュー"-"APIとサービス"-"認証情報"と辿る
- 上部にある"認証情報の作成"をクリック→"OAuthクライアントIDを作成を選択"
OAuth クライアント ID の作成画面に変わるのでアプリケーションの種類をその他にする(名前は適当に)
※使用しているgoogleアカウントによっては(古いアカウント?)の場合は画面が異なる場合があるのでその際はデスクトップアプリケーションにする(名前は適当に)
下部にある"作成"をクリック
- "OAuth クライアントを作成しました"とポップアップ表示されるので、クライアントIDとクライアントシークレットを控える
認証用URLの作成
認証用コードの取得
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(安全ではないページ)に移動をクリックした。 - 権限の付与のポップアップが表示されたら"許可"をクリック、その後表示されるコードを控ておく
- 上記URLを作成してブラウザにコピペするとログイン画面に遷移するので該当するユーザーでログインする
アクセストークンの取得
以下を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