概要
Google Photos API を使って Google Photo アプリを作成してみました
OAuth2 認証を使って認証したユーザが持つ写真とアルバムの情報を表示してみます
環境
- macOS 10.15
- Ruby 2.6.2p47
- Google Photos API (2019/11/05 時点)
Google Photos API の有効化
初めての場合はここから API を有効にできます
「Enable the Google Photos Library API」を選択します
プロジェクトを選択するダイアログが表示されるので API を有効にするプロジェクトを選択します
OAuth をコールするクライアントを選択します
今回はブラウザアプリを作成するので「Web browser」を選択します
CORS は全部許可するのでとりあえず入力しないで OK です
有効になったら API をコールするためのクレデンシャルファイルがダウンロードできます
が、情報が不十分なクレデンシャルなのでダウンロードは一旦保留しておきます
OAuth クライアントの確認/クレデンシャルの取得
API とサービスの画面から「認証情報」を選択します
「OAuth client」というクライアントが作成されているのを確認しましょう
リダイレクト URL が設定されていない場合は設定しましょう
今回は http://localhost:9292/redirect
を設定しました
また今回は設定していませんが「承認済みの JavaScript 生成元」に http://localhost:9292
を設定しても OK です
設定したら保存して上にある「JSON をダウンロード」を選択してクレデンシャルの JSON ファイルを保存します
またダウンロードしたクレデンシャルファイルの名前を「client_secrets.json」に変更しましょう
ライブラリインストール
ここからはコーディングです
まずは必要なライブラリをインストールします
bundle init
vim Gemfile
gem "sinatra"
gem "google-api-client"
bundle install --path vendor
サンプルアプリ
ダウンロードした client_secrets.json
はアプリのルートディレクトリに配置します
vim config.ru
require './app'
run TestWebApp
vim app.rb
require 'sinatra/base'
require 'google/api_client/client_secrets'
require 'json'
require 'net/https'
class TestWebApp < Sinatra::Base
enable :sessions
before do
client_secrets = Google::APIClient::ClientSecrets.load
@auth_client = client_secrets.to_authorization
end
get '/' do
@auth_client.update!(
:redirect_uri => 'http://localhost:9292/redirect',
:scope => [
'https://www.googleapis.com/auth/photoslibrary.readonly',
'https://www.googleapis.com/auth/photoslibrary.readonly.appcreateddata'
]
)
auth_uri = @auth_client.authorization_uri.to_s
redirect auth_uri
end
get '/redirect' do
@auth_client.code = request['code']
@auth_client.fetch_access_token!
auth_client = Signet::OAuth2::Client.new(JSON.parse(@auth_client.to_json))
session[:token] = auth_client.access_token
redirect '/list'
end
get '/list' do
uri = URI.parse 'https://photoslibrary.googleapis.com/v1/albums'
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new uri.request_uri
req['Content-type'] = 'application/json'
req['Authorization'] = "Bearer #{session[:token]}"
res = http.request req
# "<pre>#{JSON.pretty_generate(JSON.parse(res.body))}</pre>"
@albums = JSON.parse(res.body)
erb :list
end
get '/:album_id/list' do
uri = URI.parse 'https://photoslibrary.googleapis.com/v1/mediaItems:search'
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new uri.request_uri
req['Content-type'] = 'application/json'
req['Authorization'] = "Bearer #{session[:token]}"
req.body = {
"pageSize" => "100",
"albumId" => params['album_id']
}.to_json
res = http.request req
@media_items = JSON.parse(res.body)
erb :items
end
end
mkdir views/
vim views/list.erb
<html>
<head>
<title>test web app</title>
</head>
<body>
<h1>Albums</h1>
<ul>
<% @albums['albums'].each do |album| %>
<li><a href="/<%= album['id'] %>/list"><%= album['title'] %></a></li>
<% end %>
</ul>
</body>
</html>
vim views/items.erb
<html>
<head>
<title>test web app</title>
</head>
<body>
<h1>MediaItems</h1>
<ul>
<% @media_items['mediaItems'].each do |item| %>
<li><a href="<%= item['productUrl'] %>" target="_blank"><%= item['filename'] %></a></li>
<% end %>
</ul>
</body>
</html>
説明
まずは OAuth2 認証します
/
にアクセスすると認証が開始されます
認証部分は SDK の機能が使えるのでそのまま使います
認証自体は Google が用意してくれている同意画面を使います
許可するスコープは「https://www.googleapis.com/auth/photoslibrary.readonly
」と「https://www.googleapis.com/auth/photoslibrary.readonly.appcreateddata
」になります
前者はアルバムへのアクセス権限で後者はアルバムの配下の写真にアクセスするための権限です
Google 側で認証と認可が成功するとアプリの /redirect
に戻ってきます
認証が成功していると Google Photos API をコールするためのセッショントークンが返ってきます
このセッショントークンを使って Google Photos API をコールします
Ruby の google-api-client
には Google Photos API の SDK が含まれていないので直接 REST API をコールしています
今回はアルバムの一覧を表示する画面とアルバム配下の写真の一覧を表示するビューを作成しています
写真は 100 枚ごとに取得しておりもし次のページが存在する場合は nextPageToken
が付与されています
これを使ってリクエストすることで次のページの写真を取得することができます (参考)
動作確認
bundle exec rackup config.ru
http://localhost:9292
にアクセスしましょう
認証画面が出るのでユーザを選択します
警告画面が表示されますがテストなので気にせず移動します
もし「承認済みの JavaScript 生成元」を設定している場合はこの警告はでません
アルバムを選択するとアルバム配下の写真の一覧が表示されます
写真のリンクをクリックすると実際の写真を確認することができます
最後に
Google Photos API を Ruby からコールしてみました
Ruby には専用の SDK がなかったですが Java と Node.js には実装されているようです
API をコールする前に OAuth2 の認証を設定/実装する必要があるのでそっちが大変かなと思います
また今回はアルバムと写真の取得の API のみ使っています
他にも共有アルバムを取得する API や写真をアップロードする API もあるので興味があれば試してみてください
Tips
{"error": "unsupported_grant_type", "error_description": "Invalid grant_type: "}
が出る場合はクレデンシャルの JSON ファイルの情報が不足している可能性があるので再度ダウンロードし直してください
0 件のコメント:
コメントを投稿