fetch multiple api requests, parse once, in Google Apps script, doe - json

I'm having trouble with the fetchAll method for UrlFetchApp.
I'm currently running multiple functions to gather api data from a handful of links with slight variations in api actions. All functions are returning and parsing data under consistent JSON fields. I want to have one function to retrieve the api data at once, parse once, and output once. I thought fetchAll would be the better method of doing this. The output will be to a spreadsheet.
Below is a variation of the script simplified for privacy. I keep getting "Cannot find method fetchAll(object,object)" error at line 14. I have tried fetching the urls with UrlFetchApp.fetchAll[eth,btc] and this gets me past the error but then "Cannot call method 'getContentText' of undefined".
Can't seem to figure out the correct way to do this from the Google Apps documentation. No help from google discussion group so far.
Do I need to incorporate the parse as an object within the fetchAll method?
function dailyhx() {
var ss = SpreadsheetApp.getActive().getSheetByName('DailyHx');
var eth = {
'url' : 'https://min-api.cryptocompare.com/data/histoday?fsym=ETH&tsym=USD&limit=10',
'method' : 'get',
'contentType' : 'application/json',
};
var btc = {
'url' : "https://min-api.cryptocompare.com/data/histoday?fsym=BTC&tsym=USD&limit=10",
'method' : 'get',
'contentType' : 'application/json',
};
var mph = UrlFetchApp.fetchAll(eth, btc)
var j1 = JSON.parse(mph.getContentText());
Loager.log(j1)
}

The UrlFetchApp.fetchAll() function only expects one parameter which must be an array.
So replace this:
var mph = UrlFetchApp.fetchAll(eth, btc);
with this:
var requests = [eth, btc];
var mph = UrlFetchApp.fetchAll(requests);

Related

I can't resolve error with API POST function

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"},

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.

Update Classroom courseState using patch

I am trying to write an Apps Script function to archive a whole bunch of courses in Google Classroom.
function myFunction() {
var response = Classroom.Courses.list();
var optionalArgs = {'courseState': 'ARCHIVED'};
var courses = response.courses;
if (courses && courses.length > 0) {
for (i = 0; i < courses.length; i++) {
var course = courses[i];
Classroom.Courses.update(course.name, course.id, {'updateMask':'courseState'}, body=optionalArgs); // Line 10
//Logger.log('%s (%s) [%s]', course.name, course.id, course.enrollmentCode);
}
}
}
I get the following error when running the above code:
Invalid number of arguments provided. Expected 2-3 only (line 10, file "ArchiveAll")
What is the correct way of doing this with Google Apps Script and the Classroom advanced service?
Based on the code, it looks like you may have previously used the Python client libraries (specifically the body=optionalArgs portion). In JavaScript / Google Apps Script, keyword parameter assignment isn't a thing, at least not like it is in Python.
The format expected by class methods in Google's "Advanced Services" client libraries are derived from the HTTP REST API specification for the associated API. For the Classroom.Courses.update call, this is courses#update (or per your title, courses#patch).
The REST API spec for update is for 1 path parameter (the course id), and a request body with a Course resource. As with all Google APIs, you can additionally add any of the Standard Query Parameters as an optional argument. This count - 2 required, 1 optional) corresponds with the error message you received:
Invalid number of arguments provided. Expected 2-3 only
Thus, your function should be something like:
function updateCourse_(course) {
course.courseState = 'ARCHIVED';
const options = {
fields: "id,name,courseState" // data sent back in the response.
};
return Classroom.Courses.update(course, course.id, options);
}
The patch method has an additional optional argument, the updateMask query parameter. As with other optional parameters (like Standard Query Parameters), this is passed in an object as the last parameter to the class method:
function patchCourse_(courseId) {
const newMetaData = {
courseState: 'ARCHIVED',
// other options, must be valid Course fields per patch documentation:
// https://developers.google.com/classroom/reference/rest/v1/courses/patch#query-parameters
};
const options = {
updateMask: "courseState", // CSV string of things you alter in the metadata object
fields: "id,name,courseState" // data sent back in the response
};
return Classroom.Courses.patch(newMetaData, courseId, options);
}
The updateMask allows you to use some template Course resource and only apply the specified portions of it to a specified course. If you were to use update instead of patch, you would alter all fields to use the template's values:
function patchedViaTemplate_(templateCourse, courseId, fieldsToAlter) {
const options = { updateMask: fieldsToAlter };
return Classroom.Courses.patch(templateCourse, courseId, options);
}

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.

GDocs Script to fetch web info behind a form using UrlFetchApp

I want to fetch some web data using GDocs but the data is behind a form so I need to post some data to the form to get the result. (So I cant use ImportXML etc)
The function that I am trying to use is https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app but I dont really know where to start since I don't have much java script experience.
Is there anyone that has a script that takes an url, form name & the data to post that can be used in GDocs?
There's an example of such a script here: How do I use Google Apps Script to change a CSS page to one with inline styles?.
It's a different application, but the method applies. Here's a skeleton function to get you started.
The payload object should contain the name / value pairs of the form data you want to simulate. The url should be changed to match the site you're submitting the form to. Once you've made the POST request by the call to UrlFetchApp.fetch(), you should be able to parse the response using the getElementByVal() utility from Does Google Apps Script have something like getElementById?.
function postForm() {
// Generate a POST request with form data.
var payload =
{
"name" : 'Anonymous Person', // Replace with relevant name / value pairs
"town" : "Springfield"
};
// Because payload is a JavaScript object, it will be interpreted as
// an HTML form. (We do not need to specify contentType; it will
// automatically default to either 'application/x-www-form-urlencoded'
// or 'multipart/form-data')
var options =
{
"method" : "post",
"payload" : payload,
"muteHttpExceptions" : true
};
var url = "http://form.somewhere.com"; // Replace as appropriate
var response = UrlFetchApp.fetch(url, options);
// Put the receieved xml response into XMLdocument format
var xml = response.getContentText();
var doc = XmlService.parse(xml);
// Extract the details you want...
var someData = getElementByVal( doc, 'textarea', 'name', 'text' );
...
}