拥有内容管理器权限的服务账号在共享Google Drive创建文件/文件夹时提示‘File not found: DRIVE_ID’错误求助
我来帮你排查这个问题!你遇到的「File not found」错误其实是Google Drive API处理共享Drive(Team Drive)时的常见坑,结合你的代码和权限情况,我整理了几个关键的解决方向:
1. 最关键:API请求必须添加supportsAllDrives: true参数
默认情况下,Drive API的files.create方法不会自动支持共享Drive的操作,必须显式声明这个参数才能让API识别并操作共享Drive资源。你的代码里刚好缺少这个配置,这大概率是报错的核心原因。
修改你的创建文件夹和上传文件代码,在drive.files.create的配置中新增该参数:
修改后的创建文件夹代码:
async function createFolderInDrive(drive, driveId) { try { const folderMetadata = { name: FOLDER_NAME, mimeType: 'application/vnd.google-apps.folder', parents: [driveId], }; const folder = await drive.files.create({ resource: folderMetadata, fields: 'id, name', supportsAllDrives: true // 新增这个参数! }); console.log(`Folder ${folder.data.name} created with ID: ${folder.data.id}`); } catch (err) { console.error('Error creating folder:', err.message); } }
修改后的上传文件代码:
async function uploadFile(drive, fileName, stream) { try { const fileMetaData = { name: fileName, parents: [process.env.DRIVE_ID], mimeType: 'application/pdf', }; const media = { mimeType: 'application/pdf', body: stream, }; const res = await drive.files.create({ resource: fileMetaData, media: media, supportsAllDrives: true // 新增这个参数! }); return res; } catch (err) { console.log('ERROR:', err.message); } }
2. 确认服务账号的权限是直接授予的
你提到自己是「内容管理器」权限,但要注意:服务账号是独立的身份,共享Drive的权限需要直接授予给服务账号的邮箱(也就是你代码里用的CLIENT_EMAIL),不能通过用户组或间接权限传递。
你可以手动登录共享Drive的网页版,在Drive的「共享设置」里添加服务账号邮箱,指定「内容管理器」角色,确保权限是直接绑定的。
3. 验证DRIVE_ID的正确性
虽然你能列出Drive,但还是要确认你用的DRIVE_ID是共享Drive的根ID,而不是某个子文件夹的ID。共享Drive的ID可以在网页版URL里找到:比如https://drive.google.com/drive/u/0/folders/[DRIVE_ID],这里的字符串就是正确的Drive根ID。
4. 检查服务账号的具体角色(附代码)
如果你不确定自己的角色,可以通过Drive API查询该共享Drive的权限列表,筛选出服务账号的条目:
async function checkServiceAccountPermission(drive, driveId) { try { const res = await drive.permissions.list({ fileId: driveId, supportsAllDrives: true, fields: 'permissions(id, role, emailAddress)' }); // 筛选出当前服务账号的权限 const serviceAccountPerm = res.data.permissions.find(p => p.emailAddress === process.env.CLIENT_EMAIL); if (serviceAccountPerm) { console.log('服务账号在该Drive的角色:', serviceAccountPerm.role); } else { console.log('服务账号未被直接授予该Drive的权限,请检查共享设置'); } } catch (err) { console.error('查询权限失败:', err.message); } }
调用这个方法就能明确看到服务账号的具体角色了。
优先尝试添加supportsAllDrives: true参数,这个解决了绝大多数类似问题,如果还是不行,再依次检查权限和Drive ID。
备注:内容来源于stack exchange,提问作者MoeezShahid01

