我在运行于UrlFetchApp.fetch的Google表格中托管了一个Google Apps脚本,用于执行多项操作(通过GCP服务帐户进行身份验证,调用GCP api等)。
问题是,如果我运行它或直接从脚本编辑器运行它(菜单运行->运行功能/调试功能),它可以正常工作,但是当我将其附加到事件处理程序(如“ onEdit”)时,它将失败,在“应用脚本仪表板”中,我可以看到此错误
您无权调用UrlFetchApp.fetch。需要 权限:https://www.googleapis.com/auth/script.external_request 在getBearerToken(Code:24)处的未知函数处 onEdit(Code:15)上的writeToBigquery(Code:40)
但是,我具有给定的范围https://www.googleapis.com/auth/script.external_request作为清单和脚本属性,以及脚本本身(即使具有硬编码值的onedit在直接启动时也可以很好地运行)。
遵循清单:
{
"timeZone": "Europe/Paris",
"dependencies": {
...
},
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request"
],
"exceptionLogging": "STACKDRIVER"
}
然后提取脚本文件:
function onEdit(e) {
// var range = e.range;
var range = SpreadsheetApp.getActiveSheet().getRange("A1");
// var row = range.rowStart;
var row = 2;
var cols = ['C', 'K', 'L', 'M', 'O', 'P', 'Q', 'R'];
var data = new Object();
for (var ii = 0; ii < cols.length; ii++)
{
data[cols[ii]] = SpreadsheetApp.getActiveSheet().getRange(cols[ii] + row.toString()).getValue();
}
Logger.log('calling writeToBigquery');
writeToBigquery(data);
}
// uses the wonderful library https://github.com/Spencer-Easton/Apps-Script-GSApp-Library to oauth against a GCP service account
function getBearerToken() {
var jsonKey = JSON.parse(PropertiesService.getScriptProperties().getProperty("json_key"));
var key = jsonKey.private_key;
var clientEmail = jsonKey.client_email;
var serverToken = new GSApp.init(key, ['https://www.googleapis.com/auth/bigquery.insertdata'], clientEmail);
// requestToken invokes UrlFetchApp according to https://github.com/Spencer-Easton/Apps-Script-GSApp-Library/blob/master/GSApp.gs, line 120
serverToken.addUser(clientEmail).requestToken();
var token = serverToken.getToken(clientEmail);
Logger.log(token);
return token.token;
}
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
function writeToBigquery(obj)
{
Logger.log('requesting bearer token');
// fails in this line
var token = getBearerToken();
// lots of other irrelevant stuff
// ...
}
如前所述,当直接从脚本编辑器运行时,可以正常运行,但通过在Google表格中通过用户交互触发它来运行时,它只是失败。
编辑Google表格的用户不一定是拥有GCP项目权限的用户(这就是使用服务帐户的原因)。