限制Google App Script的OAuth范围

3
我正在尝试限制我的OAuth范围,以便在表单提交后发送电子邮件的脚本中使用最少的权限。我想要限制它只拥有必要的权限。如果我点击运行,它会尝试授权正确的权限。如果我设置表单提交触发器,它将要求授权所有电子表格的读取、更改、删除和所有表单的更改。
如果我给予脚本完全访问电子表格和表单的权限,它就能按预期运行。我只是想减少一些权限。截图显示它正在请求比appsscript.json文件中指定的权限更多的权限。
此脚本附加到从我的表单生成的响应电子表格上。
来自我的appsscript.json:
"oauthScopes": [
    "https://www.googleapis.com/auth/gmail.readonly",
    "https://www.googleapis.com/auth/gmail.send",
    "https://www.googleapis.com/auth/drive.file",
    "https://www.googleapis.com/auth/forms.currentonly",
    "https://www.googleapis.com/auth/spreadsheets.currentonly"
  ]

代码:

/**
 * @OnlyCurrentDoc
 */

function onFormSubmit(e) {
  var values = e.namedValues;

  var htmlBody = 'Hey ' + values['Name of Recipient'] + "!<br>";
  htmlBody += values['Name of Sender'] + " thinks you deserve a shoutout! Thank you for being so awesome!";
  htmlBody += '<br> <em>' + values['Shoutout'] + " - " + values['Name of Sender'] + "</em>";
  htmlBody += '<br><br>';

  GmailApp.sendEmail(values['Recipient Email'],'SHOUT OUT!!!!!!','',
  {from:'email@domain.com',
  htmlBody:htmlBody});
}

Google表格/表单问题/列

  • 时间戳

  • 发件人姓名

  • 收件人姓名

  • 收件人上司姓名

  • 喊话

  • 收件人电子邮件

  • 收件人上司电子邮件

OAuth权限截图:

OAuth Permissions Screenshot

项目详细信息OAuth范围:


那么你有什么问题? - Kos
1
我不想让脚本“查看、编辑、创建和删除所有你的Google Sheets电子表格”或者“在Google Drive中查看和管理你的表单”。我只希望这个脚本能够访问特定的表格及其响应。 - RayFranosa
截图的URL。您能否将其粘贴在此处,同时删除敏感信息,如客户端ID和客户端密钥? - TheMaster
@RayFranosa 这些信息仍然可以在编辑历史记录中看到。如果您想要完全擦除,请“标记”您的问题和包含敏感信息的答案,请求“管理员干预”,并进行解释。相关链接:https://meta.stackoverflow.com/questions/327142/ - TheMaster
2个回答

2
默认情况下,如果您添加了一个事件源为“来自电子表格”的“可安装触发器”,则查看、编辑、创建和删除所有您的Google Sheets电子表格是一个必需的范围,并且如果事件类型为“提交表单”,则还会添加在Google Drive中查看和管理您的表单。这是为了让脚本访问由提交响应引起的电子表格可能发生的更改。因此,它将返回一个包含有关触发器触发的上下文信息的事件对象给用户。
如果您手动按下“运行”按钮,则脚本也可以工作,但是不会向函数参数传递任何事件对象。
您可以尝试使用“定时驱动”作为事件源,它将显示与您在appsscript.json中声明的相同范围,因为触发器不需要访问电子表格来执行触发器。
例如:
时间驱动:

enter image description here

从电子表格和“打开时”:

enter image description here

从电子表格和表单提交:

enter image description here

参考资料:


这就是它。我没有注意到那些触发器所需权限的差异。谢谢。 - RayFranosa

0

我相信你的目标如下。

  • 从您的问题来看,您想要限制The code:脚本的显示范围如下。

      /**
       * @OnlyCurrentDoc
       */
    
      function onFormSubmit(e) {
        var values = e.namedValues;
    
        var htmlBody = '嘿 ' + values['Name of Recipient'] + "!<br>";
        htmlBody += values['Name of Sender'] + "认为你值得一提!感谢你的卓越表现!";
        htmlBody += '<br> <em>' + values['Shoutout'] + " - " + values['Name of Sender'] + "</em>";
        htmlBody += '<br><br>';
    
        GmailApp.sendEmail(values['Recipient Email'],'SHOUT OUT!!!!!!','',
        {from:'email@domain.com',
        htmlBody:htmlBody});
      }
    

似乎在使用 Gmail 服务的 GmailApp.sendEmail 时,范围常量为 https://mail.google.com/。这似乎是当前的规格。因此,如果您想要限制范围,我认为您可以使用 Gmail API 来实现。当使用 Gmail API 转换脚本时,它将变成以下形式。

修改后的脚本:

在使用此脚本之前,请启用高级谷歌服务中的 Gmail API

/**
 * @OnlyCurrentDoc
 */

// This is from https://stackoverflow.com/a/66088350
function convert_(toEmail, fromEmail, subject, textBody, htmlBody) {
  const boundary = "boundaryboundary";
  const mailData = [
    `MIME-Version: 1.0`,
    `To: ${toEmail}`,
    `From: ${fromEmail}`,
    `Subject: =?UTF-8?B?${Utilities.base64Encode(subject, Utilities.Charset.UTF_8)}?=`,
    `Content-Type: multipart/alternative; boundary=${boundary}`,
    ``,
    `--${boundary}`,
    `Content-Type: text/plain; charset=UTF-8`,
    ``,
    textBody,
    ``,
    `--${boundary}`,
    `Content-Type: text/html; charset=UTF-8`,
    `Content-Transfer-Encoding: base64`,
    ``,
    Utilities.base64Encode(htmlBody, Utilities.Charset.UTF_8),
    ``,
    `--${boundary}--`,
  ].join("\r\n");
  return Utilities.base64EncodeWebSafe(mailData);
}

function onFormSubmit(e) {
  var htmlBody = 'Hey ' + values['Name of Recipient'] + "!<br>";
  htmlBody += values['Name of Sender'] + " thinks you deserve a shoutout! Thank you for being so awesome!";
  htmlBody += '<br> <em>' + values['Shoutout'] + " - " + values['Name of Sender'] + "</em>";
  htmlBody += '<br><br>';

  var raw = convert_(values['Recipient Email'], 'email@domain.com', 'SHOUT OUT!!!!!!', "", htmlBody);
  Gmail.Users.Messages.send({raw: raw}, "me");
}
  • 在此脚本中,只能使用https://www.googleapis.com/auth/gmail.send的范围。

  • 在此示例脚本中,它假定e是你想要使用的正确值。请注意这一点。

注意:

  • 关于其他范围"https://www.googleapis.com/auth/gmail.readonly", "https://www.googleapis.com/auth/drive.file", "https://www.googleapis.com/auth/forms.currentonly", "https://www.googleapis.com/auth/spreadsheets.currentonly",当我看到您的脚本时,不需要使用这些范围。但是,在使用Google表单时,可能需要使用https://www.googleapis.com/auth/forms.currentonly。请注意这一点。

  • 例如,当您想要使用其他方法时,请为它们添加范围。我的答案是针对您在问题中显示的脚本。请注意这一点。

参考资料:


@RayFranosa 现在我明白了你的编辑意图。很抱歉我之前没有注意到。 - Tanaike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接