UrlFetchApp Post Req response inconsistent - google-apps-script

When I make a request via apps script, the response is inconsistent than when I make a request with a tool like postman or any other way of sending a post request, it seems specific to apps script.
Here is my request:
var headers = {'Authorization': 'Bearer #'},
var payload = JSON.stringify({'_id':_id, "email": email}),
var options = {
'method': 'post',
'contentType': 'application/x-www-form-urlencoded',
'payload': payload,
'headers': headers,
'muteHttpExceptions':false
}
var response = UrlFetchApp.fetch('https://...", options);
The response code is 201, it appears that the contentText returned in the response is correct except for one key piece of information, the email that was sent in the post payload should be in the response as well. After the post is sent, it triggers an email using the email sent in the payload. This doesn't work with the apps script post request.
When I run this same exact request via postman or another tool, it works perfectly, the email is triggered right after the request is sent and works as intended.
Does anyone have any ideas why the "email" in the payload isn't working via apps script, but does via postman? Do I have an error in payload or way I'm using UrlFetchApp?

Change content type to:
'contentType': 'application/json',
The documentation shows an example with the object stringified, and they change the contentType
Apps Script Documentation UrlFetchApp.fetch(url, parameters)

Related

Exception: Bad request: https://internal-api.company.com... -Google appscript

I have an internal API that I can check by postman status connected to VPN and with a token that changes daily:
but I have not been able to make the same query from Google Apps Script, I get this error:
Exception: Bad request: https://... .
function nomina() {
var url = 'https://internal-api.company.com/app-api/master/api/ssff/users';
var headers= {
'Authorization' : 'Bearer token',
'Accept': 'application/json',
'contentType': 'application/json'
}
var options =
{
'method' : 'GET',
'headers' : headers
}
var response = UrlFetchApp.fetch(url,options);
jsonParse=(JSON.parse(response))
}
Maybe you could suggest me something to be able to do the API query?
I need to know why it doesn't give me an answer, this is another API that I use and this does bring me information.
I see this similar post but have same error still:
Request to external api to get authentication token in google appscript
Google Apps Script run from the Google servers. It can't use your VPN. You should talk with the responsible of the API and request them to make a connection with Google servers. They might have to involve other people (system and / or networks administrators).

How to allow Cors Headers in Google AppScript for making an XMLHttpRequest?

I have created a doGet and doPost endpoints in my appscript. When I hit the endpoint to make a post request from Python, it does work perfectly and as expected.
But when I try to hit the same url with my Flutter based mobile App, it throws me an XML error. (Which I suspect is related to CORSING).
When I hit the url with get request, I get the right response, but post request is failing. To ensure that my Post request is properly configured, I have made a post request to public API and it worked like charm.
Is it possible to add headers, where I could enable cors like this:
allowHeaders = {
"Access-Control-Allow-Origin": "*", // Required for CORS support to work
"Access-Control-Allow-Credentials": true, // Required for cookies, authorization headers with HTTPS
"Access-Control-Allow-Headers": "Origin,Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,locale",
"Access-Control-Allow-Methods": "POST, OPTIONS"
}
Here is what my doPost request returns:
ContentService.createTextOutput(JSON.stringify(
{
data: isAuthenticated.data,
error: true,
//request: request,
msg: query.apiKey,
//paramters:request.parameters
})).setMimeType(ContentService.MimeType.JSON)
Here is my python script to get the post response:
requests.post("https://script.google.com/macros/s/AKfycbz7kTROol8u509M_p9pMZ9XRnL-myVjcRQKeb9Etp_OIMPnH640vHf_0Jp2dvvrbto7kOg/exec",
json = requestObject)
And here is my Flutter function:
Future<http.Response> createAlbum() async{
print("Trying to make a post request");
var result = await http.post(Uri.parse('https://script.google.com/macros/s/AKfycbz7kTROol8u509M_p9pMZ9XRnL-myVjcRQKeb9Etp_OIMPnH640vHf_0Jp2dvRIco7kOg/exec'),
headers: {"Content-Type": "application/json"},
body: jsonEncode(<String, dynamic>{
"apiKey":apiKey,
"operationType":"register_user",
"operationData": {
"email": "shivam#yoptima.com",
"otp": 318728
}
}),
);
print("Here is the result: " + result.body);
}
Just to clarify things:
Get Request works for both the platforms.
Post Request works with python for AppScript.
Post Request works for any other public API from flutter.
Post Request doesn't work for Flutter when Hitting AppScript API.
I suspect it to be something to do with CORS. (But not very sure).
Flutter http library makes request via XMLHttpRequest.

Google scripts, using urlFetchApp() for PUT request, I cannot get a response code when server sends 204 no content response

For GET and POST requests for a private server I work with I use in Google Sheets, do something like this, and I get a proper response. I use that response to update data and just as importantly for error checking by evaluating response.getResponeCode().
function postDataToServer(params){
let myjdService = getService();
let orgId = getOrgIdForSelectedOrg();
let link = https://GoodURLForPrivateDataIWorkWithALot/neededurlParameter/anotherNeededURLParameter;
let options = {
'method': 'put',
'payload': JSON.stringify(params),
'headers': {
'Accept': 'application/vnd.PRIVATE.v3+json',
'Content-Type': 'application/vnd.PRIVATE.v3+json',
'authorization': 'Bearer ' + myPrivateService.getAccessToken()
}
};
let response = UrlFetchApp.fetch(link, options);
return response.getResponseCode();
For all the GET and POST requests I do, I get a response. And from that response I can parse a response code. But for the specific server I work with, when I edit a record using PUT, a successful edit returns this:
204 No Content
And further, the last line return response.getResponseCode() returns an error the response is undefined.
Here's the error I get for doing anything with response:
ReferenceError: response is not defined
The PUT is working. I only know this because 1) when I check if edits are made with the server, they are 2) testing the PUT in Postman at least shows me the words "204 No Content" and 3) the documentation says that's exactly what I should expect.
But I still would like to find out how to evaluate this no-content response in my Google Sheets App for proper error tracking. At least some way to get the string "204". Any ideas? I can't even get Google Sheets to do say 204.

Why am I getting an empty response back from UrlFetchApp in Google Apps Script?

I am trying to make a GET request to an external API from a Google Apps Script using UrlFetchApp. When I make this request with Postman or curl, I get back the expected response. However, when I try it with UrlFetchApp, I get back an empty response, {}.
I have tried using Basic Auth and OAuth 2, as well as explicitly setting the oauthScopes property in the manifest as described here.
I have confirmed with the API team that they are indeed sending back a full response when I hit the endpoint, but all I receive is {}. My problem seems similar to this StackOverflow question which went unanswered.
var headers = {
"X-Client-Key": "KEY",
"Authorization": "Bearer TOKEN"
};
var options = {
method: "get",
headers: headers,
}
var response = UrlFetchApp.fetch(ENDPOINT, options);
console.log(JSON.stringify(response)); // returns {}
Do not take what you see in logs at face value. fetch method of the UrlFetchApp service always returns an instance of HTTPResponse which is an object first and foremost. This is what the logs show you (I am assuming you are logging the response because this is the only context I am aware of where {} is displayed).
To extract useful information from the response, use the appropriate methods exposed on HTTPResponse instances, like getResponseCode or getContentText.

Making a curl request with headers in apps script

I am trying to make a curl request using apps script, the link of the official guide of which is below. Here is the query:
curl -X POST "https://bhagavadgita.io/auth/oauth/token" -H "accept: application/json" -H "content-type: application/x-www-form-urlencoded" -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=client_credentials&scope=verse"
According to the official guide:
How to get an access token?
Make a POST request to /auth/oauth/token with these parameters sent in Headers -
Client ID - Obtained from Account Dashboard after registering an app.
Client Secret - Obtained from Account Dashboard after registering an app.
Grant Type - Use client credentials.
Scope - Use verse if you just want to access the verses, chapter if you just want to access the chapters and verse chapter if you want access to both.
I have written the code as below:
function myFunction() {
var data = {
'accept': 'application/json',
'content-type': 'application/x-www-form-urlencoded',
'header':{
'client_id':'MY-CLIENT-ID',
'client_secret':'MY-CLIENT-SECRET',
'grant_type':'client_credentials',
'scope':'verse'
}
};
var response = UrlFetchApp.fetch('https://bhagavadgita.io/auth/oauth/token', data);
Logger.log(response.getContentText());
}
I am getting an error as below:
Exception: Request failed for https://bhagavadgita.io returned code 405. Truncated server response: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>405 Method Not Allowed</title> <h1>Method Not Allowed</h1> <p>The method is not allo... (use muteHttpExceptions option to examine full response) (line 13, file "Code")
What is the proper way of making such a request?
Reference: https://bhagavadgita.io/api/
405 error is stating that you cannot query that endpoint with the current HTTP verb.
You should specify that your .fetch method is making a POST Http request.
To do so you have to specify in the "method" : "post" parameter in your fetch options:
var data = {
'client_id':'MY-CLIENT-ID',
'client_secret':'MY-CLIENT-SECRET',
'grant_type':'client_credentials',
'scope':'verse'
}
var options = {
"method" : "post",
"accept": "application/json",
"content-type": "application/x-www-form-urlencoded",
"payload" : data
}
var response = UrlFetchApp.fetch('https://bhagavadgita.io/auth/oauth/token', options);
References:
UrlFetchApp
REST