なぜcurlなのか
公式で提供されているクライアントライブラリを利用するのがお手軽かと思います。
今回は実行するマシン(主にMac)でライブラリのセットアップを必要とせず、そのまま実行できることを目的としてcurl
を選びました。
Google Drive APIを実行するために
各種APIを実行するにはアクセストークン
が必要になります。
OAuth 2.0クライアントの作成
Google Cloud Platform (GCP)でプロジェクトを作成。
有効なAPIとサービス
より、Google Drive APIを有効化。
認証情報を作成
より、OAuth クライアントID
を選択。
ウェブアプリケーション
、リダイレクトURLをhttp://localhost:8080
を指定して作成。
作成後、
クライアントID
やシークレットID
を控える。
Authorization Code
を取得
認証を行うURLを作成し、ブラウザでGoogle Driveの操作を行うアカウントからOAuth認証します。
パラメータ | |
---|---|
client_id | 先ほど取得した値 |
redirect_uri | https://localhost:8080 |
scope | 権限 スコープ の値はコチラを参照。ファイルアップロード/ダウンロードであれば2つで十分です。 https://www.googleapis.com/auth/drive : Google ドライブのすべてのファイルの表示、編集、作成、削除を行えます https://www.googleapis.com/auth/drive.metadata : Google ドライブ内のファイルのメタデータの表示と管理 |
response_type | code |
access_type | offline |
組み立て
https://accounts.google.com/o/oauth2/auth?client_id=[クライアントID]& redirect_uri=https://localhost:8080& scope=https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.metadata& response_type=code& access_type=offline
アクセスを許可する。
localhostなのでアクセスできません となりますが、アドレスバーからAuthorization Code
を確認できます。
http://localhost:8080/?code=[Authorization Code]& scope=https://www.googleapis.com/auth/drive%20https://www.googleapis.com/auth/drive.metadata
リフレッシュトークン
を取得
先ほど取得したAuthorization Code
を使ってリフレッシュトークン
を取得します。
curl 'https://www.googleapis.com/oauth2/v4/token' \ --data 'code=[Authorization Code]' \ --data 'client_id=[クライアントID]' \ --data 'client_secret=[シークレットID]' \ --data 'redirect_uri=http://localhost:8080' \ --data 'grant_type=authorization_code' \ --data 'access_type=offline'
レスポンス
{ "access_token": "ya29.*****", "expires_in": 3599, "refresh_token": "1//*****", "scope": "https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.metadata", "token_type": "Bearer" }
アクセストークンとリフレッシュトークンが得られます。
アクセストークンは1時間で有効期限が切れるので、リフレッシュトークンを使って再取得します。
アクセストークンを取得
curl 'https://www.googleapis.com/oauth2/v4/token' \ --data refresh_token=[リフレッシュトークン] \ --data client_id=[クライアントID] \ --data client_secret=[シークレットID] \ --data grant_type=refresh_token
レスポンス例
{ "access_token": "*****", "expires_in": 3599, "scope": "https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.metadata", "token_type": "Bearer" }
有効期限が切れた状態でAPIを実行するとエラーコード 401 が返るので、再度アクセストークンを取得し直してください。
{ "error": { "code": 401, "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "errors": [ { "message": "Invalid Credentials", "domain": "global", "reason": "authError", "location": "Authorization", "locationType": "header" } ], "status": "UNAUTHENTICATED" } }
アップロード
アップロード先が共有ドライブの場合、supportsAllDrives=true
を指定する。
マイドライブの場合はfalse
でも可。
curl -X POST 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&supportsAllDrives=true' \ -F "metadata={name:'[ファイル名]', mimeType:'application/octet-stream', parents:['[ドライブID]']};type=application/json;charset=UTF-8" \ -F 'file=@'[ファイルパス]';type=application/octet-stream' \ -H 'Authorization: Bearer [トークン]'
レスポンス例
{ "kind": "drive#file", "id": "[ファイルID], "name": "hoge.png", "mimeType": "image/png" }
ダウンロード
-o
オプションでファイル保存。
ドライブ上と同じファイル名が不明で同名で保存したい場合、メタデータを別途取得する必要がある。
curl -X GET 'https://www.googleapis.com/drive/v3/files/[ファイルID]?alt=media' \ -o [ファイル名] \ -H "Accept: application/json" \ -H "Authorization: Bearer [トークン]"
ファイルメタデータ
共有ドライブ内のファイルの場合、supportsAllDrives=true
を指定。
curl -X GET 'https://www.googleapis.com/drive/v3/files/[ファイルID]?supportsAllDrives=true' \ -H "Accept: application/json" \ -H "Authorization: Bearer [トークン]"
レスポンス例
{ "kind": "drive#file", "id": "[ファイルID]", "name": "[ファイル名]", "mimeType": "text/plain", "teamDriveId": "[チームドライブID]", "driveId": "[ドライブID]" }
フォルダ内ファイルの列挙
少し複雑、クエリを使用します。
デフォルトだとゴミ箱に移動したファイルも列挙されるため、trashed=false
で除外する。
共有ドライブの場合、supportsAllDrives
とincludeItemsFromAllDrives
の両方をtrueに指定する。
curl -X GET 'https://www.googleapis.com/drive/v3/files?q='"'"'[フォルダID]'"'"'+in+parents+and+trashed=false&supportsAllDrives=true&includeItemsFromAllDrives=true' \ -H "Authorization: Bearer [トークン]"
レスポンス例
{ "kind": "drive#fileList", "incompleteSearch": false, "files": [ { "kind": "drive#file", "driveId": "[ドライブID]", "mimeType": "text/plain", "id": "[ファイルID]", "name": "[ファイル名]", "teamDriveId": "[チームドライブID]" }, { "kind": "drive#file", "driveId": "[ドライブID]", "mimeType": "text/plain", "id": "[ファイルID]", "name": "[ファイル名]", "teamDriveId": "[チームドライブID]" }, {略 } ] }
ページング
pageSize
を指定しない場合は最大100件のファイルを列挙しますが、
超える場合はnextPageToken
というフィールドが追加されます。
{ "nextPageToken": "[ページトークン]", "kind": "drive#fileList", "incompleteSearch": false, "files": [ { "kind": "drive#file", "driveId": "[ドライブID]", "mimeType": "text/plain", "id": "[ファイルID]", "name": "[ファイル名]", "teamDriveId": "[チームドライブID]" }, {略 }, ] }
全ファイルを列挙する際はnextPageToken
が無くなるまで順次実行します。
※ MacのZshで実行する際のハマりポイント
ページトークンは先頭 ~!!~
から始まるのですが、ヒストリー展開されてエラーになることがありました。
なのでURL全体はダブルクォートではなく、シングルクォートでエスケープするようにしています。
curl -X GET 'https://www.googleapis.com/drive/v3/files?q='"'"'[フォルダID]'"'"'+in+parents+and+trashed=false&supportsAllDrives=true&includeItemsFromAllDrives=true&pageToken=[ページトークン]' \ -H "Authorization: Bearer [トークン]"