Get data from array in nested json using Google Script - json

I need to fix a Google Script I've been working on. Basically, I have a json https://www.instagram.com/nike/?__a=1 that returns basic info about Nike's account on instagram. I have no problem retrieving data from objects such as "biography". But, when I try to retrieve nested objects (arrays) I'm doing something wrong because the results arrive duplicated (see attachment). Can anyone help me figure out what I'm doing wrong?
// the name of the sheet within your document
var sheetName = "Sheet1";
// the name of the Instagram account you want the follower count for
var instagramAccountName = "nike";
function insert() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(this.sheetName);
var followers = [];
var followers = captionArray(this.instagramAccountName);
for(var i = 0 ; i < 3; i++) {
sheet.appendRow([Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd"), followers]);
};
}
function captionArray(username) {
var i = 0;
for(var i = 0; i < 3; i++) {
var url = "https://www.instagram.com/" + username + "/?__a=1";
var response = UrlFetchApp.fetch(url).getContentText();
var caption = [];
var caption = JSON.parse(response).graphql.user.edge_owner_to_timeline_media.edges[i].node.edge_media_to_caption.edges[i].node.text;
return caption;
};
}

I think this is causing problems:
You're using the same index (i) for both arrays, but the second have only one element.
You just need to do one request.
This code works for me:
function captionArray(username) {
var captions = [];
var url = "https://www.instagram.com/nike/?__a=1";
var response = UrlFetchApp.fetch(url).getContentText();
var edges = JSON.parse(response).graphql.user.edge_owner_to_timeline_media.edges;
for(var i = 0, limit = edges.length; i < limit; i++) {
captions.push(edges[i].node.edge_media_to_caption.edges[0].node.text);
}
return captions;
}

Related

How to define numbers inside a string to map JSON in Javascript?

The API has numbers to define each of the data containers, I've tried to use several ways to be able to define these numbers, but without success.
In the image you can see the map clubes.262 clubes.264 clubes.265 clubes.266 clubes.275
My attempts:
var idclub = clubes[i].id;
var idclub = clubes.[i].id;
var idclub = clubes[0][i].id;
var idclub = clubes. + i + .id;
The complete script for easy viewing:
function MenuMercadoCartola1() {
var url = 'https://api.cartolafc.globo.com/atletas/mercado';
var response = UrlFetchApp.fetch(url);
var results = JSON.parse(response.getContentText());
var clubes = results.clubes;
var table = [['ID do Clubes','Nome do Clube']];
for (var i = 0; i < clubes.length; i++) {
var idclub = clubes[i].id;
var nameclub = clubes[i].nome;
table.push([idclub,nameclub]);
}
var sheet = SpreadsheetApp.getActive().getSheetByName('Menu');
sheet.getRange(1,1, table.length, table[0].length).setValues(table);
}
It appears that you should be using a 'for in' loop.
Your code revised:
for (var idclub in clubes)
{
idclub = +idclub;
var nameclub = clubes[idclub].nome;
table.push([idclub, nameclub]);
}
Your loop assumes clubes is an array however it is an object which means you could have to iterate on it using a for (var ... in ...) loop.

How to change cell values?

I'm using Google app script for sheets and I'm new to it.
I have a column with number and a hyperlink in each cell (each link and number is different).
I want to get the link then make an API request which will return a number which will replace that original number for each cell.
At the moment here is my function:
function getLinkUrls() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("B2:B");
var values = range.getRichTextValues();
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < values[i].length; j++) {
if (values[i][j].getLinkUrl() !== null) {
const val = values[i][j],
url = val.getLinkUrl(),
path = url.split('/')[3];
var response = UrlFetchApp.fetch(`https://decapi.me/twitch/followcount/${path}`),
f = response.getContentText();
}
}
}
}
I want to replace each cell now with f but I'm unsure how.
Table:
Column B should always have hyperlink
I have successful replace the hyperlink with the follower count, you may try if working on your side also, since I did not use getrichtext but getvalue directly:
function getLinkUrls1() {
var sheet = SpreadsheetApp.getActiveSheet();
for (var i = 2; i <= sheet.getLastRow(); i++) {
var url = sheet.getRange(i,2).getRichTextValue().getLinkUrl();
if (url){
var path = url.split('/')[3];
var response = UrlFetchApp.fetch(`https://decapi.me/twitch/followcount/${path}`),
f = response.getContentText();
sheet.getRange(i,2).setRichTextValue(SpreadsheetApp.newRichTextValue()
.setText(f).build());
}
}
}
This is my sample data:

Script: Transpose, Find and Save

I have some data containing, Dates, Usernames and an average percent that i want to save in a certain way. My problem is that the order of the usernames can change depending on if new ones are added. I therefore need to "find" a specific username and then save the percentage data in the correct column.
I have found some code that partially helps me save the data that i need. But i could use some help in the "find" the corresponding username and save it in a certain Column part.
function save() {
var sss = SpreadsheetApp.getActive();
var ss = sss.getSheetByName('Result');
var range = ss.getRange('B1:B10');
var data = range.getValues();
var tss = SpreadsheetApp.getActive();
var ts = tss.getSheetByName('Archive');
ts.getRange(ts.getLastRow()+1, 1,data[0].length,data.length)
.setValues(Object.keys(data[0]).map ( function (columnNumber) {
return data.map( function (row) {
return row[columnNumber];
});
}));
}
Basically from this:
To a result that looks like this:
Thank you for your assistance.
Alright for anyone out there that may have a similar problem, this is what i ended up with.
function extractAttendance() {
var currentSheet = SpreadsheetApp.getActive();
var attendanceTab = currentSheet.getSheetByName('Data_Filtered');
var userData = attendanceTab.getRange('B1:B').getValues();
var percentageData = attendanceTab.getRange('I1:I').getValues();
var archiveTab = currentSheet.getSheetByName('Archive');
var existingUsersRow = archiveTab.getRange('1:1');
var newRowNumber = archiveTab.getLastRow() + 1;
archiveTab.getRange(newRowNumber, 1).setValue(new Date());
for (var i = 1; i < userData.length; i++) {
var user = userData[i][0];
if (user === '') {
continue;
}
var existingUsers = existingUsersRow.getValues()[0];
var exists = false;
var existingColumnNumber = -1;
for (var j = 0; j < existingUsers.length; j++) {
if (existingUsers[j] === user) {
exists = true;
existingColumnNumber = j + 1;
break;
}
}
if (exists) {
archiveTab.getRange(newRowNumber, existingColumnNumber).setValue(percentageData[i]);
} else {
var newColumnNumber = archiveTab.getLastColumn() + 1;
archiveTab.getRange(1, newColumnNumber).setValue(user);
archiveTab.getRange(newRowNumber, newColumnNumber).setValue(percentageData[i]);
}
}
}
It might be easier to implement your desired functionality through looping rather than through mapping.
The following code retrieves all users ad their percentage data in ‘Result’ and transfers the data (in the format you desire) to "Archive" with the percentages data pasted with the corresponding timestamp into the first empty row.
function save() {
var sss = SpreadsheetApp.getActive();
var ss = sss.getSheetByName('Result');
var range = ss.getRange('B1:B');
var percentageRange = ss.getRange('G1:G');
var userData = range.getValues();
var percentageData = percentageRange.getValues();
var tss = SpreadsheetApp.getActive();
var ts = tss.getSheetByName('Archive');
var userRow=1;
var percentageRow=(ts.getLastRow()+1)
for(var i=0; i<=userData.length; i++)
{
{
var j=(i+2);
ts.getRange(userRow, j).setValue(userData[i])
ts.getRange(percentageRow, 1).setValue(new Date())
ts.getRange(percentageRow, j).setValue(percentageData[i])
}
}
}

Load data from google sheet on start up

I tried to retrieve a list of agents who are stored in a google sheet. The problem that I am facing right now is that I can get the list of agents in the script file. However, when I try to pass it to an html file, I keep getting null for the list. I absolutely has no idea how that can be.
Can someone give me an idea where I should look for?
My script:
var DB_URL = "";
var AGENT_DB = "";
var CREATED_ON_IDX = 0;
var NAME_IDX = 1;
var EMAIL_IDX = 2;
function agentService_getAgents() {
var ss = SpreadsheetApp.openByUrl(DB_URL);
var sheet = ss.getSheetByName(AGENT_DB);
var dataRange = sheet.getDataRange();
var agents = [];
var values = dataRange.getValues();
for (var i = 1; i < values.length; ++i) {
var row = values[i];
var name = row[NAME_IDX];
var email = row[EMAIL_IDX];
var createdOn = row[CREATED_ON_IDX];
var agent = new Agent(name, email, createdOn);
agents[i-1] = agent;
}
Logger.log(agents);
return agents;
}
Ajax call in Html
<script type="text/javascript">
function onSuccess(agents) {
var $table = $("table");
console.log(agents);
}
google.script.run.withSuccessHandler(onSuccess)
.agentService_getAgents();
</script>
So Logger.log(agents) gives me a list of agent; but console.log(agents) gives me null.

Parse JSON formatted result of HTTP request into columns

Google Apps Script to pull data from API. I'd like to parse out the information according to the relevant headers.
function Fraud2() {
var ret = "no value";
var response = UrlFetchApp.fetch("https://fraudshield.24metrics.com/api/v1/reports/fraud.json?tracker_id=905&group[]=sub_id&group[]=partner&date_start=2018-01-18&date_end=2018-01-18&timezone=UTC&user_id=XXX&api_token=XXX",{muteHttpExceptions:true})
var user_id = "XXX";
var api_token = "XXX";
var sheet = SpreadsheetApp.getActiveSheet();
sheet.appendRow([response]);
}
The return is pushed into one single cell like so:
{"results":[{"tracker_id":905,"conversion":7883,"click":0,"goal":0,"approved":6511,"rejected":1372,"tracker":"Tatoo
Integration","conversion_rate":"N\/A"},{"tracker_id":906,"conversion":1868,"click":0,"goal":0,"approved":1682,"rejected":186,"tracker":"Aise
Integration","conversion_rate":"N\/A"},{"tracker_id":933,"conversion":413,"click":0,"goal":0,"rejected":290,"approved":123,"tracker":"Tatoo
Invalids Integration","conversion_rate":"N\/A"}]}
I tried this without success.
How can I get the results arranged neatly into columns?
As Hink said, you need to convert the object to an array first.
Hinks solution will work fine but below is a combination of the code you tried to use in your post.
function Fraud2() {
var ss = SpreadsheetApp.getActiveSheet();
var ret = "no value";
var response = UrlFetchApp.fetch("https://fraudshield.24metrics.com/api/v1/reports/fraud.json?tracker_id=905&group[]=sub_id&group[]=partner&date_start=2018-01-18&date_end=2018-01-18&timezone=UTC&user_id=XXX&api_token=XXX",{muteHttpExceptions:true})
var user_id = "XXX";
var api_token = "XXX";
var out=JSON.stringify(response.results);
out=JSON.parse(out)
var title = [];
for (var i in out[0]) {
title.push(i);
}
var res = [];
res.push(title);
for (var i in out) {
var values = [];
for (var j in out[i]) {
values.push(out[i][j]);
}
res.push(values);
}
ss.getRange(1, 1, res.length, res[0].length).setValues(res);
};
You need to convert the response object into an array and append the array:
for (var i = 0; i < response.results.length; i++){
var current = response.results[i];
var myArray = [current.tracker_id, current.conversion, current.click, current.goal, current.approved, current.rejected, current.tracker,current.conversion_rate];
sheet.appendRow(myArray);
}