【问题标题】:Google Sheets, "The request is missing a valid API key"Google 表格,“请求缺少有效的 API 密钥”
【发布时间】:2019-03-11 11:32:22
【问题描述】:

我正在尝试使用Google Sheets API。问题是,一旦我在谷歌电子表格上调用我的脚本函数,我就会收到以下错误:

对 sheet.spreadsheets.values.get 的 API 调用失败并出现错误:请求缺少有效的 API 密钥。 (第 5 行)。

脚本中的line 5 如下所示:

var values = Sheets.Spreadsheets.Values.get(spreadsheetId, rangeName).values;

spreadsheetIdrangeName 在第一行中定义。

我认为问题可能是我没有在任何地方复制 API 密钥,但我真的不明白我可以在哪里以及如何做到这一点。

我只使用= function()调用该函数。

【问题讨论】:

  • 是的,我已经看到了。在第二个链接中,他们说:“获得 API 密钥后,您的应用程序可以将查询参数 key=yourAPIKey 附加到所有请求 URL。”要么我不明白这一步,要么我做错了。究竟是什么意思?
  • 您是否为此脚本启用了 Google Sheets API 高级服务?
  • 是的,是的,我做到了
  • 您是否在此 Apps 脚本的 Google Cloud 项目中启用了上述 API?您究竟是如何通过电子表格调用脚本的?菜单选项?自定义函数?

标签: google-apps-script google-sheets authorization google-sheets-api


【解决方案1】:

当您通过将 =myFunction() 等自定义函数放入单元格时使用 Sheets API 时,会发生此类错误。当自定义函数运行时,ScriptApp.getOAuthToken() 返回null。我认为这是您问题的主要原因。不幸的是,我认为这是规范。为了避免这个问题,我想提出 2 个解决方法。

解决方法 1:

电子表格服务的一部分可用于自定义功能。所以使用它,它与var values = Sheets.Spreadsheets.Values.get(spreadsheetId, rangeName).values; 获得相同的结果。对于您的脚本,不能使用openById()。所以脚本如下。

示例脚本:

function customFunc() {
  var rangeName = "#####"; // Please set this.

  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var values = sheet.getRange(rangeName).getValues();
  return values;
}

解决方法 2:

如果您想使用 Sheets API,则需要访问令牌。但是需要直接向Sheets API的端点请求,因为访问令牌在Advanced Google Services内部会自动使用。作为这种情况的一个问题,在自定义函数中运行ScriptApp.getOAuthToken() 时,会返回null。为了避免这种情况,作为一种方法,使用 PropertiesService 将访问令牌直接赋予自定义函数。示例流程如下。

  1. 当电子表格打开时,它会通过 OnOpen 触发器将访问令牌放入 PropertiesService。
    • 使用时,请将 OnOpen 触发器安装到示例脚本中的onOpenFunc()
  2. 运行自定义函数时,PropertiesService 检索到的访问令牌用于使用 Sheets API。

这样,Sheets API 就可以在自定义函数中使用了。

示例脚本:

// Please install OnOpen trigger to this function.
function onOpenFunc() {
  PropertiesService.getScriptProperties().setProperty("accessToken", ScriptApp.getOAuthToken());
}

function customFunc() {
  var spreadsheetId = "#####"; // Please set this.
  var rangeName = "#####"; // Please set this.

  var accessToken = PropertiesService.getScriptProperties().getProperty("accessToken");
  var url = "https://sheets.googleapis.com/v4/spreadsheets/" + spreadsheetId + "/values/" + rangeName;
  var res = UrlFetchApp.fetch(url, {headers: {"Authorization": "Bearer " + accessToken}});
  var obj = JSON.parse(res.getContentText());
  var values = obj.values;
  return values;
}
  • 访问令牌的过期时间为 1 小时。在此示例脚本中,使用了 PropertiesService。在这种情况下,当电子表格打开后 1 小时后,无法使用访问令牌。如果您想持续使用访问令牌,您还可以使用时间驱动触发器对其进行更新。

注意:

  • 使用 Sheets API 时,请在 API 控制台启用 Sheets API。

参考资料:

如果这些解决方法不是您想要的,我深表歉意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 2018-07-05
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    相关资源
    最近更新 更多