You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:Google Sheets插件使用drive.file OAuth权限无法创建文件

用drive.file权限在Google Apps Script中创建Drive文件的正确姿势

问题核心

drive.file权限的核心限制是:只能创建与用户通过应用主动选择/打开的资源(文件/文件夹)相关联的新文件,直接调用DriveApp.createFile()创建无关联的根目录文件会触发权限错误,因为这个操作需要完整的drive权限。


解决方案一:结合Google Picker + 高级Drive服务创建文件

这是符合drive.file权限要求的标准流程:通过Picker让用户选择目标文件夹,获得授权后在该文件夹下创建文件。

步骤1:实现Google Picker前端(HTML侧边栏)

创建一个HTML文件(比如Picker.html),用来加载Picker让用户选择文件夹:

<!DOCTYPE html>
<html>
  <head>
    <script src="https://apis.google.com/js/api.js"></script>
    <script>
      function initPicker() {
        gapi.load('picker', () => {
          const picker = new google.picker.PickerBuilder()
            .addView(google.picker.ViewId.FOLDERS)
            .setOAuthToken('<?= ScriptApp.getOAuthToken() ?>')
            .setDeveloperKey('你的API密钥') // 需要在Google Cloud控制台启用Picker API并创建密钥
            .setCallback(pickerCallback)
            .build();
          picker.setVisible(true);
        });
      }

      function pickerCallback(data) {
        if (data[google.picker.Response.ACTION] === google.picker.Action.PICKED) {
          const folderId = data[google.picker.Response.DOCUMENTS][0][google.picker.Document.ID];
          google.script.run.withSuccessHandler(() => {
            alert('文件创建成功!');
            google.script.host.close();
          }).createFileInFolder(folderId);
        }
      }
    </script>
  </head>
  <body onload="initPicker()">
    <p>请选择要创建文件的文件夹...</p>
  </body>
</html>

步骤2:后端创建文件(使用高级Drive服务)

  1. 在Apps Script编辑器中启用高级Drive服务:点击「资源」→「高级Google服务」,找到Drive API并开启。
  2. 在.gs文件中编写创建文件的函数:
function showPicker() {
  const html = HtmlService.createHtmlOutputFromFile('Picker')
    .setWidth(600)
    .setHeight(400);
  SpreadsheetApp.getUi().showModalDialog(html, '选择文件夹');
}

function createFileInFolder(folderId) {
  // 使用高级Drive服务创建文件,关联用户选择的文件夹
  const fileMetadata = {
    name: 'dummy.txt',
    parents: [folderId]
  };
  const media = Utilities.newBlob('beep boop', 'text/plain');
  Drive.Files.insert(fileMetadata, media);
}

权限配置

确保appsscript.json中的权限包含:

{
  "oauthScopes": [
    "https://www.googleapis.com/auth/drive.file",
    "https://www.googleapis.com/auth/script.container.ui"
  ]
}

解决方案二:直接调用Drive API(UrlFetchApp)

如果不想用高级服务,也可以用UrlFetchApp直接调用Drive API,注意需要添加script.external_request权限(该权限不在OAuth同意屏幕的可选列表中,需手动在appsscript.json中声明)。

示例代码:

function createFileViaApi(folderId) {
  const url = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart';
  const fileMetadata = JSON.stringify({
    name: 'dummy.txt',
    parents: [folderId]
  });
  const boundary = '-------314159265358979323846';
  const delimiter = `\r\n--${boundary}\r\n`;
  const closeDelimiter = `\r\n--${boundary}--`;

  const body = delimiter +
    'Content-Type: application/json\r\n\r\n' +
    fileMetadata +
    delimiter +
    'Content-Type: text/plain\r\n\r\n' +
    'beep boop' +
    closeDelimiter;

  const options = {
    method: 'post',
    headers: {
      'Authorization': `Bearer ${ScriptApp.getOAuthToken()}`,
      'Content-Type': `multipart/related; boundary=${boundary}`
    },
    payload: body
  };

  UrlFetchApp.fetch(url, options);
}

对应的appsscript.json权限:

{
  "oauthScopes": [
    "https://www.googleapis.com/auth/drive.file",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/script.container.ui"
  ]
}

关键注意事项

  • drive.file权限下,所有文件操作必须关联用户主动授权的资源(通过Picker或文件打开操作获得),不能直接创建无关联的根目录文件。
  • script.external_request权限无需在OAuth同意屏幕手动添加,只需在appsscript.json的oauthScopes中声明即可。
  • 必须在Google Cloud控制台启用Google Picker API和Drive API,否则Picker和API调用会失败。

内容的提问来源于stack exchange,提问作者joon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 05:13:16