google-drive について
curl、jq、Drive API を使い、ユーザーが選択したファイルやアプリに共有したファイルを扱うコマンドラインガイドです。読み取り、エクスポート、アップロード、変更手順に加え、権限範囲と破壊的操作前の確認を扱います。
主な機能
- 01OAuth 接続とアカウントの確認
- 02指定フォルダー内の項目一覧
- 03ファイルの読み取り、ダウンロード、エクスポート
- 04ファイルのアップロード、名前変更、移動
- 05アクセス制限の順守と変更前の確認
活用シーン
- 01指定した Google ドキュメントやシートの読み取り
- 02Drive フォルダーへのレポートのアップロード
- 03確認後のファイル名変更や移動
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ acedatacloud/ skills --skill google-driveインストール後、Claude Code で/google-driveを入力して読み込まれたか確認します。
詳細
curl + jq を使って Google Drive を操作します。ユーザーの OAuth ベアラートークンは
$GOOGLE_DRIVE_TOKEN にあり、すべての呼び出しで次のように指定する必要があります。
Authorization: Bearer $GOOGLE_DRIVE_TOKEN。トークンには
drive.file と ID 用スコープ(openid email profile)が含まれ、このアプリでユーザーが選択、開いた、作成した、または共有したファイルにのみアクセスできます。
Drive API は標準的な JSON を返します。エラーは
{"error": {"code": 401|403|..., "message": "..."}} の形式で返されます。エラーは
そのままユーザーに表示してください。401 はトークンの期限切れを意味するため、ユーザーは
コネクターを再インストールする必要があります。403 insufficientPermissions
は、ファイルがこのアプリと共有されていないか、Google による審査中に一時的に無効化されている、より広範な Drive スコープを必要とする操作であることを意味します。
Drive 全体を対象とした検索には、このスキルを使用しないでください。「最近のファイル一覧」、 Drive 全体の全文検索、「自分と共有」ファイルのスキャン、ルートフォルダーの 整理、Drive 全体を検索した結果に基づくファイルの一括移動は行わないでください。まずユーザーに、対象のファイルまたはフォルダーの ID を正確に選択するか貼り付けてもらってください。
破壊的な書き込みを行う前に必ず(名前の変更、移動、ゴミ箱への移動、ファイルの一括変更)、対象の一覧を正確に示し、ユーザーに確認を求めてください。ID を推測してゴミ箱に移動してはいけません。操作対象のファイル名とパスを必ずユーザーに伝えてください。
必ず最初に /about?fields=user を実行して、接続が機能していることを確認し、操作対象の Google アカウントを把握してください。
オプション:アップロード用 Google Workspace CLI(gws)
gws は Google の公式 CLI です(公式サポート対象ではなく、コミュニティによってメンテナンスされています。対象組織は googleworkspace です)。Google の Discovery Document からコマンド体系を動的に構築し、API エラー時にはゼロ以外の終了コードを返します。--page-all による自動ページネーションに対応し、マルチパートアップロードプロトコルをラップする +upload ヘルパーが付属しています。
アップロードには gws を使用してください。 Drive のマルチパートアップロードでは、JSON メタデータ部分とバイナリファイル部分を境界文字列で区切った、手動で整形した multipart/related ボディが必要です。curl では間違えやすいため、gws drive +upload を使えば正しく実行できます。それ以外のすべての操作
(取得、エクスポート、名前の変更、移動、ゴミ箱への移動、削除)では、以下の curl のレシピも同等の処理をより短く記述できます。そちらを使用してください。
インストール
npm install -g @googleworkspace/cli # or: brew install googleworkspace-cli
# Pre-built binaries also at https://github.com/googleworkspace/cli/releases
gws --version
認証
gws は GOOGLE_WORKSPACE_CLI_TOKEN 環境変数から OAuth ベアラートークンを読み取ります。このスキルで使用する Drive トークンは
$GOOGLE_DRIVE_TOKEN にあるため、gws を呼び出すすべてのシェルブロックの先頭で、一度再エクスポートしてください。
export GOOGLE_WORKSPACE_CLI_TOKEN="$GOOGLE_DRIVE_TOKEN"
アップロード
# Simple upload to My Drive (auto-detects MIME type, sets the file name
# from --name; falls back to the local filename if --name is omitted)
gws drive +upload ./report.pdf --name "Q1 Report"
# Upload into a specific folder, or with explicit metadata, via the
# generic Discovery method + --upload (multipart wire format handled
# for you)
gws drive files create \
--json '{"name":"report.pdf","parents":["FOLDER_ID"],"description":"Q1"}' \
--upload ./report.pdf
Google がリクエストを拒否した場合、どちらも構造化 JSON エラーを標準エラー出力に出力し、ゼロ以外の終了コードで終了します。そのままユーザーに表示してください。
レシピ
認証の確認(必ず最初に実行)
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
"https://www.googleapis.com/drive/v3/about?fields=user(displayName,emailAddress,photoLink),storageQuota(usage,limit)" \
| jq '{user, quota: .storageQuota}'
選択したフォルダー内の子項目を一覧表示
ユーザーがフォルダー ID を明示的に選択または指定した場合にのみ使用してください。
FOLDER_ID='1A2B3CdEfGhIjKlMn'
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
--get "https://www.googleapis.com/drive/v3/files" \
--data-urlencode "q='$FOLDER_ID' in parents and trashed = false" \
--data-urlencode 'fields=files(id,name,mimeType,size,modifiedTime),nextPageToken' \
| jq '.files'
単一ファイルのメタデータを取得
FILE_ID='1A2B3CdEfGhIjKlMn'
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
"https://www.googleapis.com/drive/v3/files/$FILE_ID?fields=id,name,mimeType,size,modifiedTime,parents,owners,webViewLink,description"
バイナリファイルをダウンロード(PDF/画像/zip など)
FILE_ID='1A2B3CdEfGhIjKlMn'
OUT=/tmp/download.bin
curl -sS -L -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
"https://www.googleapis.com/drive/v3/files/$FILE_ID?alt=media" \
-o "$OUT"
file "$OUT" && wc -c "$OUT"
Google ドキュメントをプレーンな Markdown/テキストとして読み込む
Google ネイティブファイル(Docs、Sheets、Slides)には未加工のバイト列がありません。 具体的な MIME タイプを指定して、Drive にエクスポートを依頼する必要があります。
DOC_ID='1A2B3CdEfGhIjKlMn'
# Markdown (best for chat-friendly summaries)
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
"https://www.googleapis.com/drive/v3/files/$DOC_ID/export?mimeType=text/markdown" \
> /tmp/doc.md
head -40 /tmp/doc.md
# Plain text fallback for older docs
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
"https://www.googleapis.com/drive/v3/files/$DOC_ID/export?mimeType=text/plain" \
> /tmp/doc.txt
一般的なエクスポート MIME タイプ:
| ネイティブ MIME | エクスポート先 |
|---|---|
application/vnd.google-apps.document | text/markdown、text/plain、text/html、application/pdf、application/vnd.openxmlformats-officedocument.wordprocessingml.document |
application/vnd.google-apps.spreadsheet | text/csv、application/pdf、application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
application/vnd.google-apps.presentation | application/pdf、text/plain、application/vnd.openxmlformats-officedocument.presentationml.presentation |
Google スプレッドシートを CSV として読み込む
SHEET_ID='1A2B3CdEfGhIjKlMn'
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
"https://www.googleapis.com/drive/v3/files/$SHEET_ID/export?mimeType=text/csv" \
> /tmp/sheet.csv
head /tmp/sheet.csv
Drive の export エンドポイントが返すのは最初のシートのみです。複数のタブにアクセスするには、別の Google Sheets コネクターをインストールする必要があります(現在カタログにはありません)。そのことを説明して、そこで終了してください。
ファイルの権限/共有設定を取得
FILE_ID='1A2B3CdEfGhIjKlMn'
curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
"https://www.googleapis.com/drive/v3/files/$FILE_ID/permissions?fields=permissions(id,type,role,emailAddress,domain,deleted)" \
| jq '.permissions[] | {who: (.emailAddress // .domain // .type), role}'
書き込みレシピ
これらは drive.file 経由で利用できるファイルとフォルダーにのみ適用されます。
Google が 403 insufficientPermissions を返した場合は、エラーを表示し、
ユーザーに対象ファイルをアプリで選択するか、アプリと共有するよう依頼してください。
ゴミ箱に移動したり、一括で移動したりする前に、必ず
対象の名前とパスをユーザーに伝えてください。
ファイル名を変更する
FILE_ID='1A2B3CdEfGhIjKlMn'
NEW_NAME='2026 Q2 OKR (final).gdoc'
curl -sS -X PATCH -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
-H 'Content-Type: application/json' \
--data "{\"name\":$(jq -nr --arg n "$NEW_NAME" '$n')}" \
"https://www.googleapis.com/drive/v3/files/$FILE_ID?fields=id,name"
ファイルを別のフォルダーに移動する
Drive のフォルダーモデルは親 ID に基づいています。移動とは、古い親を削除し、 新しい親を追加することです。
FILE_ID='1A2B3CdEfGhIjKlMn'
NEW_PARENT='1XYZnewFolderId'
# Read existing parents (so we can pass them in removeParents)
OLD_PARENTS=$(curl -sS -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
"https://www.googleapis.com/drive/v3/files/$FILE_ID?fields=parents" \
| jq -r '.parents | join(",")')
curl -sS -X PATCH -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
--data '' \
"https://www.googleapis.com/drive/v3/files/$FILE_ID?addParents=$NEW_PARENT&removeParents=$OLD_PARENTS&fields=id,name,parents"
新しいフォルダーを作成する
PARENT_ID='1XYZparentFolderId' # or 'root' for My Drive root
curl -sS -X POST -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
-H 'Content-Type: application/json' \
--data "{\"name\":\"Reports / 2026Q2\",\"mimeType\":\"application/vnd.google-apps.folder\",\"parents\":[\"$PARENT_ID\"]}" \
"https://www.googleapis.com/drive/v3/files?fields=id,name,webViewLink" \
| jq
ファイルをアップロードする(メタデータとバイト列を1つのリクエストで送るマルチパート形式)
LOCAL=/tmp/report.pdf
NAME='Q2 report.pdf'
PARENT_ID='1XYZparentFolderId'
MIME='application/pdf'
BOUNDARY='aceDataBoundary'
META=$(jq -nc --arg n "$NAME" --arg p "$PARENT_ID" '{name:$n, parents:[$p]}')
{
printf -- '--%s\r\n' "$BOUNDARY"
printf 'Content-Type: application/json; charset=UTF-8\r\n\r\n'
printf '%s\r\n' "$META"
printf -- '--%s\r\n' "$BOUNDARY"
printf 'Content-Type: %s\r\n\r\n' "$MIME"
cat "$LOCAL"
printf '\r\n--%s--\r\n' "$BOUNDARY"
} > /tmp/_drive_upload.bin
curl -sS -X POST -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
-H "Content-Type: multipart/related; boundary=$BOUNDARY" \
--data-binary @/tmp/_drive_upload.bin \
"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,name,webViewLink" \
| jq
メディアのみをアップロードする(メタデータなし)場合は uploadType=media を使用します。5 MB を超える
ファイルには uploadType=resumable を使用します([Drive のドキュメント]
(https://developers.google.com/drive/api/guides/manage-uploads#resumable)で説明されています)。
既存ファイルの内容を置き換える
FILE_ID='1A2B3CdEfGhIjKlMn'
LOCAL=/tmp/report-v2.pdf
curl -sS -X PATCH -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
-H 'Content-Type: application/pdf' \
--data-binary @"$LOCAL" \
"https://www.googleapis.com/upload/drive/v3/files/$FILE_ID?uploadType=media&fields=id,name,modifiedTime"
メタデータ(id / parents / name)はそのまま維持され、バイト列のみが置き換えられます。Drive は modifiedTime を更新します。
ファイルをゴミ箱に移動する(または復元する)
FILE_ID='1A2B3CdEfGhIjKlMn'
curl -sS -X PATCH -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"trashed":true}' \
"https://www.googleapis.com/drive/v3/files/$FILE_ID?fields=id,name,trashed"
# Restore:
curl -sS -X PATCH -H "Authorization: Bearer $GOOGLE_DRIVE_TOKEN" \
-H 'Content-Type: application/json' \
--data '{"trashed":false}' \
"https://www.googleapis.com/drive/v3/files/$FILE_ID?fields=id,name,trashed"
DELETE よりも trashed:true を優先してください。DELETE は完全に削除され、
ユーザーは元に戻せません。ユーザーが「完全に削除」と明示した場合にのみ
DELETE を使用してください。
一般的なエラーコード
| HTTP | 意味 | ユーザーへの案内 |
|---|---|---|
401 UNAUTHENTICATED | トークンの期限切れ/失効 | 「Connections ページで Google Drive コネクターに再接続してください。」 |
403 insufficientPermissions | 対象がアプリと共有されていない/より広範な Drive スコープが無効 | 「現在の drive.file 権限では、このファイルをアプリで利用できません。Google Drive コネクターで該当ファイルを選択するか、共有してから、もう一度お試しください。」 |
403 userRateLimitExceeded | クォータ | 5~10 秒後に1回再試行します。解決しない場合はユーザーに伝えてください。 |
404 notFound | ファイル ID が間違っている、またはこのアプリからファイルを表示できない | ID を再確認し、ユーザーにコネクターでファイルを選択するか、共有するよう依頼してください。 |
400 invalidQuery | q の形式が正しくない | 送信した q とエラーメッセージをユーザーに表示してください。 |
$GOOGLE_DRIVE_TOKEN を記録したり、ユーザーに伝えたりしないでください。秘密情報として扱ってください。