Google Spreadsheets as JSON - json

I want to know if and how is it possible to get data from specific cells of a Google spreadsheet without publishing the sheet as public using HTTP GET request to fetch data in JSON format.

I am not totally sure if this is what you are looking for, but you could just create a doGet() that returns a JSON object and then publish your project as a Webapp. Then make get requests to that URL.
function doGet() {
var cell = SpreadsheetApp
.openById('SPREADSHEET ID HERE')
.getActiveSheet()
.getRange('A1')
.getValue();
var stringified = JSON.stringify({cellValue: cell});
return ContentService.createTextOutput(stringified);
}
EDIT: You could even put in some URL parameters and make it return specific cells. Read more here.

Related

How to get the correct XPath for Google Sheets formula ImportXML

I tried to set up importXML in my Google Sheets, I used the method to copy full Xpath.
It seems not working at all.
After reading Xpath still not sure how to get the right path just for the token price.
Hope can get some idea or document to read to get the value I need.
Thanks a lot for reading this.
Wish you to have a nice day.
=IMPORTXML("https://info.osmosis.zone/token/DSM","/html/body/div[1]/div/div[3]/div/div/p")
Create a custom function by:
Opening Script Editor (Tools > Script Editor or Extensions > Apps Scripts)
And then enter the following within the script:
/**
* #return Specific value out of the value of different fields
* #customfunction
*/
function PARSEVALUE(Url,itemKey) {
var res = UrlFetchApp.fetch(Url);
var content = res.getContentText();
var jsonObject = JSON.parse(content);
return jsonObject[0][itemKey];
}
In your spreadsheet, use the function like:
=PARSEVALUE("https://api-osmosis.imperator.co/tokens/v1/DSM","price")
There are different values for different keys, as in price,symbol,name,liquidity,volume_24h e.t.c. you can grab using this function.
The page contents
You need to enable JavaScript to run this app.
JavaScript content is not supported by any IMPORT formulae. the best course of action would be to find a different source for your scrapping.
You need to use a specific url (api) which contains the json.
edit :
According to the url provided by #QHarr and if you want to retrieve all informations from url, try
function parseValues(url) {
const jsn = JSON.parse(UrlFetchApp.fetch(url).getContentText())
const headers = Object.keys(jsn[0]);
return ([headers, ...jsn.map(obj => headers.map(header => Array.isArray(obj[header]) ? obj[header].join(",") : obj[header]))]);
}
and in your sheet
=parseValues("https://api-osmosis.imperator.co/tokens/v1/DSM")

appendRow() adds blank row in google sheets (app script)

I've setup a google app script that would be triggered from an external system. This script would fetch the details from the third party system and add them to google sheet row.
function doPost(request) {
try{
var jsonString = request.postData.getDataAsString(); //get the request from KF as JSON String
setLog("\n postData*********************"+jsonString+"************************************* \n");
setLog("before the row append");
ss.appendRow([jsonString["Name"], jsonString["Age"], jsonString["Contact"]]);
setLog("After the row append");
var returnJson = '{"status": "success"}';
//used to send the return value to the calling function
setLog("/n returnJson****************************"+returnJson+"************************************* /n")
return ContentService.createTextOutput(returnJson).setMimeType(ContentService.MimeType.JSON);
}
There's absolutely no errors or warnings, but somehow it keeps adding the blank rows into the sheet.
Note: setLog() is a function where I print the values into google doc for debugging.
Maybe the reason your script is not working has to do with the value of jsonString.
I could not find any reference to request.postData.getDataAsString() inside GAS Documentation, so maybe you are trying to call a method on an object which does not support it, which would not raise an Error, but would return undefined.
One quick way to debug this would be to LOG the value (using your custom function or Logger.log(jsonString)) BEFORE you call .appendRow(). Then, you can verify if your variable has the value you expect it to have.
On the other hand, my suggestion is to use this method:
var jsonString = JSON.parse(request.postData.contents) //Gets the content of your request, then parses it
This method is present in the Documentation, and has been consistently working on all of my projects.
I think you should sort the coulmns with google app script. Write this code after ss.appendRow. The column will be sorted and all blank rows gets down.
// Sorts the sheet by the first column, ascending
ss.sort(1)
or if errors try this one also
var fl = SpreadsheetApp.getActiveSpreadsheet();
var sheet = fl.getSheets()[0];
fl.sort(1)

Google Sheet Script Returning #NAME?

I have set up a script to pull in data from a JSON API into a Google Sheet. I have set it to refresh by adding a third parameter which isn't used in the API call but is linked to a cell which another script adds the current time to. This ensures that the API is called regularly.
We are then using this Google Sheet to input data into Google Ads.
It all seems to function correctly, however, when the sheet has been closed for a while (e.g. overnight) and Google Ads tries to update from the sheet, it imports #NAME? instead of the correct API value.
I have set up another script which records the API values at regular intervals. This seems to record the values correctly, suggesting that the API calls are working whilst the sheet is closed.
// Make a POST request with a JSON payload.
// Datetime parameter isn't use in API call but is used to refresh data
function TheLottAPI(game,attribute,datetime) {
var data = {
'CompanyId': 'GoldenCasket',
'MaxDrawCount': 1,
'OptionalProductFilter': [game]};
Logger.log(data);
var options = {
'method' : 'post',
'contentType': 'application/json',
// Convert the JavaScript object to a JSON string.
'payload' : JSON.stringify(data)};
var response = UrlFetchApp.fetch('https://data.api.thelott.com/sales/vmax/web/data/lotto/opendraws', options);
Logger.log('output: '+ response);
// Convert JSON response into list
var json = JSON.parse(response)
var drawList=json ["Draws"];
// Extract attribute from list
for(var i=0;i<drawList.length;i++)
{var value=drawList[i][attribute];}
Logger.log(value)
return value;
SpreadsheetApp.flush();
};
// Set date & time to refresh API call
function RefreshTime() {
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Attributes").getRange("K4").setValue(new Date().toTimeString());
}
The correct numeric values from the API should be shown, rather than the #NAME? error.
I have checked that the API call is functioning correctly by using another script to copy the current values. The API was updating at the appropriate times overnight.
function RecordDraws() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Draw Amounts");
var source = sheet.getRange("A3:D3");
var values = source.getValues();
values[0];
sheet.appendRow(values[0]);
};
This is my guess
Google Sheets custom functions definitions are loaded when the spreadsheet is opened by using the Google Sheets UI, then formulas are calculated and as custom functions are already defined they are calculated correctly. If the spreadsheet isn't opened this way the custom functions definitions aren't loaded thus the spreadsheet doesn't know what to do with that function and returns #NAME?
If you are already running a script that updates some values, enhance that script to do the calculations that does your custom function.
Try converting this
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Attributes").getRange("K4").setValue(new Date().toTimeString());
Into this:
SpreadsheetApp.openById("id").getSheetByName("Attributes").getRange("K4").setValue(new Date().toTimeString());
Because I don't think there is an "active sheet" when the Spreadsheet it's closed or the method is called from the API.

Number object from http request returns date type or similar

I make a Facebook API call in Google scripts to get the share count for a URL. It appears that the number (e.g. 31) is being found correctly, but when I pass it to Sheets, it shows e.g. 30/01/1900 in the sheets box.
My appScript code is:
function getShareCount(url) {
var url = "https://any.org/111";
var inputurl = "https://graph.facebook.com/v2.1/?id=" + url + "&access_token=XXXXXXXX";
var response = UrlFetchApp.fetch(inputurl);
var response = JSON.parse(response.getContentText());
var response = response.share.share_count;
Utilities.sleep(500);
return response;
}
and the spreadsheet box has: "=getShareCount(B2)"
If I purposefully break the code and run the debugger in script Apps, I can see that script apps is getting a response with Number: 31. If I change to e.g. "response.id", the URL is returned into sheets as expected. The same with other parts of the object. Those are strings, and this is a number. I can't work out what sort of object sheets is receiving, nor what method I can use to simply show the number `311.
Any ideas? Thanks!
It seems that your cell has a custom format of Date. Select the cells you want to format and click Format > Number > Automatic

Send form data to Google Spreadsheet from client side

I have some form on my pure JS/HTML/CSS site (without server side). And have Google account. My purpose is send filled form from web client direct to Google Spreadsheet. Is it possible?
Yes, this is possible. I would do it by creating an Apps Script and deploying it as a web app. Here is a sample script: fill in the Id of the spreadsheet and the name of one of its sheets.
function doPost(event) {
var params = event.parameter;
var sheet = SpreadsheetApp.openById('..Id..').getSheetByName('..Name..');
if (params.data !== undefined) {
sheet.getRange(1, 1).setValue(params.data);
return ContentService.createTextOutput("Success");
}
else {
return ContentService.createTextOutput("Oops");
}
}
Publish the script as a web app, allowing access to everyone (unless you want to deal with authentification). This will give you a URL such as https://script.google.com/macros/s/..../exec
On the client side, you send POST request to that URL. The script expects data to be in parameter "data".
var url = 'https://script.google.com/macros/s/..../exec';
$.post(url, {data: 'hello world'});
(I'm using jQuery here just to have a shorter example; you can send a POST request in plain JavaScript.)
The cell A1 of the sheet you chose will have "hello world".