Reputation: 571
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()
.
Upvotes: 9
Views: 18070
Reputation: 1
I want to thank you, @Tanaike, for your response (I don't have enough 'points' to upvote or comment, so my only option is an 'Answer') I know this thread is several years old, but I thought others might be interested in my personal experience.
First of all: "Workaround 1" worked for me!
The function/method "Sheets.Spreadsheets.Values.get(spreadsheetID, RangeName).values" was giving me an "missing a valid API key" error, so I swapped it for "sheet.getRange(RangeName).getValues()". Most of the above was set as Global Variables, i.e. outside of any functions.
Weird thing was that this error occured only when running from within the [container] sheet, not from the "embedded" script.
For instance: If I had an active onOpen() function, and I opened/refreshed the Sheet, the script would log a "The request is missing a valid API key." error, and the UI/Menu I had built therein would not load. I could, however run the onOpen() function from within the script itself, and the menu would appear, and function, within the Sheet. If I disabled/renamed the onOpen() function, and reloaded the Sheet, I would not get the error message. Makes sense, as the simple loading of the Sheet does not appear to run the script, but when one does access it (the script), i.e. through the onOpen() function, then the initial global variables are read (and the error occurs). However, when I ran the same function, or others, from within the script itself, they would run ok. This permissions conundrum is what has led me on a wild goose chase all over the Internet, ultimately landing here.
All this after numerous other issues, in the course of whose resolution I built a Google Cloud Project, added APIs (e.g. for Sheets), added scopes to the oauthScopes section of the manifest, and more.
It was only after I made the replacements described above that everything worked, both from the script, and its container spreadsheet! So, THANKS!
Anyway... Sorry for the long post, but I hope others may benefit from your solution, and in which context it helped me.
Cheers, -Paul
Upvotes: 0
Reputation: 201583
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.
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.
function customFunc() {
var rangeName = "#####"; // Please set this.
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var values = sheet.getRange(rangeName).getValues();
return values;
}
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.
onOpenFunc()
in the sample script.By this, Sheets API can be used in the custom function.
// 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;
}
If these workarounds were not what you want, I apologize.
Upvotes: 11