Google Sheets, "The request is missing a valid API key"

13,688

When you use Sheets API by a custom function like =myFunction() put to a cell, such error occurs. When the custom function is run, ScriptApp.getOAuthToken() returns null. I think that this is the mainly reason of your issue. And unfortunately, I think that this is the specification. In order to avoid this issue, I would like to propose 2 workarounds.

Workaround 1:

A part of Spreadsheet Services can be used at the custom function. So using this, it obtains the same result with var values = Sheets.Spreadsheets.Values.get(spreadsheetId, rangeName).values;. In the case of your script, openById() cannot be used. So the script is as follows.

Sample script:

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

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

Workaround 2:

If you want to use Sheets API, the access token is required. But it is required to directly request to the endpoint of Sheets API, because the access token is automatically used in internal at Advanced Google Services. As an issue of this case, there is that when ScriptApp.getOAuthToken() is run in the custom function, null is returned. In order to avoid this, as a method, the access token is directly given to the custom function using PropertiesService. The sample flow is as follows.

  1. When the Spreadsheet is opened, it puts the access token to PropertiesService by the OnOpen trigger.
    • When you use this, please install the OnOpen trigger to onOpenFunc() in the sample script.
  2. When the custom function is run, the access token retrieved by PropertiesService is used for using Sheets API.

By this, Sheets API can be used in the custom function.

Sample script:

// 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;
}
  • The expilation time of access token is 1 hour. In this sample script, PropertiesService is used. In this case, when 1 hour is spent after the Spreadsheet was opened, the access token cannot be used. If you want to use continuously the access token, you can also update it using the time-driven trigger.

Note:

  • When you use Sheets API, please enable Sheets API at API console.

References:

If these workarounds were not what you want, I apologize.

Share:
13,688
Giacomo
Author by

Giacomo

Updated on June 26, 2022

Comments

  • Giacomo
    Giacomo about 2 years

    I am trying to use the Google Sheets API. The problem is, once I call my script function on the google spreadsheet, I get the following error:

    API call to sheets.spreadsheets.values.get failed with error: The request is missing a valid API key. (line 5).

    where line 5 in the script looks like this:

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

    and spreadsheetId and rangeName are defined in the first lines.

    I think the problem might be that I did not copy the API key anywhere, but I really do not understand where and how I can do it.

    I call the function just using = function().