几年前,当我将附加组件发布到Chrome网络商店时,我发布了Google Docs的附加组件。我在主脚本的顶部添加了@OnlyCurrentDoc
标记,以缩小权限:该加载项仅需要编辑正在使用的文档,而无需访问Google云端硬盘中的任何其他文档。起初它看起来很棒。现在,附加组件已过渡到GSuite市场,我已经更新并重新发布了该附加组件,但是我开始在Stackdriver Error日志中收到一些通知,提示某些用户“无权执行此操作” 。我将所有需要权限的脚本的调用都保留在[onOpen
“函数的范围内,并检查了"e.AuthMode === ScriptApp.AuthMode.Limited || e.AuthMode === ScriptApp.AuthModeFull
”。没有任何授权(“ e.AuthMode === ScriptApp.AuthModeNone
”),该加载项几乎无法执行任何事情,它只会使用“ DocumentApp.getUi().alert()
”发出警报,以使用户知道他们需要授权该附件才能执行任何操作。
所以我想知道,是什么引起“用户无权执行此操作”错误?脚本是否只需要调用“ DocumentApp.getUi()
”就需要权限?但是我在文档中看到了一些示例,这些示例说在AuthModeNone
的情况下,您仍然可以创建一个基本的侧边栏,不需要用户的任何特定权限,只是这样他们就一无所有。但是在我看来,使用HtmlService
创建任何类型的UI(例如补充工具栏或模态)确实需要权限,因此我避免了这种情况,但仍然看到此错误。
[现在,我什至注意到,当我在Google帐户上安装附加组件时(实际上已对任何Google帐户(不仅是GSuite帐户)启用了附加组件),该附件在文档中都可用它在安装时是打开的,但是如果我创建一个新文档,则会为该加载项提供一个空菜单,并且会收到我创建的UI警报,说该加载项需要权限才能工作。然后,我可以转到“管理加载项:我的加载项显示为已安装”,如果我单击上下文菜单的三个点,则会看到未选中“在本文档中使用”。如果我选中它,则将无法立即使用附加菜单,但是如果刷新页面,则有时将可用,有时则不可用。如果然后我从附加组件菜单中单击“文档附加组件”,则会打开一个带有我的附加组件徽标和一个按钮“使用”的侧边栏,该按钮有时为蓝色(表示已启用),并显示我的附件创建的菜单相同,但有时会变成灰色且无法单击,从而使我无法为该文档启用它。甚至文档刷新也不会总是修复它。我可以看到,对于任何尝试使用该附件的给定用户来说,这都将是多么令人沮丧。
完全删除@OnlyCurrentDoc
标记(以及GSuite Marketplace中的相对权限范围)是否更简单,所以我可以确定该插件在用户需要时可用于用户?在我看来,通过使用缩小范围来保护用户隐私实际上在授权对话框中创建了一个额外的“需要许可”行,这似乎违反直觉,这似乎使用户似乎不得不授予更多权限,而实际上这意味着正在询问权限。然后,实际上使用附加组件变得更加令人沮丧,使用缩小范围的工具真的值得吗?以下是我本人所看到的屏幕快照,我可以想象许多其他用户正在查看(并且如果体验令用户感到沮丧,则他们可能会为附加组件的信誉评分很差,这只是在试图更加保护他们的隐私!)
刷新文档后,这次创建了附加菜单,转到“文档附加”显示该文档已启用该菜单。但是有时这不起作用,并且“使用”按钮显示为灰色!
这里有一些示例代码:
/**
* @OnlyCurrentDoc
*/
function onInstall(e){
// Show instructions for usage automatically on first install
openHelpSidebar(); //This uses the HtmlService to create the sidebar, do we need to check for authorization in order to be able to create and open this sidebar?
// Add plugin menu to the toolbar (according to AuthMode)
onOpen(e);
}
function onOpen(e) {
if(e && (e.authMode == ScriptApp.AuthMode.LIMITED || e.authMode == ScriptApp.AuthMode.FULL)){
// Initialize user preferences ONLY after user has granted permission to the Properties Service!
//set default user properties using propertiesservice if not properties are not set yet
...
//and create our menu items
DocumentApp.getUi().createAddonMenu()
.addItem(__('Start',locale), 'openMainSidebar')
.addSeparator()
.addItem(__('Instructions',locale), 'openHelpSidebar')
.addItem(__('Send Feedback',locale), 'openSendFeedback')
.addItem(__('Contribute',locale), 'openContributionModal')
.addToUi();
}
else{ //if e.AuthMod === ScriptApp.AuthMode.NONE
//can I create any kind of UI if permissions are NONE? Seems to me that trying to create any kind of menu items that open a sidebar or modal with HtmlService will generate error if permissions are NONE
DocumentApp.getUi().alert('You must grant the correct permissions in order to use this add-on. To fix this, remove the add-on and install it again, granting the requested permissions.'); //perhaps try refreshing the page first? and try enabling for the document from the "Document add-ons" menu item in the add-ons menu?
}
}
当然,只有在将该附件实际发布到非GSuite用户可以安装的市场上时,这才是真正可测试的。
我的附加组件简单触发器的经验法则
onInstall
仅应用于调用onOpen
(从G Suite市场安装插件不会创建新文件,而Google阻止了某些操作,例如打开对话框/边栏)]onOpen
仅应用于创建菜单(通过打开文件调用onOpen
时进行其他操作会导致问题)onEdit
不依赖于编辑事件对象的用户属性。基于properties的动态菜单示例。
来自https://developers.google.com/gsuite/add-ons/concepts/editor-auth-lifecycle
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();
}