另一个 Google Apps 脚本 UrlFetchApp 返回未授权错误 401
Another Google Apps Script UrlFetchApp returning Unauthorized Error 401
所以,我正在使用一个 Google Spreadsheet 来保存受保护的范围,因此,为了完成排序行,从 sheet 调用一个未绑定的网络应用程序:
Google Sheet XYZ -> Unbound Web App (sort code) -> Google Sheet XYZ
Unbound Web App 运行 在我的帐户下,并与使用 Sheet XYZ 的用户共享。
完美运行。
现在,我正尝试使用 OnSubmit
:
从 Google 表单调用相同的 Web 应用程序
Google Form ABC -> Unbound Web App (sort code) -> Google Sheet XYZ
然而 en 异常 si 从网络应用程序返回:
{ [Exception: Request failed for https://script.google.com returned code 401. Truncated server response: <HTML>
<HEAD>
<TITLE>Unauthorized</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Unauthorized</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
(use muteHttpExceptions option to examine full response)] name: 'Exception' }
虽然我是表单、Web 应用程序和 sheet 所有者,但说这种情况发生很奇怪....还尝试将其他范围添加到表单脚本。
这是表单 OnSubmit
:
中的代码 运行ning
function callWebApp(){
var queryString = "?action=sort&sheetID="+contactListSSID+"&sortType=byName&sheetName="+S_PARENTS_SHEET_NAME+"&firstDataRow="+S_PARENTS_FIRST_DATA_ROW+"&colUserName="+S_PARENTS_NAME_SURNAME_COLUMN+"&classColSection="+null+"&colDOB="+null; // null because unused for this sort type
var baseUrl ="https://script.google.com/a/macros/ourdomain.com/s/xxxxxxx/exec"
var url = encodeURI(baseUrl + queryString).replace("#","%23");
var params = {method: "get", headers: {'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()}};
try {
var request = UrlFetchApp.fetch(url,params)
Logger.log(request);
} catch (error) {
console.error(error);
return error;
}
return request;
}
未绑定的 Web App 代码(不包括代码中列出的所有操作):
function doGet(e) {
var param = e.queryString;
var parameters = param.split("&")
var validActions = ["sort", "duplicate", "delete"];
if (param == null){
return "Missing parameters";
}
param = e.parameter;
const matches = parameters.filter(s => s.includes('action'));
if (matches.length < 1 || validActions.indexOf(param.action) < 0){
return "Missing or bad action";
}
var ret;
switch(param.action){
case "sort":
ret = sortSheet(e);
break;
case "duplicate":
ret = duplicateSheet(e);
break;
case "delete":
ret = deleteSheet(e);
break;
}
return ContentService.createTextOutput(ret);
}
function sortSheet (e){
param = e.parameter;
var sheetId = param.sheetID;
var name = param.sheetName;
var sortType = param.sortType;
var COL_STUDENT_NAME = Number(param.colUserName);
var S_CLASS_COL_SECTION = Number(param.classColSection);
var COL_DOB = Number(param.colDOB);
var FIRST_DATA_ROW = Number(param.firstDataRow);
try{
var ss = SpreadsheetApp.openById(sheetId)
var sheet = ss.getSheetByName(name)
var dataRange = sheet.getRange(FIRST_DATA_ROW,1,(sheet.getLastRow() - FIRST_DATA_ROW + 1),sheet.getMaxColumns());
var a1 = dataRange.getA1Notation();
switch (sortType){
case "byName":
dataRange.sort({column: COL_STUDENT_NAME, ascending: true});
break;
case "bySection":
dataRange.sort([{column: S_CLASS_COL_SECTION, ascending: true}, {column: COL_STUDENT_NAME, ascending: true}]);
break;
case "byDOB":
dataRange.sort([{column: COL_DOB, ascending: true}, {column: COL_STUDENT_NAME, ascending: true}]);
break;
}
}
catch (err){
return err;
}
return a1;
}
当上面的代码是 运行 来自 spreadsheet 时,它起作用了。同样的代码一旦在表单中运行,就会抛出异常
Google 表单在 Google Sheet 中不起作用,如果您使用 App 脚本处理 Google Sheet。因此,您无法调用身份验证表单,无法通过身份验证步骤
问题:
需要 drive
作用域才能访问 non-public Apps 脚本网络应用程序。
解决方案:
添加这两个范围中的任何一个都可以:
您可以添加它们 explicitly in the manifest,使用字段 oauthScopes
:
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/forms",
"https://www.googleapis.com/auth/drive.readonly"
]
或者,更简单的方法是,您可以在需要此范围的方法中添加注释行,例如:
//DriveApp.getFileById()
脚本会注意到这一点,因此 ScriptApp.getOAuthToken()
将获得此范围的授权。
相关:
所以,我正在使用一个 Google Spreadsheet 来保存受保护的范围,因此,为了完成排序行,从 sheet 调用一个未绑定的网络应用程序:
Google Sheet XYZ -> Unbound Web App (sort code) -> Google Sheet XYZ
Unbound Web App 运行 在我的帐户下,并与使用 Sheet XYZ 的用户共享。 完美运行。
现在,我正尝试使用 OnSubmit
:
Google Form ABC -> Unbound Web App (sort code) -> Google Sheet XYZ
然而 en 异常 si 从网络应用程序返回:
{ [Exception: Request failed for https://script.google.com returned code 401. Truncated server response: <HTML>
<HEAD>
<TITLE>Unauthorized</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Unauthorized</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
(use muteHttpExceptions option to examine full response)] name: 'Exception' }
虽然我是表单、Web 应用程序和 sheet 所有者,但说这种情况发生很奇怪....还尝试将其他范围添加到表单脚本。
这是表单 OnSubmit
:
function callWebApp(){
var queryString = "?action=sort&sheetID="+contactListSSID+"&sortType=byName&sheetName="+S_PARENTS_SHEET_NAME+"&firstDataRow="+S_PARENTS_FIRST_DATA_ROW+"&colUserName="+S_PARENTS_NAME_SURNAME_COLUMN+"&classColSection="+null+"&colDOB="+null; // null because unused for this sort type
var baseUrl ="https://script.google.com/a/macros/ourdomain.com/s/xxxxxxx/exec"
var url = encodeURI(baseUrl + queryString).replace("#","%23");
var params = {method: "get", headers: {'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()}};
try {
var request = UrlFetchApp.fetch(url,params)
Logger.log(request);
} catch (error) {
console.error(error);
return error;
}
return request;
}
未绑定的 Web App 代码(不包括代码中列出的所有操作):
function doGet(e) {
var param = e.queryString;
var parameters = param.split("&")
var validActions = ["sort", "duplicate", "delete"];
if (param == null){
return "Missing parameters";
}
param = e.parameter;
const matches = parameters.filter(s => s.includes('action'));
if (matches.length < 1 || validActions.indexOf(param.action) < 0){
return "Missing or bad action";
}
var ret;
switch(param.action){
case "sort":
ret = sortSheet(e);
break;
case "duplicate":
ret = duplicateSheet(e);
break;
case "delete":
ret = deleteSheet(e);
break;
}
return ContentService.createTextOutput(ret);
}
function sortSheet (e){
param = e.parameter;
var sheetId = param.sheetID;
var name = param.sheetName;
var sortType = param.sortType;
var COL_STUDENT_NAME = Number(param.colUserName);
var S_CLASS_COL_SECTION = Number(param.classColSection);
var COL_DOB = Number(param.colDOB);
var FIRST_DATA_ROW = Number(param.firstDataRow);
try{
var ss = SpreadsheetApp.openById(sheetId)
var sheet = ss.getSheetByName(name)
var dataRange = sheet.getRange(FIRST_DATA_ROW,1,(sheet.getLastRow() - FIRST_DATA_ROW + 1),sheet.getMaxColumns());
var a1 = dataRange.getA1Notation();
switch (sortType){
case "byName":
dataRange.sort({column: COL_STUDENT_NAME, ascending: true});
break;
case "bySection":
dataRange.sort([{column: S_CLASS_COL_SECTION, ascending: true}, {column: COL_STUDENT_NAME, ascending: true}]);
break;
case "byDOB":
dataRange.sort([{column: COL_DOB, ascending: true}, {column: COL_STUDENT_NAME, ascending: true}]);
break;
}
}
catch (err){
return err;
}
return a1;
}
当上面的代码是 运行 来自 spreadsheet 时,它起作用了。同样的代码一旦在表单中运行,就会抛出异常
Google 表单在 Google Sheet 中不起作用,如果您使用 App 脚本处理 Google Sheet。因此,您无法调用身份验证表单,无法通过身份验证步骤
问题:
需要 drive
作用域才能访问 non-public Apps 脚本网络应用程序。
解决方案:
添加这两个范围中的任何一个都可以:
您可以添加它们 explicitly in the manifest,使用字段 oauthScopes
:
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/forms",
"https://www.googleapis.com/auth/drive.readonly"
]
或者,更简单的方法是,您可以在需要此范围的方法中添加注释行,例如:
//DriveApp.getFileById()
脚本会注意到这一点,因此 ScriptApp.getOAuthToken()
将获得此范围的授权。