In google sheets using the Coinmarketcap.com API I am trying to download data.
For this purpose, I have a loop in which I want to iterate subsequent names from the previously created table.
var listaCrypto = "BTC,ETH,ADA";
var tabCrypto = listaCrypto.split(",");
for (var i = 1; tabCrypto[i]; i++) {
var url='https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol='+tabCrypto[i];
var result= UrlFetchApp.fetch(url, requestOptions);
var txt= result.getContentText();
var d=JSON.parse(txt);
lista1.getRange(start_row + rankBTC, 1).setValue(d.data.tabCrypto[i].name); //<-- this doesn't
lista1.getRange(start_row + rankBTC, 2).setValue(d.data.BTC.name); //<-- this line works
}
You can use this syntax object["property_name"] to retrieve a property property_name from object
var listaCrypto = "BTC,ETH,ADA";
var tabCrypto = listaCrypto.split(",");
for (var i = 0; i<tabCrypto.length; i++) {
var symbol = tabCrypto[i];
var url='https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol='+tabCrypto[i];
var result= UrlFetchApp.fetch(url, requestOptions);
var txt= result.getContentText();
var d=JSON.parse(txt);
lista1.getRange(start_row + rankBTC, 1).setValue(d.data[symbol].name); //<-- this doesn't
lista1.getRange(start_row + rankBTC, 2).setValue(d.data.BTC.name); //<-- this line works
}
Related
This question already has an answer here:
How to create a hyperlink in Google Sheets
(1 answer)
Closed 2 months ago.
I'm using the Discogs API to export my Wantlist to Google Sheets
Is there a way to add the HTML to make the release-url (resource_url) clickable in the output?
function logTheData (url){
var sheet = SpreadsheetApp.getActiveSheet();
var url ='https://api.discogs.com/users/bartvanbelle/wants?per_page=100';
var response = UrlFetchApp.fetch(url); // get feed
var json = response.getContentText(); //
var data = JSON.parse(response);
var counter = 100;
for (var i = 0; i< counter; i++) {
var stats = [];
// var instance_id = data.wants[i].instance_id;
//if (typeof data.wants[i].basic_information.formats[0].descriptions[0] !== "undefined"){
// var description = data.wants[i].basic_information.formats[0].descriptions[0]
// };
// stats.push(instance_id);//works a
stats.push(data.wants[i].basic_information.title); //works a
stats.push(data.wants[i].basic_information.formats[0].name);
// stats.push(description); //stringify array?
stats.push(String(data.wants[i].basic_information.formats[0].descriptions));
stats.push(data.wants[i].basic_information.labels[0].name); //works c
stats.push(data.wants[i].basic_information.labels[0].catno); // work d
stats.push(data.wants[i].basic_information.year); //l
stats.push(data.wants[i].basic_information.artists[0].name); //works j
stats.push(data.wants[i].basic_information.id); // m
stats.push(data.wants[i].basic_information.resource_url); // m
Logger.log(stats);
SpreadsheetApp.getActiveSpreadsheet().appendRow(stats);
}
var pages = data.pagination.pages;
for (var a = 1; a < pages; a++){
var next = data.pagination.urls.next;
var response = UrlFetchApp.fetch(next); // get feed
var json = response.getContentText(); //
var data = JSON.parse(response);
var counter = 100;
for (var i = 0; i< counter; i++) {
var stats = [];
stats.push(data.wants[i].basic_information.title); //works a
stats.push(data.wants[i].basic_information.formats[0].name);
stats.push(String(data.wants[i].basic_information.formats[0].descriptions));
stats.push(data.wants[i].basic_information.labels[0].name); //works c
stats.push(data.wants[i].basic_information.labels[0].catno); // work d
stats.push(data.wants[i].basic_information.year); //l
// stats.push(description); //stringify array?
stats.push(data.wants[i].basic_information.artists[0].name); //works j
stats.push(data.wants[i].basic_information.id); // m
stats.push(data.wants[i].basic_information.resource_url); // m
Logger.log(stats);
SpreadsheetApp.getActiveSpreadsheet().appendRow(stats);
}
}
}
The resource URL is also formatted as http://api.discogs.com/.... Is there a way to convert that to http://www.discogs.com?
Maybe try something like:
stats.push('=HYPERLINK(data.wants[i].basic_information.resource_url,data.wants[i].basic_information.resource_url')
In general what works is to
get the cell
set the value
set the formula (HYPERLINK(...))
setShowHyperlink(true) on the cell.
Hope this helps.
You might aswell checkout this answer: https://stackoverflow.com/a/37488194/1698461
I think you need to wrap data.wants[i].basic_information.resource_url into html tag
like this :
stats.push(
'link'
);
so full code ll be :
function logTheData (url){
var sheet = SpreadsheetApp.getActiveSheet();
var url ='https://api.discogs.com/users/**********/wants?per_page=100';
var response = UrlFetchApp.fetch(url); // get feed
var json = response.getContentText(); //
var data = JSON.parse(response);
var counter = 100;
for (var i = 0; i< counter; i++) {
var stats = [];
stats.push(data.wants[i].basic_information.title); //works a
stats.push(data.wants[i].basic_information.formats[0].name);
stats.push(String(data.wants[i].basic_information.formats[0].descriptions));
stats.push(data.wants[i].basic_information.labels[0].name); //works c
stats.push(data.wants[i].basic_information.labels[0].catno); // work d
stats.push(data.wants[i].basic_information.year); //l
stats.push(data.wants[i].basic_information.artists[0].name); //works j
stats.push(data.wants[i].basic_information.id); // m
stats.push(data.wants[i].basic_information.resource_url); // m
Logger.log(stats);
SpreadsheetApp.getActiveSpreadsheet().appendRow(stats);
}
var pages = data.pagination.pages;
for (var a = 1; a < pages; a++){
var next = data.pagination.urls.next;
var response = UrlFetchApp.fetch(next); // get feed
var json = response.getContentText(); //
var data = JSON.parse(response);
var counter = 100;
for (var i = 0; i< counter; i++) {
var stats = [];
stats.push(data.wants[i].basic_information.title);
stats.push(data.wants[i].basic_information.formats[0].name);
stats.push(String(data.wants[i].basic_information.formats[0].descriptions));
stats.push(data.wants[i].basic_information.labels[0].name);
stats.push(data.wants[i].basic_information.labels[0].catno);
stats.push(data.wants[i].basic_information.year);
stats.push(data.wants[i].basic_information.artists[0].name);
stats.push(data.wants[i].basic_information.id);
stats.push( 'link');
Logger.log(stats);
SpreadsheetApp.getActiveSpreadsheet().appendRow(stats);
}
}
}
I have this code. I want to loop through the array and create a new doc for each entry. If I manually set the loop length to the number of rows it works fine. I want to set it to loop for the length of the array. However the .length property always returns null. What am I missing. I have also tried for each loops with no luck.
function createDocument()
{
//var headers = Sheets.Spreadsheets.Values.get('fileID', 'A1:Z1');
var studentHistory = Sheets.Spreadsheets.Values.get('fileID', 'A2:Z200');
var templateId = 'fileID';
var documentId;
var dstFolder = DriveApp.getFolderById('folderID');
var length = studentHistory.length;
Logger.log(studentHistory);
Logger.log(length);
//Loop through rows in sheet
for (var i = 0; i < length; i++){
//Get values from sheet row
var date = studentHistory.values[i][0];
var studentName = studentHistory.values[i][1];
var dob = studentHistory.values[i][2];
var pcDoctor = studentHistory.values[i][3];
var address = studentHistory.values[i][4];
var fgName = studentHistory.values[i][5];
var mgName = studentHistory.values[i][6];
var phoneMom = studentHistory.values[i][7];
var phoneDad = studentHistory.values[i][8];
var empMom = studentHistory.values[i][9];
var empDad = studentHistory.values[i][10];
var livesWith = studentHistory.values[i][11];
var childrenInHome = studentHistory.values[i][12];
var childrenNotInHome = studentHistory.values[i][13];
var othersInHome = studentHistory.values[i][14];
var illnesses = studentHistory.values[i][15];
var illnessDetails = studentHistory.values[i][16];
var hospitalizations = studentHistory.values[i][17];
var hospDetails = studentHistory.values[i][18];
var trauma = studentHistory.values[i][19];
var traumaDetails = studentHistory.values[i][20];
var injuries = studentHistory.values[i][21];
var injuryDetails = studentHistory.values[i][22];
var medications = studentHistory.values[i][23];
var additionalComments = studentHistory.values[i][24];
var otherSchools = studentHistory.values[i][25];
//Make a copy of the template file
documentId = DriveApp.getFileById(templateId).makeCopy(dstFolder).getId();
//Change name of newly created document
DriveApp.getFileById(documentId).setName('SocialHistory_' + studentName + '_' + date);
var body = DocumentApp.openById(documentId).getBody();
//Insert values
body.replaceText('<<date>>', date);
body.replaceText('<<studentName>>', studentName);
body.replaceText('<<dob>>', dob);
body.replaceText('<<pcDoctor>>', pcDoctor);
body.replaceText('<<address>>', address);
body.replaceText('<<fgName>>', fgName);
body.replaceText('<<mgName>>', mgName);
body.replaceText('<<phoneMom>>', phoneMom);
body.replaceText('<<phoneDad>>', phoneDad);
body.replaceText('<<empMom>>', empMom);
body.replaceText('<<empDad>>', empDad);
body.replaceText('<<livesWithe>>', livesWith);
body.replaceText('<<childrenInHome>>', childrenInHome);
body.replaceText('<<childrenNotInHome>>', childrenNotInHome);
body.replaceText('<<othersInHome>>', othersInHome);
body.replaceText('<<illnesses>>', illnesses);
body.replaceText('<<illnessDetails>>', illnessDetails);
body.replaceText('<<hospitalizations>>', hospitalizations);
body.replaceText('<<hospDetails>>', hospDetails);
body.replaceText('<<trauma>>', trauma);
body.replaceText('<<traumaDetails>>', traumaDetails);
body.replaceText('<<injuries>>', injuries);
body.replaceText('<<injuryDetails>>', injuryDetails);
body.replaceText('<<medications>>', medications);
body.replaceText('<<additionalComments>>', additionalComments);
body.replaceText('<<otherSchools>>', otherSchools);
}
}
studentHistory.values is the array.
Therefore, try this instead to get the length:
var length = studentHistory.values.length;
Solution
I see you are using Advanced Google Services to call the Sheets API. This Apps Script class allows you to call the Google APIs directly from your script handling automatically the authorization process.
However it doesn't work as the built in Classes that are available for example inside the SpreadsheetApp wrapper.
Your request will return an HTTP-like response following these specifications:
{
"range": string,
"majorDimension": enum (Dimension),
"values": [
array
]
}
You will need to parse these responses in order to achieve the desired result.
Proposed modification
function createDocument()
{
//var headers = Sheets.Spreadsheets.Values.get('fileID', 'A1:Z1');
var studentHistory = Sheets.Spreadsheets.Values.get('fileID', 'A2:Z200');
var templateId = 'fileID';
var documentId;
var dstFolder = DriveApp.getFolderById('folderID');
var length = studentHistory.values.length;
...
Reference
Google Sheets API
Advanced Google Services
I am working with a third-party API (from company called Simpli.fi) in Google Apps Script to pull some data into a spreadsheet. I am able to authenticate my API call just fine and can pull all of my required data with one URL. The issue is that the way the URL to call this API is formatted is as follows:
https://app.simpli.fi/api/organizations/{CLIENT_ID}/{SOME_ENDPOINT}
It works when I plug in one client id and one endpoint, however I do not want to pull the data individually for each client with each data endpoint.
I wish to pull data on all of my clients and also wish to access multiple endpoints, such as "/audiences" or "/campaigns". I am hoping there is a way (similar to Promises in JavaScript) that I can iterate through multiple URLs to fetch all of the data from the API.
For now, I am simply focusing on pulling all the data I want from the "/audiences" endpoint for all of my clients. I have set up an array accessing my Google Sheet that contains all the client codes and have plugged this into the URL with a for loop, which works just fine:
// iterate through all URL endpoints and client codes
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('formatting');
var range = sheet.getRange(['B2:B']).getValues();
var clients = range.filter(String);
var urlOneArray = [];
for (var i = 0; i < clients.length; i++) {
var urlOne = [baseURL + clients[i] + '/audiences'];
for (var j = 0; j < urlOne.length; j++) {
urlOneArray = urlOne[j];
Logger.log(urlOneArray);
}
}
The above logs a list of each built out URL as desired.
After pushing all of the built-out URLs into the urlOneArray, I tried calling with UrlFetchApp.fetchAll:
for (i=0; i < urlOneArray.length; i++) {
var response = UrlFetchApp.fetchAll(urlOneArray[i], params);
Utilities.sleep(500);
Logger.log(response);
}
When trying to use this method, I receive this error:
"Cannot find method fetchAll(string,object). (line 35, file "Code")"
If there is a way to iterate through multiple URLs to gather all of the data from the API in one pull, I would really appreciate some pointers.
Here is the full script:
// authenticate API call
var X_USER_KEY = 'XXXX';
var X_APP_KEY = 'XXXX';
function simplifiService() {
var baseURL = 'https://app.simpli.fi/api/organizations';
// iterate through all URL endpoints and client codes
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('formatting');
var range = sheet.getRange(['B2:B']).getValues();
var clients = range.filter(String);
var urlOneArray = [];
for (var i = 0; i < clients.length; i++) {
var urlOne = [baseURL + clients[i] + '/audiences'];
for (var j = 0; j < urlOne.length; j++) {
urlOneArray = urlOne[j];
Logger.log(urlOneArray);
}
}
var params = {
method: 'GET',
headers: {
"x-app-key": X_APP_KEY,
"x-user-key": X_USER_KEY
},
muteHttpExceptions: true
}
for (i=0; i < urlOneArray.length; i++) {
var response = UrlFetchApp.fetchAll(urlOneArray[i], params);
Utilities.sleep(500);
Logger.log(response);
}
if (response.getResponseCode() === 200) {
var data = JSON.parse(response);
Logger.log(data);
} else {
Logger.log('Error: ' + response.getResponseCode());
}
getData(data);
}
// parse out JSON data
function getData(data) {
var date = new Date();
var geoFenceId = data.audiences;
var geoFenceName = data.audiences[0].name;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Campaign Data');
//sheet.appendRow([date, geoFenceId, geoFenceName]);
}
Issue:
Invalid syntax: UrlFetchApp.fetchAll(requests Object[]) accepts object array, while you're providing a string and a object as argument.
Solution:
Valid Syntax: Create a object array for each endpoint/client and provide it as a argument to fetchAll()
Snippet:
function copyParams() {//shallow clone params object
for (var i in params) {
this[i] = params[i];
}
}
var endPoints = ['/audiences', '/campaigns'];
var requests = [];
var url, obj;
clients.forEach(function(client) {
endPoints.forEach(function(endPoint) {
obj = new copyParams();
url = baseUrl + '/' + client[0] + endPoint;
obj.url = url;
requests.push(obj);
});
});
console.log(requests);
var responseArray = UrlFetchApp.fetchAll(requests);
console.log(responseArray);
References:
UrlFetchApp.fetchAll
Array#forEach
I am reading JSON from a Google Spreadsheet and need help getting to the text within entry.content.$t. The text is a column named "description" in the spreadsheet. The feed for the spreadsheet is (removed)
So far, my script is
function listChapters(root) {
var feed = root.feed;
var entries = feed.entry || [];
var html = ['<ul>'];
for (var i = 0; i < entries.length; ++i) {
var chlist = entries[i];
var title = (chlist.title.type == 'html') ? chlist.title.$t : escape(chlist.title.$t);
var chapters = chlist.content.$t;
html.push('<li>', chapters, '</li>');
}
html.push('</ul>');
document.getElementById("chapterlist").innerHTML = html.join("");
}
The question is - How do I read "description" from $t to place in the var chapters?
The text within chlist.content.$t is almost, but not quite, properly formatted JSON. Since it's not properly formatted, you cannot use JSON.parse() to create an object that you could then get a description property from.
Here's a brute-force approach that will extract the description, used in place of the original html.push('<li>', chapters, '</li>');:
// Get the text between 'description: ' and 'Chapter website:'
var descStart = chapters.indexOf('description:')+13; //+length of 'description: '
var descEnd = chapters.indexOf('Chapter website:');
var description = chapters.substring(descStart,descEnd);
html.push('<li>', description, '</li>');
Tested with this, checking results in debugger:
function test() {
var url = '---URL---';
var result = UrlFetchApp.fetch(url);
var text = result.getContentText();
var bodytext = Xml.parse(text,true).html.body.getText();
var root = JSON.parse(bodytext);
listChapters(root);
}
I generate an html table using YUI/JavaScript. I am now trying to go through and store the information that is generated by looking at each item in the table using a for loop.
var savedata = function(){
var tabledata = Y.one("#generatedtable")._node;
var jData = [];
for (var r in tabledata.rows){
var samplerow = {};
samplerow.timestamp = r.cells[0].innerHTML;
samplerow.volts = r.cells[1].innerHTML;
samplerow.amps = r.cells[2].innerHTML;
samplerow.kW = r.cells[3].innerHTML;
samplerow.kWh = r.cells[4].innerHTML;
samplerow.sessionid = r.cells[5].innerHTML;
jData.push(samplerow);
}
};
using Chrome developer tools I can see that Y.one("#generatedtable")._node.rows gives me an HTMLcollection of [X]. This signifies the number of rows that were created by my previous function. Row[0] is just headers and I want to skip over this row. The loop fails on the
samplerow.timestamp = r.cells[0].innerHTML;
line. How should I structure this for loop to go through rows[0] to [X] to store in my JSON Data variable?
var savedata = function(){
var tabledata = Y.one("#generatedtable")._node;
var jData = [];
var i = 1;
var length = tabledata.rows.length
while (i<length){
var samplerow = {};
var r = tabledata.rows[i];
samplerow.timestamp = r.cells[0].innerHTML;
samplerow.volts = r.cells[1].innerHTML;
samplerow.amps = r.cells[2].innerHTML;
samplerow.kW = r.cells[3].innerHTML;
samplerow.kWh = r.cells[4].innerHTML;
jData.push(samplerow);
i++;
}
alert(jData);
};