从Sheets事件触发的UrlFetchApp.fetch因缺少权限而失败,但直接运行时有效

时间:2019-07-01 15:23:11

标签: google-apps-script urlfetch

我在运行于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项目权限的用户(这就是使用服务帐户的原因)。

0 个答案:

没有答案