How to get data from API with GAS - json

First, I'm not a non-native, so there're some mistakes.And I'm a newbie.
function myFunction() {
var response = UrlFetchApp.fetch("https://api.ookami.me/v1/news/public?sport_id=1");
var json = JSON.parse(response.getContentText());
var news = JSON.parse(json.getContentText());
Logger.log("id");
Logger.log("url");
Logger.log("image");
}
CODE
I wrote "news" in line8's code, and that time, displayed the log. but wrote again, didn't display.
And the log displayed with id, url, image and so on, so I added the code on line6 and wrote the code on line8 to line10. But a log displayed "undefined".
I want to get data about id, url, image from this API with GAS.
And the data, I'll export to spread sheet.

You're almost there:
At this line:
var json = JSON.parse(response.getContentText());
You have all the data in this format:
I you want the element news, you need to change your line var news = JSON.parse(json.getContentText()); to var news = json.news;
Then you can loop through all the values:
for(var i = 0; i < news.length; i++) {
var obj = news[i];
Logger.log(obj.summary);
}
To export to spreadsheet, you just need to populate an Array inside the loop, and it should look like this:
var rows = []; // new values
for(var i = 0; i < news.length; i++) {
var obj = news[i];
rows.push([obj.id, obj.image,obj.url]); //your JSON entities here
}
Logger.log(rows);

Related

How to Import JSON data to google sheet with for loop

I almost import my JSON data from API.
But I don't know what is exactly the value of setvalue() in my case.
I want to get a google sheet of the product list loop automatically.
The final output that I want to get is the product list continually looping from page 1 to the last page.
When I run my code on Apps script, I got the output like the screenshot below.
But, It repeats only the first product of the product list.
function dearAPI(endpoint,sheetname,dig) {
const dataRows = [];
let pagenumber = 1;
const a = UrlFetchApp.fetch(
'https://inventory.dearsystems.com/externalapi/v2/product?page=1&limit=10',
{
'method':'get',headers:
{
"api-auth-accountid": accountID,
"api-auth-applicationkey": secret,
},
"contentType": 'application/json'
});
var sheet = SpreadsheetApp.getActiveSheet();
var json = JSON.parse(a.getContentText());
var headers = [Object.keys(json.Products[0])];
sheet.getRange(1,1,headers.length,headers[0].length).setValues(headers);
for(var i = 0; i < json.Products.length; i++){
var rows = [Object.values(json.Products[i])];
var final = Object.values(json.Products[i]);
getFinal = [final[i]];
for (var j = 0; j < json.Products.length; j++){
sheet.getRange(2, i+1, json.Products.length, rows[0].length).setValue(getFinal);
}
}
}
Suggestion:
Assuming this manually created sample JSON below has the same JSON structure from your API:
{
Products=[
{
Name=DarknessPumpLarge,
DropShipMode=NoDropShip,
Brand=Darkness,
DefaultLocation=Toronto,
Category=Accessories,
CostingMethod=FIFO,
Type=Stock
},
{
DropShipMode=NoDropShip,
Name=AppleiPhone,
Type=Stock,
DefaultLocation=California,
Category=Gadget,
Brand=Apple,
CostingMethod=FIFO
},
{
CostingMethod=FIFO,
Brand=Samsung,
DropShipMode=NoDropShip,
DefaultLocation=SouthKorea,
Name=SamsungGalaxyS21,
Category=Gadget,
Type=Stock
}
]
}
NOTE: It would also be better if you can share a snippet of your JSON value for better replication.
You can try this implementation, the script starting from the line with var = headers:
function dearAPI() {
var getFinal = []; //Assuming the `getFinal` was initialized as `an array variable
//Sample JSON value manually imputted here for replication
const json = {
"Products":[
{"Name":"Darkness Pump Large", "Category":"Accessories", "Brand":"Darkness", "Type":"Stock", "CostingMethod":"FIFO", "DropShipMode":"No Drop Ship", "DefaultLocation":"Toronto"},
{"Name":"Apple iPhone", "Category":"Gadget", "Brand":"Apple", "Type":"Stock", "CostingMethod":"FIFO", "DropShipMode":"No Drop Ship", "DefaultLocation":"California"},
{"Name":"Samsung Galaxy S21", "Category":"Gadget", "Brand":"Samsung", "Type":"Stock", "CostingMethod":"FIFO", "DropShipMode":"No Drop Ship", "DefaultLocation":"South Korea"}
]
}
var headers = [Object.keys(json.Products[0])];
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange(1,1,headers.length,headers[0].length).setValues(headers);
for(var i = 0; i < json.Products.length; i++){
var final = Object.values(json.Products[i]);
getFinal.push(final);
}
sheet.getRange(2,1,getFinal.length,getFinal[0].length).setValues(getFinal);
}
Sample Result:

API to Google sheets - unable to fetch data

I am trying to fetch data via API to Google sheets, I am able to get "NewConfirmed" and other few fields but not able to get "Countries" data. Please help.
function Covid19() {
// Call the COVID19 API
var response = UrlFetchApp.fetch("https://api.covid19api.com/summary");
// Parse the JSON reply
var json=response.getContentText();
var data=JSON.parse(json);
var sheet = SpreadsheetApp.getActiveSheet();
var i = 2;
for each (var info in data)
{
sheet.getRange(i,1).setValue([info['NewConfirmed']]);
sheet.getRange(i,2).setValue([info['Country']]);
i = i + 1;
}
If you log data, you will see
{Countries=[{CountryCode=AX, TotalRecovered=0.0, NewDeaths=0.0,
Slug=ala-aland-islands, Country=ALA Aland Islands, NewRecovered=0.0,
Date=2020-04-21T12:32:01Z, NewConfirmed=0.0, ...
Thus, in order to retrieve Country and NewConfirmed you need to define
var data=JSON.parse(json).Countries and then you have to iterate through all entries within a loop.
Sample based on your code:
function Covid19() {
var response = UrlFetchApp.fetch("https://api.covid19api.com/summary");
var json=response.getContentText();
var data=JSON.parse(json).Countries;
var sheet = SpreadsheetApp.getActiveSheet();
for(var i = 0; i < data.length; i++)
{
sheet.getRange(i+2,1).setValue([data[i]['NewConfirmed']]);
sheet.getRange(i+2,2).setValue([data[i]['Country']]);
}
}
Sidenote:
It is ot good practive to use getRange(...).setValue(..) during each
loop iteration. It would be better to write the data into an array and
assign the array with all the data to the sheet after finishing
iteration.

How to loop pagination in Pipedrive to get all deals?

I have more than 5000 deals in Pipedrive and I want to pull all the deals using Pipedrive integration to google sheet.
I tried some script and successfully pull some data but the problem is Pipedrive has only 500 max limit in each page.
So would like to ask how will I able to loop the pagination and to get all the deals.
please see the script below.
function GetPdriveSalesToday() {
var ss = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxxx');
var sheet = ss.getSheetByName("Sheet6");
var lastrow = sheet.getLastRow();
sheet.getRange("Sheet6!A2:C3500").clearContent();
var url = "https://api.pipedrive.com/v1/deals?filter_id=2699&start=1&limit=500&api_token=xxxxxxxxxxxxxxxxxxxx";
var response = UrlFetchApp.fetch(url);
var dataSet = JSON.parse(response.getContentText());
var data;
for (var i = 0; i < dataSet.data.length; i++) {
data = dataSet.data[i];
sheet.appendRow([data.id,data.title,data.e2c4a2838c16e53c6f4cf3b54ac5bfe253310a7a]).getRange(lastrow +1,1);
}
}
They gave an official functional example function about retrieving all records using pagination data which given as additional data once you made your request, have a good at this:
https://pipedrive.readme.io/docs/using-pagination-to-retrieve-all-deal-titles

Error in Google Sheets Script when parsing XML

I have this function running in a Google Sheets script that pulls HTML from subreddits and returns them to a spreadsheet. It works for me some/most of the time, but other times I get an error "Could not parse text. (line 13)" which is the line with var doc = Xml.parse(page, true);. Any idea why this is happening or is this just a bug with Google Scripts? Here's the code that works...sometimes.
function getRedditHTML() {
var entries_array = [];
var subreddit_array = ['https://www.reddit.com/r/news/','https://www.reddit.com/r/funny/','https://www.reddit.com/r/science/'];
for (var s = 0; s < subreddit_array.length; s++) {
var page = UrlFetchApp.fetch(subreddit_array[s]);
//this is Line 13 that is breaking
var doc = Xml.parse(page, true);
var bodyHtml = doc.html.body.toXmlString();
doc = XmlService.parse(bodyHtml);
var root = doc.getRootElement();
var entries = getElementsByClassName(root,'thing');
for (var i = 0; i < entries.length; i++) {
var title = getElementsByClassName(entries[i],'title');
title = XmlService.getRawFormat().format(title[1]).replace(/<[^>]*>/g, "");
var link = getElementsByClassName(entries[i],'comments');
link = link[0].getAttribute('href').getValue();
var rank = getElementsByClassName(entries[i],'rank');
rank = rank[0].getValue();
var likes = getElementsByClassName(entries[i],'likes');
likes = likes[0].getValue();
entries_array.push([rank, likes, title, link]);
}
}
return entries_array.sort(function (a, b) {
return b[1] - a[1];
});
}
Here is what I found upon playing with importXML (my usual way of doing this) - for some reason I cannot narrow down - it DOES appear to randomly stall out and return null for a few minutes - so I'm guessing the issue with your thing is not the code but that the site or google temporarily blocks/won't return the data -
however I found the JSON endpoint to the piece you want - and I noticed that when XML went down - the JSON didnt.
You can take that and fix it to push your own array of topics/urls - I just left it for one link for now to show you how the URL breaks down and where it should be modified:
The URL is 'https://www.reddit.com/r/news/hot.json?raw_json=1&subredditName=news&sort=top&t=day&feature=link_preview&sr_detail=true&app=mweb-client
News is mentioned in 2 places so just modify all your URLs to follow that method - you can easily load that javascript in a browser to see all the fields available
Also the portion hot.json is where you can change whether you want the ranked list (called hot), or new,top,promoted, etc. you just change that keyword.
Score is the same as the upvotes/likes
function getSubReddit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet(); //get Active sheet
var subject = 'news';
var url = 'https://www.reddit.com/r/' + subject + '/hot.json?raw_json=1&subredditName=' + subject + '&sort=top&t=day&feature=link_preview&sr_detail=true&app=mweb-client'; //json endpoint for data
var response = UrlFetchApp.fetch(url); // get api endpoint
var json = response.getContentText(); // get the response content as text
var redditData = JSON.parse(json); //parse text into json
Logger.log(redditData); //log data to logger to check
//create empty array to hold data points
var statsRows = [];
var date = new Date(); //create new date for timestamp
//The following lines push the parsed json into empty stats array
for (var j=0;j<25;j++){
for (var i =0;i<25;i++){
var stats=[];
stats.push(date);//timestamp
stats.push(i+1);
stats.push(redditData.data.children[i].data.score); //score
stats.push(redditData.data.children[i].data.title); //title
stats.push(redditData.data.children[i].data.url); //article url
// stats.push('http://www.reddit.com' + redditData.data.children[i].data.permalink); //reddit permalink
statsRows.push(stats)
}
//append the stats array to the active sheet
sheet.appendRow(statsRows[j])
}
}

Parsing XML Data that I receive from UrlFetch

I want to parse the data I get from UrlFetch into a spreadsheet, but all I'm getting is undefined can someone show me what i'm doing wrong
The xml is at the address https://dl.dropbox.com/u/11787731/Minecraft/bans.xml
function runevery15mins() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("MC Bans");
sheet.clearContents();
var banURL = "https://dl.dropbox.com/u/11787731/Minecraft/bans.xml";
var banXML = UrlFetchApp.fetch(banURL).getContentText();
var banDOC = Xml.parse(banXML, false);
var mcuser = banDOC.bans;
var x = 0;
for(var c=0; c>mcuser.length;c++){
var name = mcuser.getElement("username")[c].getText();
var date = mcuser.getElement("date")[c].getText();
var reason = mcuser.getElement("reason")[c].getText();
var duration = mcuser.getElement("duration")[c].getText();
}
sheet.appendRow([name, date, reason, duration]);
}
You have some small errors in your code.
For example, the second argument in the for loop needs to be c<mcuser.length.
Using the Xml service documentation, this worked for me
function runevery15mins() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("MC Bans");
sheet.clearContents();
var banURL = "https://dl.dropbox.com/u/11787731/Minecraft/bans.xml";
var banXML = UrlFetchApp.fetch(banURL).getContentText();
var banDOC = Xml.parse(banXML, false);
// Get all the child nodes from the document element that are 'user' nodes
var mcusers = banDOC.getElement().getElements('user');
for(var c=0; c<mcusers.length;c++){
var user = mcusers[c];
var name = user.getElement('username').getText();
var date = user.getElement('date').getText();
var reason = user.getElement('reason').getText();
var duration = user.getElement('duration').getText();
sheet.appendRow([name, date, reason, duration]);
}
}
Note for example that the sheet.appendRow line is INSIDE the loop, not outside as you had it before. I also deleted the X variable, since I didn't see any purpose for it.
I also created a user variable, which is an XmlElement, to make it easier to understand how to get the different contents of each node.
You were almost there.
Looks like there was another array you needed to drill down into. Also, your call back to the spreadsheet should be in the loop. Try this:
...
var mcuser = banDOC.bans.user;
for(var i in mcuser){
var name = mcuser[i].getElement("username").getText();
var date = mcuser[i].getElement("date").getText();
var reason = mcuser[i].getElement("reason").getText();
var duration = mcuser[i].getElement("duration").getText();
sheet.appendRow([name, date, reason, duration])
}