编辑器插件授权

对许多基于 Apps 脚本的应用进行授权非常简单,因为 当有人尝试访问脚本项目时,脚本项目会请求获取所需的所有权限 使用。

以下各项的授权模式: 编辑器插件是 变得更加复杂:

  • 当用户创建文件时,该用户安装的所有插件 扩展程序菜单中均列有相应列表,即使 如果用户尚未授权这些插件,则会发生该错误。

  • 这些插件适用于可与协作者共享的 Google 云端硬盘文件。如果协作者未安装编辑器插件,则会在文件创建者使用该插件的文档中看到该插件。

  • 编辑器插件会在打开文档时自动运行其 onOpen() 函数。

为保护用户数据,采用的授权模式会使某些服务 onOpen()无法使用。本指南可帮助您了解代码的用途和使用时机。

授权模型

编辑器插件的授权模式取决于其状态,而状态取决于使用它的人:安装插件的用户还是协作者。

编辑器插件状态

Extensions(扩展程序)菜单中的编辑器插件已安装或已启用,或二者兼有。

  • 安装了适用于特定操作系统的 用户或其管理员从 Google Workspace Marketplace,并授权其访问用户的 Google 数据。
  • 插件在文档、表单、 或电子表格。
  • 当用户协同处理文件时,如果其中一位用户使用了插件,系统会为该用户安装该插件,并为相应文件启用该插件。

下表总结了已安装版本与已启用版本之间的不同。 请注意,以插件形式测试脚本时,您可以在上述任一状态或两种状态下运行测试。

已安装 已启用
适用对象 用户 文档、表单、演示文稿或电子表格
原因 从商店获取插件 在使用相应文档、表单、演示文稿或电子表格时从商店获取插件,或
在相应文档、表单、演示文稿或电子表格中使用之前安装的插件
菜单对哪些人可见 在用户打开或创建的所有文档、表单、演示文稿或电子表格中,只有该用户 该文档、表单、演示文稿或电子表格的所有协作者
onOpen() 的授权模式 AuthMode.NONE
) (除非也启用了,在这种情况下, AuthMode.LIMITED)
AuthMode.LIMITED

授权模式

编辑器插件的 onOpen() 函数运行 在用户打开文档、表单、演示文稿或电子表格时触发。 为保护用户的数据,Apps Script 会限制 onOpen() 函数可以执行的操作。编辑器插件状态决定了 onOpen() 函数在哪种授权模式下运行。

如果文件、表单、演示文稿或电子表格中启用了编辑器插件,onOpen() 将在 AuthMode.LIMITED 中运行。如果该插件未启用且处于 仅已安装onOpen()AuthMode.NONE 中运行。

AuthMode.NONE 中,除非用户通过点击或运行自定义函数与插件互动,否则插件无法运行某些服务。如果您的插件尝试在 onOpen()onInstall() 或全局范围内使用这些服务,权限会失败,并且其他调用(例如填充菜单)也会停止。“帮助”是唯一受支持的选项。

如需运行受限服务调用,您必须使用 AuthMode.FULL 授权模式。用户互动功能(例如点击菜单选项)仅在这种模式下运行。在 AuthMode.FULL 模式下运行代码后,该插件可以使用用户授权的所有镜重。

Apps 脚本通过了授权模式 作为 Apps 脚本的 authMode 属性 事件参数e;值 e.authMode 对应于 Apps 脚本中的一个常量 ScriptApp.AuthMode 枚举。

授权模式适用于所有 Apps 脚本执行方法,包括从脚本编辑器、菜单项或 Apps 脚本 google.script.run 调用运行。不过, 只有在脚本作为结果运行时才能检查 e.authMode 属性 (例如 onOpen()onEdit())的触发器onInstall()。Google 表格中的自定义函数使用自己的授权模式 AuthMode.CUSTOM_FUNCTION,该模式与 LIMITED 类似,但存在一些略有不同的限制。对于所有其他情况,脚本都在 AuthMode.FULL 中运行,如下表所述。

NONE LIMITED CUSTOM_FUNCTION FULL
出现于 onOpen()(如果用户已安装插件,但未在文档、表单、演示文稿或电子表格中启用该插件) onOpen()(所有其他时间)
onEdit()(仅限表格)
自定义函数 所有其他时间,包括:
可安装的触发器
onInstall()
google.script.run
访问用户数据 仅限语言区域 仅限语言区域 仅限语言区域
对文档、表单、演示文稿或电子表格的访问权限 是 - 只读
访问界面 添加菜单项 添加菜单项
可使用 Properties
有权访问 JdbcUrlFetch
其他服务 Logger
Utilities
不访问用户数据的任何服务 任何不会访问用户数据的服务 所有服务

编辑器插件的授权生命周期

为当前用户安装了插件时 或是在当前文件中启用的 加载了以下插件:文档、表单、演示文稿 或电子表格该插件会列在扩展程序菜单中,并开始监听简单触发器 onInstall()onOpen()onEdit()。如果用户点击 Extensions 菜单项,该扩展程序就会运行

已安装编辑器插件

从应用店安装编辑器插件后, onInstall() 函数在 AuthMode.FULL 中运行。在此授权模式下,插件可以运行复杂的设置例程。您还应该 使用 onInstall() 创建菜单项,因为文档、表单、演示文稿、 或电子表格已打开,但 onOpen() 函数尚未运行。 以下示例展示了如何从 onInstall() 函数调用 onOpen() 函数:

function onInstall(e) {
  onOpen(e);
  // Perform additional setup as needed.
}

编辑器插件已打开

打开文档、表单、演示文稿或电子表格时,系统会加载当前用户安装的或任何协作者在文件中启用的所有 Google 表格编辑器插件,并调用其每个 onOpen() 函数。onOpen() 运行的授权模式取决于加购项是已安装还是已启用

如果插件仅创建基本菜单,则模式 都没关系。以下示例展示了一个基本的 onOpen() 函数:

function onOpen(e) {
  SpreadsheetApp.getUi().createAddonMenu() // Or DocumentApp.
      .addItem('Insert chart', 'insertChart')
      .addItem('Update charts', 'updateCharts')
      .addToUi();
}

如需根据存储的 Apps Script 属性添加动态菜单项、读取当前文件的内容或执行其他高级任务,您必须识别授权模式并进行适当处理。

以下示例展示了一个高级 onOpen() 函数,该函数会根据授权模式更改其操作:

function onOpen(e) {
  var menu = SpreadsheetApp.getUi().createAddonMenu(); // Or DocumentApp.
  if (e && e.authMode == ScriptApp.AuthMode.NONE) {
    // Add a normal menu item (works in all authorization modes).
    menu.addItem('Start workflow', 'startWorkflow');
  } else {
    // Add a menu item based on properties (doesn't work in AuthMode.NONE).
    var properties = PropertiesService.getDocumentProperties();
    var workflowStarted = properties.getProperty('workflowStarted');
    if (workflowStarted) {
      menu.addItem('Check workflow status', 'checkWorkflow');
    } else {
      menu.addItem('Start workflow', 'startWorkflow');
    }
  }
  menu.addToUi();
}

请注意,在 AuthMode.LIMITED。您可以使用菜单项 以打开边栏和对话框,因为这些AuthMode.FULL 中运行

用户运行编辑器插件

当用户点击扩展程序菜单项时, Apps 脚本首先会检查用户是否安装了 插件,以及 否则就会提示他们执行这些操作如果用户已授权该插件,脚本会运行与 AuthMode.FULL 中的菜单项对应的函数。通过 文档、表单、 或电子表格(如果尚未创建的话)

排查插件菜单无法呈现的问题

如果您的代码无法正确管理授权模式,您的插件菜单可能无法呈现。例如:

  • 某个插件尝试运行当前授权模式不支持的 Apps 脚本服务。

  • 插件会在用户与其互动之前尝试运行服务调用。

如需移除或重新排列导致 AuthMode.NONE 中出现权限错误的服务调用,请尝试执行以下操作:

  1. 打开插件的 Apps 脚本项目,然后找到 onOpen() 函数。
  2. 搜索 onOpen() 函数,看看是否提及 Apps 脚本 与其关联的服务或对象,例如 PropertiesServiceSpreadsheetAppGmailApp
  3. 如果服务用于创建界面元素以外的任何用途,请将其移除或封装在注释块中。仅保留以下方法:.getUi().createMenu().addItem().addToUi()。此外,请查找并移除任何不在函数中的服务。
  4. 找出可能包含注释或移除的代码行的函数 尤其是那些使用所生成信息的用户, 并将服务调用移至需要它们的函数。重新排列或重写 以适应前面步骤中所做的更改。
  5. 保存代码并创建测试部署。

    创建测试部署时,请确保 Config 字段 是为当前用户安装,并且配置框下方的文本显示 AuthMode.None 中测试

  6. 启动测试部署并打开扩展程序菜单。

  7. 如果显示了所有菜单项,则表明问题已经解决。 如果您只看到帮助菜单,请返回第 1 步。 您可能错过了服务通话。