I can't resolve error with API POST function - json

I am trying to post data via an API interface.
I have checked the JSON of the data with JSON formatter and tested the API post in ReqBin and they work fine but when I execute it in App Script I get the same error, seemingly ignoring the attributes I put in the options variable.
Error is
{"code":"not_acceptable","message":"I can only talk JSON. Please set 'Accept' and 'Content-Type' to 'application/json' in your http request header."}
Note: I have tried sending just the data as the payload without json.stringify'ing it as it is formatted as JSON to start with.
In all cases it executes, but comes back 406
Is there another way to add 'Accept':"application/json" into the header??
My Code
function exportNation()
{
// Make a POST request with a JSON payload.
var data = {
"person":
{
"email":"mikenizzckelisaweiner#tv.com",
"last_name":"Bozzrovowski",
"first_name":"Edwzzard",
"tags":"Imported Data,Volunteer,Sign Request"
}
};
var options = {
"method":"POST",
"Content-Type":"application/json",
'Accept':"application/json",
'muteHttpExceptions':true,
'payload':JSON.stringify(data)
};
var response = UrlFetchApp.fetch('https://xyz.xyz.com/api/v1/people?
access_token=5604da84fXXXXXXXXXXXXXXXX42da1ea',options );
}
Any help would be greatly appreciated!

Additional HTTP headers need to be sent as a headers object.
See: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#advanced-parameters
var options = {
"method":"POST",
"contentType":"application/json",
"headers": {'Accept':"application/json"},

Related

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.

How to parse HTTP response?

I'm trying to build a script to run in Google Sheets to automatically pull my bank account balance into the sheet. I'm using Plaid to get the account information. I've pulled the information using UrlFetchApp. I'm stuck trying to figure out how to parse the returned text for the available balance information.
I've tried to use an old XML method to parse it, but quite frankly I don't think I'm even close to figuring out this problem.
function myFunction() {
//HTTP Request
var avail_balance = [];
var data = {
"client_id": "5bf874c39bb5dc0012b1be13",
"secret" : "Redacted",
"access_token" : "Redacted"
};
var payload = JSON.stringify(data);
var options = {
"method" : "POST",
"contentType" : "application/json",
"payload" : payload
};
var url = "https://development.plaid.com/accounts/balance/get";
var response = UrlFetchApp.fetch(url, options);
//Parse HTML
//return avail_balance
return avail_balance
}
The docs for Plaid API say this under API protocols
The Plaid API uses POST requests to communicate and HTTP response
codes to indicate status and errors. All responses come in standard
JSON
Plaid API documentation
You should only use XmlService to parse XML, not JSON. JSON is a standard notation for objects, not just in JavaScript but in many other languages as well so the name is a bit confusing.
Calling UrlFetchApp.fetch() will return an HttpResponse object that you can then parse to JSON (if, in fact, it's a valid JSON - if not, try logging the response first via Logger.log(response))
var responseString = resonse.getContentText();
var data = JSON.parse(responseString);
UrlFetchApp methods
Checked the documentation for the Plaid service and it appears that the response payload is formatted as JSON. So I'm not sure why you'd need to parse the response as HTML.
Try using JSON.parse() on the response instead and then referencing the appropriate property as detailed in the documentation.

POST request not able to find url

I am new to nodejs as well as developing.
I am trying to get a set of data bat from a nutrition site in JSON format. If I formulate the url with my app and api keys along with criteria to paste into the browser I get a JSON data ok. When I try to send a POST request as the site asks for when the request comes back it says it cannot find the url. What it is doing is attaching ':443' to the end of the host url and like I said coming back as an error:
Error: getaddrinfo ENOTFOUND https://api.nutritionix.com/v1_1/search https://api.nutritionix.com/v1_1/search:443
What I would like to do is after the end of the url is append the 'postData'.
Here is my code:
var https = require('https');
var querystring = require('querystring');
var postData = { // Nutrionix required JSON formt
"appId":"MY_APP_KEY",
"appKey":"MY_API_KEY",
"query": "Lentils",
"fields": ["item_name", "nf_calories", "nf_serving_size_qty", "nf_serving_size_unit"],
"sort":{
"field":"score",
"order":"desc"
},
"filters":{
"item_type":"2"
}
};
console.log("This is header dta" + postData);
postBody = querystring.stringify(postData);
var post_options = {
host:"https://api.nutritionix.com/v1_1/search",
"port":"443",
method:"post",
"path":"/",
headers:{"Content-Type":"application/json",
'Content-Length': postBody.length
}
}
console.log(post_options);
var request = https.request(post_options,function(response){
return response;
});
I also am passing this data into the dev HTTP add-on in Chrome and getting back the proper response.
Any help would be appreciated.
Can you please take a look at this documentation?
It seems that you don't need to mention HTTPS
Take the port off, 443 is the default for HTTPS.

Invalid Argument on basic API call using UrlFetchApp.fetch(url)

I'm new to Google Apps Scripts and I've been trying to make a simple Get call to a URL. I make this call from my browser: https://accounting.sageone.co.za/api/1.1.1/Supplier/Get?apikey={4CFEEFE1-CE04-425F-82C3-DCB179C817D5}&companyid=164740 and get the respons I'm looking for. I now try to make the call from Google Apps Scripts using the following code:
function myFunction() {
var url = 'https://accounting.sageone.co.za/api/1.1.1/Supplier/Get?apikey={4CFEEFE1-CE04-425F-82C3-DCB179C817D5}&companyid=164740
var response = UrlFetchApp.fetch(url);
Logger.log(response);
}'
I get a respons stating '
Message details
Invalid argument: https://accounting.sageone.co.za/api/1.1.1/Supplier/Get?apikey={4CFEEFE1-CE04-425F-82C3-DCB179C817D5}&companyid=164740 (line 4, file "Code")'
I've tried a whole bunch of permutations with no luck...
When using UrlFetchApp, you need to enter your URL parameters as part of a request parameters rather than in the URL itself. For a GET request these go directy as part of the parameters, for a POST request the parameters would be part of a payload object. Reference Documentation
Here is a modified function:
function myFunction() {
var url = 'https://accounting.sageone.co.za/api/1.1.1/Supplier/Get'
var params = {
"method": 'GET',
"apikey": "{4CFEEFE1-CE04-425F-82C3-DCB179C817D5}",
"companyid": "164740"
}
var response = UrlFetchApp.fetch(url, params);
Logger.log(response)
}
Note: This corrects your method, however, the server still requires further authentication. If you run into issues with that, ask another questions specific to that issue as well.

Angularjs - equal sign in $http post data

I'm using angularjs' $http service to post data to my API. It works great.. until I add and equals sign to the contents of data (JSONRequest in example)
var request = {
'method': 'POST',
'url': API_URL + apiActionName,
'data': JSONRequest,
'withCredentials': true,
};
$http(request).
success(function(data, status, headers, config) {
// handle success
}).
error(function(data, status, headers, config) {
// handle error
}
this works for data contain the following JSONRequest
{
'text':'this is some text'
}
however when the data contains this
{
'text':'this is = some text'
}
the request is escaped and the server cannot do anything with the POST!! It seems to work with all other characters.
Any help would be greatly appreciated! Thanks
I always use JSON.Stringify() for my POST payloads.
It had to do with URI encoding. The string that was getting getting sent the the lower level AJAX API was not uri encoded. This means that when it saw the = sign in the post it was parsing it assuming uri encoding.
All of the information may not have been present to answer this question as JSONRequest was originally was defined on the line above var request. Sorry about that. It was defined as follows:
var JSONRequest = {
'JSON': requestObject;
}
where requestObject was
{
'text':'this is = some text'
}
I ended up URI encoding the JSON Request as follows
var JSONRequest = 'JSON=' + encodeURIComponent(JSON.stringify(requestObject));
This fixed the problem and made my API calls more robust to the HTTP protocol.
Thanks for all the help!!