I am using Google Apps Script to make a UrlFetchApp call to a node.js API endpoint. I own both the Google Apps Script code and node.js code & endpoint, so I can watch what is happening.
When I use Postman, it works. But when I use GAS UrlFetchApp, it doesn't work, as req.body in node is empty { }. I even looked at the code that Postman creates for JavaScript Fetch and try to nearly duplicate it, except for things I know GAS' UrlFetchApp needs. I've done quite a few UrlFetchApp calls with GAS to various external endpoints. So, I'm not new, but can't figure this one out.
Here is my Google Apps Script code:
var url = 'https://xxxxxxxxxxx.azurewebsites.net/api/account';
var data = {
"email": address,
"apiKey": 'xxxxxxxxxxxxxxxxxxx'
}
var payLoadInfo = JSON.stringify(data);
var options = {
"method": "GET",
"headers": {'Content-Type': 'application/json'},
// 'Content-Type': 'application/json',
// "contentType": 'application/json',
redirect: 'follow',
"muteHttpExceptions": true,
"body": payLoadInfo,
// "payload": JSON.stringify(data)
// payload: payLoadInfo
};
var response = UrlFetchApp.fetch(url, options);
The commented out parts of "options" are several different ways I've tried to get it to work. I know in the past that I've usually used "payload" instead of "body" like I am this time (Postman suggested it). When I use "payload", it fails completely, not even getting to my node code. I also tried putting the apiKey in the header.
Here is the node.js API endpoint code:
router.get("/account", async (req, res) => {
var apiKey = process.env.API_KEY;
console.log('apiKey = ' + apiKey);
console.log('req.body = ' + JSON.stringify(req.body, null, 2));
console.log('req.body.apiKey = ' + req.body.apiKey);
if (req.body.apiKey != apiKey) {
console.log('apiKey is not equal');
res.status(401).send({ error: "You are not authorized." });
} else {
process the request...
}
When I use "payload" in "options" I get a 500, and the server code never executes. When I use "body" in "options", I see the server code execute, but the console.log('req.body = ' + JSON.stringify(req.body, null, 2)), just comes back with an empty object {}, and then since req.body.apiKey != apiKey, it consoles "apiKey is not equal" and sends a 401. When using Postman, the req.body object consoles fine, showing the email & apiKey.
No matter what combinations of things I put into options, it fails either with 500 or 401. However, Postman works great with pretty much the same parameters, headers, etc.
Here is what Postman shows for the code:
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Cookie", "ARRAffinity=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ARRAffinitySameSite=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
var raw = JSON.stringify({"email":"[email protected]","apiKey":"xxxxxxxxxxxxxxxx"});
var requestOptions = {
method: 'GET',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
I even tried including the cookie and "redirect: follow", but none works.
What am I missing?
Here is what Postman shows for the code:
? – TanaikeHere is what Postman shows for the code:
is Javascript, I think that the script cannot be used. I'm worry about this. For example, when your postman sample worked, can you export it as the curl sample? And, I thought thatreq.body
might be used for the POST method. How about this? – Tanaikerouter.get("/account"
, the endpoint might behttps://###/account?email=###&apiKey=###
using the query parameters. And you can retrieve the values of query parameters asconsole.log(req.query)
. How about this? – Tanaikereq.headers
at the server side. – Tanaike