Need help populating Google Sheets from nested JSON - javascript

thanks in advance for any help.
I'm trying to get data from my Hubspot account into a Google Sheet, using their Analytics API (https://developers.hubspot.com/docs/methods/analytics/get-analytics-data-breakdowns)
I've written the following script in Google App Script:
var url = API_URL + "/analytics/v2/reports/totals/summarize/daily?&start=20181201&end=20181219";
var response = UrlFetchApp.fetch(url, headers);
var json = response.getContentText();
var dataALL = JSON.parse(json);
var dataSet = dataALL;
Logger.log(dataALL);
var rows = [],
data;
for (i = 0; i < dataSet.length; i++) {
data = dataSet[i];
rows.push(data.visits, data.leads);
}
Logger.log(rows)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheet = ss.getActiveSheet();
dataRange = sheet.getRange(1, 1, rows.length, 2);
dataRange.setValues([rows])
But when I try Logger.log(rows) it comes out empty. When I try Logger.log(dataSet.length) it returns 0.0
So I gather I'm making a mistake getting the JSON data into the array. I've done tones of research, but could not find a solution that works for my specific case.
The JSON I'm trying to write into the spreadsheet has the following format:
{2018-12-03 = [
{
contactsPerPageview=0.15384615384615385,
rawViews=143,
subscribers=1,
contactToCustomerRate=0.045454545454545456,
privacyConsentDeclines=11,
customersPerPageview=0.006993006993006993,
sessionToContactRate=0.2037037037037037,
pageviewsPerSession=1.3240740740740742,
opportunities=3,
visits=108,
visitors=98,
submissionsPerPageview=0.027972027972027972,
submissions=4,
leads=17,
privacyConsentApproves=9,
customers=1,
contacts=22,
newVisitorSessionRate=0.9074074074074074
}
],
2018-12-14 = [
{
contactsPerPageview=0.06722689075630252,
rawViews=238,
subscribers=4,
privacyConsentDeclines=14,
sessionToContactRate=0.08290155440414508,
pageviewsPerSession=1.233160621761658,
opportunities=6,
visits=193,
visitors=182,
submissionsPerPageview=0.029411764705882353,
submissions=7,
leads=6,
privacyConsentApproves=12,
contacts=16,
newVisitorSessionRate=0.9430051813471503
}]}
Can you guys point me in the right direction?
Thanks again,

Since dataSet is an object, it does not have a .length property, and your for loop will check if i is smaller than Undefined, which results in false. This means the for loop never runs.
I think what you're trying to achieve is closer to the following:
var dataSet = Object.keys(dataALL);
Logger.log(dataALL);
var rows = [], data;
for (i = 0; i < dataSet.length; i++) {
data = dataALL[dataSet[i]];
rows.push(data[0].visits, data[0].leads);
}
Logger.log(rows)
Note that since each key in your object contains an array, I also added [0] to both data.visits and data.leads, resulting in rows.push(data[0].visits, data[0].leads);.

Related

How to get nested elements in Google App script / JavaScript

I need to get values {nb_conversions":58"} under idgoal=ecommerceAbandonedCart, idgoal=4 and so on , I have tried different ways but unsuccessful, would appreciate it if someone can quickly sort this out for me.
Here is API URL: https://demo.matomo.cloud/?module=API&method=UserCountry.getRegion&idSite=1&period=day&date=yesterday&format=JSON&token_auth=anonymous
Sample Data:
[{"label":"Unknown","nb_uniq_visitors":558,"nb_visits":590,"nb_actions":980,"nb_users":0,"max_actions":14,"sum_visit_length":76439,"bounce_count":408,"nb_visits_converted":45,"goals":{"idgoal=ecommerceAbandonedCart":{"nb_conversions":58,"nb_visits_converted":58,"revenue":16199.299999999997,"items":88},"idgoal=ecommerceOrder":{"nb_conversions":10,"nb_visits_converted":10,"revenue":606.7,"revenue_subtotal":2448,"revenue_tax":0,"revenue_shipping":0,"revenue_discount":22.45,"items":12},"idgoal=4":{"nb_conversions":2,"nb_visits_converted":2,"revenue":2},"idgoal=5":{"nb_conversions":1,"nb_visits_converted":1,"revenue":5},"idgoal=6":{"nb_conversions":2,"nb_visits_converted":2,"revenue":4},"idgoal=7":{"nb_conversions":16,"nb_visits_converted":16,"revenue":16},"idgoal=8":{"nb_conversions":13,"nb_visits_converted":13,"revenue":0},"idgoal=10":{"nb_conversions":1,"nb_visits_converted":1,"revenue":0}},"nb_conversions":45,"revenue":633.7,"region":"xx","country":"xx","country_name":"Unknown","region_name":"Unknown","logo":"plugins\/Morpheus\/icons\/dist\/flags\/xx.png"}]
function Goals() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Goals");
var lastRow = sheet.getLastRow();
var today = sheet.getRange(1,6).getValue().toDateString();
var startDate = sheet.getRange(lastRow,1).getValue();
var now = sheet.getRange(lastRow,1).getValue().toDateString();
var dt = new Date(startDate);
//Logger.log(now);
// Logger.log(today);
//Logger.log(dt);
if( today != now){
var response = UrlFetchApp.fetch("https://demo.matomo.cloud/?module=API&method=UserCountry.getRegion&idSite=1&period=day&date=yesterday&format=JSON&token_auth=anonymous");
var json=response.getContentText();
var dataSet=JSON.parse(json);
for(var i = 0; i < dataSet.length; i++)
{
sheet.getRange(i+lastRow+1,2).setValue([dataSet[i]['label']]);
sheet.getRange(i+lastRow+1,3).setValue([dataSet[i]['nb_visits']]);
sheet.getRange(i+lastRow+1,4).setValue([dataSet[i]['nb_uniq_visitors']]);
sheet.getRange(i+lastRow+1,5).setValue([dataSet[i]['goals']['idgoal=ecommerceAbandonedCart']]);
sheet.getRange(i+lastRow+1,1).setValue(now);
}
dt.setDate(dt.getDate()+1);
lastRow = sheet.getLastRow();
sheet.getRange(lastRow+1,1).setValue(dt);
}
}
Given your sample data, try fetching the keys using Object.keys() and loop them one by one to get all nb_conversions instead of passing the idgoals individually. See below:
Code:
var dataSet = [{"label":"Unknown","nb_uniq_visitors":558,"nb_visits":590,"nb_actions":980,"nb_users":0,"max_actions":14,"sum_visit_length":76439,"bounce_count":408,"nb_visits_converted":45,"goals":{"idgoal=ecommerceAbandonedCart":{"nb_conversions":58,"nb_visits_converted":58,"revenue":16199.299999999997,"items":88},"idgoal=ecommerceOrder":{"nb_conversions":10,"nb_visits_converted":10,"revenue":606.7,"revenue_subtotal":2448,"revenue_tax":0,"revenue_shipping":0,"revenue_discount":22.45,"items":12},"idgoal=4":{"nb_conversions":2,"nb_visits_converted":2,"revenue":2},"idgoal=5":{"nb_conversions":1,"nb_visits_converted":1,"revenue":5},"idgoal=6":{"nb_conversions":2,"nb_visits_converted":2,"revenue":4},"idgoal=7":{"nb_conversions":16,"nb_visits_converted":16,"revenue":16},"idgoal=8":{"nb_conversions":13,"nb_visits_converted":13,"revenue":0},"idgoal=10":{"nb_conversions":1,"nb_visits_converted":1,"revenue":0}},"nb_conversions":45,"revenue":633.7,"region":"xx","country":"xx","country_name":"Unknown","region_name":"Unknown","logo":"plugins\/Morpheus\/icons\/dist\/flags\/xx.png"}];
for (var i = 0; i < dataSet.length; i++) {
// Upon testing your linked data, some of them doesn't have goals key.
// Be sure to only access those who have goals to avoid encountering an error.
if(dataSet[i]['goals']) {
Object.keys(dataSet[i]['goals']).forEach(function (idgoal){
Logger.log(dataSet[i]['goals'][idgoal]['nb_conversions']);
});
}
}
Output:
Note:
I recommend you format the data or view it in a site like this one. It really helps a lot.
The nb_conversions being fetched above are only the ones under the goals key.
If some idgoals doesnt have nb_conversions, just skip them like in goals above. The linked data above all has nb_conversions so I didn't include them for now.
References
Object.keys()

Missing variable name while trying to send sheet row data to GmailApp; Javascript/Google App script

Still on a learning curve here. I am trying to get data from a google sheet and send the data Gmail app but getting Missing variable name error. This is what I have tried for the last 2 hours and I will appreciate help in structuring the code to work.
function emailTheLastRow(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getRange("AO2:AO"+sheet.getLastRow()).getValues();
var searchString = "1";
for (var i = 0; i<range.length; i++) {
if(range[i][0] == searchString) {
var lastRow = sheet.getRange(2+i,1,1,41).getValues();
var data = {
'email':lastRow[0][1],
'project':lastRow[0][2],
'client':lastRow[0][3],
'sdate':lastRow[0][4],
'edate':lastRow[0][5],
'loe':lastRow[0][7],
};
GmailApp.sendEmail("test#gmail.com", "Project", "A new project has been created with the following details: " + data());
}
}
}
You're trying to concatenate a string with a JSON, which is an object and not a string. Use stringify function [1] to convert the object to a string. Add this line after you declare data variable:
data = JSON.stringify(data);
[1] https://www.w3schools.com/js/js_json_stringify.asp

Append an array in gSheets?

Firstly I am very inexperienced here so apologies if this is obvious.
I have an array of data that updates automatically and I wish to copy this data out so I have an archive of it.
I have managed to find the following script which works for what I want:
function saveInstaPostData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("xxx");
var data0 = sheet.getRange("xxx!A2:AQ21").getValue();
var data1 = sheet.getRange("xxx!B2").getValue();
var data2 = sheet.getRange("xxx!C2").getValue();
var data3 = sheet.getRange("xxx!D2").getValue();
sheet.appendRow([data1,data2,data3,...]);
}
However I have a range of 860 cells, so doing it one by one isn't too feasible.
Reading up on the appendRow method I realise that it (seems) to only be able to append one row at a time. I only have 20 rows so this should still be doable.
I then tried using
function saveInstaPostData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Insta faction post data");
var values = sheet.getSheetValues(2, 1, 1, 43);
sheet.appendRow([values]);
However this outputs the following in the first cell of the new row: [Ljava.lang.Object;#247f2c9a
This seems to be the array I'm trying to append (java: what is this: [Ljava.lang.Object;?) however I can't get it to work!
[I have also tried using
function saveInstaPostData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Insta faction post data");
var range = sheet.getRange(2,1,20,43);
var values = range.getValues();
sheet.appendRow([values]);
This outputs ' Range ' in the first cell of the new row.
]
Any pointers would be really appreciated,
Thanks,
On your example, you try to append a tri dimensionnal array:
var values = sheet.getSheetValues(2, 1, 1, 43);
or
var range = sheet.getRange(2,1,20,43);
var values = range.getValues();
Your "values" variable contains a bi dimensionnal array, that you've put in a mono dimensionnal array:
sheet.appendRow([values]); // [values] put bi dimensionnal array in a mono dimensionnal array
To append your data, you need to append each row of your array, one after a other like :
for(var i=0; i<values.length;i++){
sheet.appendRow(values[i]);
}

Google Form If Command Error

I've been trying to code a function for a Google form that will send an email to a particular teacher that is indicated by the form. The problem is that I keep getting an error on a simple if statement. The error says, "Missing ; before statement. (line 29, file "Code")". The code is based on this Google Apps tutorial: https://developers.google.com/apps-script/articles/mail_merge#section-5-full-code. This is what I have right now:
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheets()[0];
var dataRange = dataSheet.getRange(2, 1, dataSheet.getMaxRows() - 1, 4);
var templateSheet = ss.getSheets()[1];
var emailTemplate = templateSheet.getRange("A1").getValue();
// Create one JavaScript object per row of data.
var objects = getRowsData(dataSheet, dataRange);
// For every row object, create a personalized email from a template and send
// it to the appropriate person.
for (var i = 0; i < objects.length; ++i) {
// Get a row object
var rowData = objects[i];
// Generate a personalized email.
// Given a template string, replace markers (for instance ${"First Name"}) with
// the corresponding value in a row object (for instance rowData.firstName).
var emailText = fillInTemplateFromObject(emailTemplate, rowData);
var emailSubject = "Lab Visit Report";
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i++) {
var teacher = data[i][10];
If (teacher == "Jake Nabasny") {MailApp.sendEmail("JakeN#school.edu", emailSubject, emailText);}
else if (teacher == "Dan S") {MailApp.sendEmail("DanS#school.edu", emailSubject, emailText);}
}
}
I've already made sure that the variables (such as teacher and emailText) contain data. The problem, as far as I can tell, is solely with the if statement. Can anyone please give me an idea of what is going wrong here?
You seem to have capitialised an If ...

Google spreadsheet ImportRange - need to improve my workaround

I am pretty new to this forum and also to the google scripts. I have never actually learned JavaScript or any other programming language, however I was forced to start using then since the time I chose the google apps as my main platform for my small business.
My problem is in google ImportRange function limitation to 50 on every spreadsheet. I created a model, where every customer has his own spreadsheet with his personal data, deadlines, etc. located in his own folder in google drive.
I also created a spreadsheet called "Organizer", Organizer has two functions -
1) create automatic correspondention using autoCrat script,
2) show deadlines for every costumer and sort them by priority.
So i need to be able to share / import / copy data from all customer spreadsheets to the "Organizer". Because there are 50+ costumer spreadsheets, I had to give up on ImportRange function and instead of that I am using a simple script to copy files from every spreadsheet directly:
function ImportDataRange() {
// rown number.1
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Databaze");
var range = sheet.getRange(2, 1)
var id = range.getValue()
var ssraw = SpreadsheetApp.openById(id);
var sheetraw = ssraw.getSheetByName("Raw");
var range = sheetraw.getRange("A2:AB2");
var data = range.getValues();
sheet.getRange("B2:AC2").setValues(data)
// row number.2
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Databaze");
var range = sheet.getRange(3, 1)
var id = range.getValue()
var ssraw = SpreadsheetApp.openById(id);
var sheetraw = ssraw.getSheetByName("Raw");
var range = sheetraw.getRange("A2:AB2");
var data = range.getValues();
sheet.getRange("B3:AC3").setValues(data)
}
This script actually works well, but problem is, when I want to add new costumer spreadsheet to "Organizer" using this method, I have to manually add new copy of whole code for every new row and also change the output range of imported data and location of source file ID in "Organizer".
Does anybody know some kind of workaroud, which will help me to add new rows / costumer data easier / automatically ?
Thank you for your help!
You are going to want to use a loop of some sort. I haven't tested the code below, but based on your example, I think this should work for you.
function ImportOtherSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Databaze");
// Get the first column
// lastRow() - 1 because we're starting at row 2
var sheetIds = sheet.getRange(2, 1, sheet.getLastRow() - 1);
// For each ID in the id column
for (var i = 0; i < sheetIds.length; i++) {
var id = sheetIds[i]; // Get the id from the Array
// Get the new sheet, range and values
var ssraw = SpreadsheetApp.openById(id);
var sheetraw = ssraw.getSheetByName("Raw");
var range = sheetraw.getRange("A2:AB2");
var data = range.getValues();
// Get the local range, and write the values
sheet.getRange(i + 1, 2, 1, data[0].length).setValues(data)
}
}
As you learn more about GAS and JS, take advantage of MDN and the GAS Documentation
I took the fooby´s code and after long trial-and-error procedure I came with code that is working for me, so if anyone is interested, here it is:
function ShowDataFromOtherSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Databaze");
var ids = sheet.getRange(2, 1, sheet.getLastRow() - 1).getValues();
for (var i = 0; i < ids.length; i++) {
var id = ids[i];
var ssraw = SpreadsheetApp.openById(id);
var sheetraw = ssraw.getSheetByName("Raw");
var range = sheetraw.getRange("A2:AB2");
var data = range.getValues();
sheet.getRange(i + 2, 2, 1, data[0].length).setValues(data)
}
}
And thank you fooby - i would not make it without your help!

Categories