I am using the following function to connect to an external API (Binance) using a Google Apps Script to retrieve a JSON array (of market prices). This simple query url works fine in a browser (no need for API keys):
function getMyArray() {
var url ="https://api.binance.com/api/v3/ticker/price"; // works perfectly in browser
var params = {"method" : "get", "muteHttpExceptions":true };
var response = UrlFetchApp.fetch(url, params);
var array = JSON.parse(response.getContentText());
return array;
}
However it's a different story when I try to run the function in Google Apps Script:
403 error
"Request blocked"403 error
=getMyArray()
=> request works and I can trace the array using LoggerWhy is my simple request getting blocked when called from Menu or Script Editor, and is it possile to change that? Thanks
When UrlFetchApp
is used by the custom function and the script editor, I think that the difference is whether IPv6 is used, while the address of IPv4 is changed every run. In this case, the results of the script editor and custom menu are the same. I thought that this might be the reason of your issue. But I'm not sure whether my guess is the correct. So, in this answer, I would like to propose the following workaround.
=getMyArray()
to a cell using the script.
By this flow, I think that your goal can be achieved.
The sample script is as follows.
In this script, as a test, =getMyArray()
is put to the cell "A1" on the active sheet and the value is retrieved from the cell. When you use this, please run the function main()
at the script editor and custom menu. By this, the value can be retrieved to array
.
function getMyArray() {
var url = "https://api.binance.com/api/v3/ticker/price";
var params = {"method": "get", "muteHttpExceptions": true};
var response = UrlFetchApp.fetch(url, params);
return response.getContentText();
}
// Please run this function by the script editor and the custom menu.
function main() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("A1");
range.setFormula("=getMyArray()");
SpreadsheetApp.flush();
var value = range.getValue();
range.clearContent();
var array = JSON.parse(value);
console.log(array)
}
The response value from https://httpbin.org/get
is as follows.
function sample() {
var url = "https://httpbin.org/get";
var res = UrlFetchApp.fetch(url);
console.log(res.getContentText())
return res.getContentText();
}
{
"args": {},
"headers": {
"Accept-Encoding": "gzip,deflate,br",
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0 (compatible; Google-Apps-Script; beanserver; +https://script.google.com; id: ###)",
"X-Amzn-Trace-Id": "Root=###"
},
"origin": "### IPV6 ###, ### IPV4 ###", // or "### IPV4 ###, ### IPV4 ###"
"url": "https://httpbin.org/get"
}
origin
is "### IPV6 ###, ### IPV4 ###"
. But when you are using IPV4, origin
is "### IPV4 ###, ### IPV4 ###"
.https://api.binance.com/api/v3/ticker/price
.In this case, =sample()
is put to a cell and the value is retrieved.
{
"args": {},
"headers": {
"Accept-Encoding": "gzip,deflate,br",
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0 (compatible; Google-Apps-Script; beanserver; +https://script.google.com; id: ###)",
"X-Amzn-Trace-Id": "Root=###"
},
"origin": "### IPV4 ###",
"url": "https://httpbin.org/get"
}
https://api.binance.com/api/v3/ticker/price
.When UrlFetchApp
is used with the custom function, no authorization is required. But when UrlFetchApp
is used with the OnEdit event trigger, the installable trigger is required by authorizing. I thought that this authorization might occur this issue. So I compared this.
When UrlFetchApp
is used with the installable OnEdit event trigger, the following result is retrieved.
{
"args": {},
"headers": {
"Accept-Encoding": "gzip,deflate,br",
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0 (compatible; Google-Apps-Script; beanserver; +https://script.google.com; id: ###)",
"X-Amzn-Trace-Id": "Root=###"
},
"origin": "### IPV4 ###",
"url": "https://httpbin.org/get"
}
https://api.binance.com/api/v3/ticker/price
.User-Agent
are the same for all patterns.origin
is "### IPV4 ###, ### IPV4 ###"
, 2nd IPV4 is the Google's IP address.From above results, the different of all patterns is whether the value of origin
is 1 or 2.