google-apps-script - 复制文件时保持受保护范围
问题描述
我们在 Googlesheets 上有一个文件模板,它有受保护的范围。我们希望复制此文件(文件,制作副本)并为制作此文件的每个人保留受保护的范围,以便他们只能填充某些特定的单元格。问题是,每当有人制作副本时,他/她就会自动成为副本的所有者。这使得无法保护此副本的范围免受此人的侵害(所有者似乎无论如何都可以完全访问电子表格)。有人会解决这个问题吗?
解决方案
- 您想让用户将 Google Drive 上的电子表格复制到用户的 Google Drive。
- 您的电子表格有几个受保护的范围。
- 您的电子表格与用户共享。
- 用户没有与您共享的自己的文件夹。
- 您想为用户保护电子表格的范围。即,您想从受保护范围的编辑器中删除用户。
- 您想使用 Google Apps 脚本实现此目的。
如果我的理解是正确的,这个答案怎么样?
问题:
在上述情况下,我认为以下几点是瓶颈。
- 当您的 Google Drive 中的电子表格被复制到用户的 Google Drive 时,它需要由用户的帐户运行。
- 当电子表格由用户复制到用户的 Google Drive 时,受保护范围的所有者成为用户。因此用户可以编辑受保护的范围。并且用户不能通过用户从编辑器中删除用户。
- 为了使用户不编辑受保护范围,需要更改电子表格的所有者,然后需要将用户从受保护范围的编辑器中删除。
- 在这里,又出现了 2 个问题。
- 为了将电子表格的所有者更改为您,它需要由用户帐户运行。
- 为了从受保护范围的编辑器中删除用户,它需要由您的帐户运行,该帐户不是用户的帐户。
因此,为了使用脚本实现上述目标,脚本需要由用户和您运行。
解决方法:
在我的解决方法中,使用 2 个脚本和 2 个帐户,它实现了上述目标。此解决方法的重点是使用 2 个 Web 应用程序。请将此视为几种解决方法之一。此解决方法的流程如下。
解决方法流程:
在此解决方法中,使用了 Web 应用程序“A”和 Web 应用程序“B”的 2 个 Web 应用程序。
- 用户访问您部署的 Web 应用程序“A”。
- 在这种情况下,Web 应用程序作为用户执行。
- 当 Web 应用程序“A”运行时,
- 您的电子表格从您的 Google Drive 复制到用户的 Google Drive。
- 复制的电子表格的所有者是用户。因此,将所有者从用户更改为您。
- 访问脚本中的 Web 应用程序“B”。
- 在这种情况下,Web 应用程序将作为您执行。
- 当 Web 应用程序“B”运行时,
- 用户将从受保护范围的编辑器中删除。
脚本的使用:
准备:
请创建 2 个独立脚本类型的项目。
- 一个用于 Web 应用程序“A”。
- 另一个用于 Web 应用程序“B”。
Web 应用程序“B”的独立脚本:
首先,请部署 Web 应用程序“B”,因为在 Web 应用程序“A”的脚本中使用了 Web 应用程序“B”的 URL。请复制以下脚本并将 Web 应用程序部署为Execute the app as: **Me**
和Who has access to the app: **Anyone, even anonymous**
. 请复制此 Web 应用程序“B”的 URL 并将其粘贴到url
Web 应用程序“A”的脚本中。
function doGet(e) {
var id = e.parameter.id;
if (id) {
var owner = Session.getActiveUser().getEmail();
var ss = SpreadsheetApp.openById(id);
var protectedRanges = ss.getProtections(SpreadsheetApp.ProtectionType.RANGE);
protectedRanges.forEach(function(p) {
var removes = p.getEditors().filter(function(e) {return e.getEmail() != owner});
p.removeEditors(removes);
});
}
return ContentService.createTextOutput("Done");
}
Web 应用程序“A”的独立脚本:
请复制以下脚本并设置 和 的srcSpreadsheetId
变量url
。在这种情况下,url
是在 Web 应用程序“B”中检索到的 URL。然后,请将 Web 应用程序部署为Execute the app as: **User accessing the web app**
和Who has access to the app: **Anyone**
. 请复制此 Web 应用程序“A”的 URL。此 URL 用于用户访问。
function doGet() {
var srcSpreadsheetId = "###"; // Please set your source Spreadsheet ID.
var url = "###"; // Please set the URL of Web Apps B.
var srcSS = SpreadsheetApp.openById(srcSpreadsheetId);
var dstSS = srcSS.copy(srcSS.getName());
var file = DriveApp.getFileById(dstSS.getId()).setOwner(srcSS.getOwner().getEmail());
var res = UrlFetchApp.fetch(url + "?id=" + file.getId(), {muteHttpExceptions: true}); // Here, run the script of Web Apps "B".
return ContentService.createTextOutput(res.getContentText());
}
跑:
当用户使用上述脚本时,请让用户使用自己的浏览器访问Web Apps“A”的URL。当用户访问网络应用程序“A”时,会显示谷歌的登录屏幕。通过登录到谷歌,授权屏幕显示。通过授权,Web 应用程序“A”的脚本运行,Web 应用程序“B”由 Web 应用程序“A”运行。授权只需要做一次。
当用户浏览器中显示“完成”时,用户可以在根文件夹中看到复制的电子表格。
这样,您的 Google Drive 中的电子表格将被复制到用户的 Google Drive,并且电子表格的所有者被修改为您,然后,用户从受保护范围的编辑器中删除。因此用户无法编辑受保护的范围。
如何部署 Web 应用程序:
- 在脚本编辑器上,通过“发布”->“部署为 Web 应用程序”打开一个对话框。
- 为“将应用程序执行为:”选择“用户访问网络应用程序”或“我”。
- 为“谁有权访问应用程序:”选择“任何人”或“任何人,甚至匿名”。
- 单击“部署”按钮作为新的“项目版本”。
- 自动打开“需要授权”对话框。
- 单击“查看权限”。
- 选择自己的帐户。
- 在“此应用未验证”中单击“高级”。
- 点击“转到###项目名称###(不安全)”
- 单击“允许”按钮。
- 复制“当前网络应用 URL:”。
- 就像
https://script.google.com/macros/s/#####/exec
。
- 就像
- 单击“确定”。
重要的:
- 当您修改 Web Apps 的脚本时,请将 Web Apps 重新部署为新版本。这样,最新的脚本就会反映到 Web 应用程序中。如果即使修改了脚本也没有重新部署 Web 应用程序,则不会使用最新的脚本。请注意这一点。
- 请确认您要制作用户副本的电子表格已与用户共享。
参考:
如果我误解了您的问题并且这不是您想要的方向,我深表歉意。
推荐阅读
- asp.net-mvc - 我想在 foreach 循环中的 div 上添加动态引导 bg 类
- ruby-on-rails - Rails Active Storage:从模型直接上传
- amazon-web-services - 如何通过 Jenkins CD 在 ECS 中的 ECR 中运行 docker 映像?
- javascript - XMLHttpRequest 不发送 POST 数据
- android - 即使在应用程序被杀死后如何继续运行任务?
- powershell - $null 是否应该在相等比较的左侧?(带数组的-eq)
- java - 如何在另一个活动中投射视图?
- elasticsearch - 如何将参数传递给 ElasticSearch 插件
- javascript - 从两个值中设置 Vue JS 选择选项
- r - 在函数的本地上下文中验证对象的存在