Google apps script 如何确定是什么导致脚本运行?
每当我尝试显示UI对话框(例如或)时,通过菜单项(例如,从Google Sheets)调用时,它工作正常,但如果我尝试从Google Apps脚本编辑器(例如,通过Run>Run函数)调用脚本,它会挂起我的脚本 我猜这是因为谷歌应用程序脚本编辑器无法显示任何用户界面。为了解决这个问题,我想创建一个包装函数来检查脚本是如何运行的,而不是根据源代码显示UI “执行”屏幕具有类型(编辑器、独立、触发器)的概念: 这让我觉得有一种方法可以让这种类型的代码以某种方式出现 函数外观的Psuedo代码:Google apps script 如何确定是什么导致脚本运行?,google-apps-script,Google Apps Script,每当我尝试显示UI对话框(例如或)时,通过菜单项(例如,从Google Sheets)调用时,它工作正常,但如果我尝试从Google Apps脚本编辑器(例如,通过Run>Run函数)调用脚本,它会挂起我的脚本 我猜这是因为谷歌应用程序脚本编辑器无法显示任何用户界面。为了解决这个问题,我想创建一个包装函数来检查脚本是如何运行的,而不是根据源代码显示UI “执行”屏幕具有类型(编辑器、独立、触发器)的概念: 这让我觉得有一种方法可以让这种类型的代码以某种方式出现 函数外观的Psuedo代码:
function showMessage(message) {
var scriptSource = ???;
if (scriptSource === "Standalone") {
Browser.msgBox(message);
} else {
console.log(message);
}
}
如何获取脚本源代码
我能找到的最接近的东西是,但它缺少枚举值“Editor”和“Trigger”。此外,它是一个只在网络上可用的属性。我不知道如何访问当前触发器。据我所知,这只能通过(例如,通过triggerUid
)对充当触发器的函数提供。我在应用程序脚本编辑器中运行的此方法无权访问事件对象。- 您想知道当前项目是容器绑定脚本类型还是独立脚本类型
- 您想使用
Browser.msgBox()
- 返回父ID时,会发现项目是绑定到容器的脚本类型
- 未返回父ID时,会发现项目是独立脚本类型
Browser.msgBox()
不能使用。因此,if语句用于此var id = ScriptApp.getScriptId(); // Retrieve scriptId of current project.
var url = "https://script.googleapis.com/v1/projects/" + id + "?fields=parentId";
var res = UrlFetchApp.fetch(url, {headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}});
res = JSON.parse(res.getContentText());
if ("parentId" in res) {
Logger.log("Container-bound script type.")
var mimeType = DriveApp.getFileById(res.parentId).getMimeType();
if (mimeType === MimeType.GOOGLE_FORMS) {
Logger.log("Browser.msgBox() cannot be used at Google Form.");
} else {
Browser.msgBox("Hello world");
}
} else {
Logger.log("Standalone script type.")
Logger.log("Hello world");
}
注:
- 使用此脚本时,请执行以下流程。
- 在API控制台启用应用程序脚本API
- 至少,将以下作用域添加到清单中。
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/script.external_request
https://www.googleapis.com/auth/script.projects.readonly
- 如果在脚本中需要添加其他作用域,请添加它们。如果您想在脚本编辑器中使用scopes的自动安装程序,可以使用一个库来实现。您可以在中查看详细信息
- 您需要确认是从脚本编辑器还是从自定义菜单调用该函数
https://www.googleapis.com/auth/script.processes
添加到清单中
该脚本的使用方法如下所示
addCustomMenu()
sampleFunction
。
- 这样,日志中将显示来自自定义菜单的调用
sampleFunction
。
- 这样,来自脚本编辑器的调用将显示在日志中
- 不是最好的解决方案,但我目前的解决方法是创建每个函数的3个版本,并将调用方式附加到名称中
例如,如果有一个“Hello World”函数:
function onOpen() {
var menu = [
{name: 'Hello World', functionName: 'helloWorldViaMenu_'},
];
SpreadsheetApp.getActive().addMenu('Custom', menu);
}
function helloWorldViaMenu_() {
helloWorld_(false);
}
function helloWorldViaEditor() {
helloWorld_(true);
}
function helloWorld_(invokedFromEditor) {
if (invokedFromEditor) {
Logger.log("Hello world");
} else {
Browser.msgBox("Hello world");
}
}
helloWorldViaEditor
是唯一在末尾没有\ucode>的编辑器,因此可以通过“选择功能”编辑器UI下拉菜单选择它。制作对话框
您可以从菜单或脚本编辑器运行它们。它们的工作原理相同
function makeAmenu(){
SpreadsheetApp.getUi().createMenu('A Menu')
.addItem('Run my Dialogs', 'showMyDialogs')
.addToUi();
}
function showMyDialogs(){
var ui=SpreadsheetApp.getUi();
ui.alert('This is an alert');
ui.prompt('This is a prompt');
var html=HtmlService.createHtmlOutput('<p>This is a modeless dialog</p><input type="button" value="Close" onClick="google.script.host.close();" />');
ui.showModelessDialog(html, 'Dialog');
}
函数makeAmenu(){
SpreadsheetApp.getUi().createMenu('菜单')
.addItem('运行我的对话框','显示我的对话框')
.addToUi();
}
函数showMyDialogs(){
var ui=SpreadsheetApp.getUi();
ui.alert(“这是一个警报”);
ui.prompt(“这是一个提示符”);
var html=HtmlService.createHtmlOutput(“这是一个无模式对话框””;
showModelessDialog(html,“Dialog”);
}
如果从此处运行脚本:
您必须到这里才能看到它:
如果我误解了你的情况,我很抱歉。例如,当您想知道UI是否可以用于项目中的函数时,了解项目是容器绑定脚本类型还是独立脚本类型如何?另外,尽管googleform的绑定脚本具有getUi()
的方法,但不能使用Browser.msgBox()
。我认为有几种方法可以确认它们。@Tanaike:如何确定“项目是容器绑定脚本类型还是独立脚本类型”?我想这会解决我的问题。@Tanaike:还有关于“getUi()
,Browser.msgBox()function makeAmenu(){
SpreadsheetApp.getUi().createMenu('A Menu')
.addItem('Run my Dialogs', 'showMyDialogs')
.addToUi();
}
function showMyDialogs(){
var ui=SpreadsheetApp.getUi();
ui.alert('This is an alert');
ui.prompt('This is a prompt');
var html=HtmlService.createHtmlOutput('<p>This is a modeless dialog</p><input type="button" value="Close" onClick="google.script.host.close();" />');
ui.showModelessDialog(html, 'Dialog');
}