关于 google-drive
通过 curl、jq 和 Google Drive API 操作用户已选择或共享给应用的文件,适用于需要在命令行处理 Drive 文档的场景。指南包含读取、导出、上传和修改文件的步骤,并强调权限范围与破坏性操作确认。
主要功能
- 01检查 OAuth 连接与账户
- 02列出指定文件夹内容
- 03读取、下载与导出文件
- 04上传、重命名和移动文件
- 05遵循权限限制与修改确认
适用场景
- 01读取指定 Google 文档或表格
- 02向 Drive 文件夹上传报告
- 03在确认后重命名或移动文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ acedatacloud/ skills --skill google-drive安装后在 Claude Code 中输入/google-drive确认已加载。
详细介绍
通过 curl + jq 操作 Google Drive。用户的 OAuth bearer token 位于
$GOOGLE_DRIVE_TOKEN;每次调用都需要将其作为
Authorization: Bearer $GOOGLE_DRIVE_TOKEN。该 token 包含
drive.file 以及身份作用域(openid email profile),只能访问用户为此应用选择、打开、创建或共享的文件。
Drive API 返回标准 JSON;失败时会返回
{"error": {"code": 401|403|..., "message": "..."}}——将该错误原样展示给用户。401 表示 token 已过期,用户必须重新安装连接器。403 insufficientPermissions
表示文件未与此应用共享,或该操作需要更广泛的 Drive 作用域,而该作用域在 Google 审核期间暂时被禁用。
不要使用此技能广泛发现 Drive 内容:不要“列出我最近的文件”、不要在整个 Drive 中进行全文搜索、不要扫描与我共享的内容、不要清理根文件夹,也不要根据覆盖整个 Drive 的查询批量移动文件。先让用户选择或粘贴确切的文件/文件夹 ID。
执行任何破坏性写入之前(重命名、移动、移至垃圾桶或批量修改文件),先展示确切的目标列表并请用户确认。切勿猜测 ID 后移至垃圾桶——始终回显即将操作的文件名和路径。
始终先调用 /about?fields=user,以确认连接正常并了解当前操作所用的 Google 账号。
可选:用于上传的 Google Workspace CLI(gws)
gws 是 Google 的官方 CLI(但不受官方支持——由社区在 googleworkspace 组织下维护)。它根据 Google 的 Discovery Document 动态构建命令界面,遇到 API 错误时以非零状态码退出,支持 --page-all 自动分页,并提供封装 multipart 上传协议的 +upload 辅助命令。
上传请使用 gws。 Drive multipart 上传需要手动构造 multipart/related 请求体,其中 JSON 元数据部分和二进制文件部分由边界字符串分隔——使用 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 bearer token。此技能使用的 Drive token 位于
$GOOGLE_DRIVE_TOKEN,因此每个调用 gws 的 shell
代码块开头都要重新导出一次:
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 拒绝请求,两者都会以非零状态码退出,并在 stderr 上输出结构化 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)没有原始字节数据—— 必须请求 Drive 将其导出为具体的 MIME 类型:
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
上传文件(使用 multipart,以便在一个请求中发送元数据和字节)
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"
优先使用 trashed:true,而非 DELETE——DELETE 是永久操作,用户无法撤销。仅当用户明确说
“永久删除”时才使用 DELETE。
常见错误代码
| HTTP | 含义 | 告知用户的内容 |
|---|---|---|
401 UNAUTHENTICATED | 令牌已过期 / 已撤销 | “请在 Connections 页面重新连接 Google Drive 连接器。” |
403 insufficientPermissions | 目标文件未与应用共享 / 已停用更广泛的 Drive 权限范围 | “在当前 drive.file 权限下,应用无法访问此文件。请在 Google Drive 连接器中选择或共享确切的文件,然后重试。” |
403 userRateLimitExceeded | 配额限制 | 5–10 秒后重试一次;如果问题仍然存在,请告知用户。 |
404 notFound | 文件 ID 错误,或应用无法看到该文件 | 仔细检查 ID;让用户在连接器中选择或共享该文件。 |
400 invalidQuery | q 格式错误 | 向用户显示你发送的 q 和错误消息。 |
切勿记录或回显 $GOOGLE_DRIVE_TOKEN——请将其视为机密。