Google scripts function to fetch curl data to Google Sheets - json

I'm trying to fetch some data to a google sheet. The code goes like this:
function ls() {
var url = "https://api.loanscan.io/v1/interest-rates?tokenFilter=BTC";
var params = {
"contentType": "application/json",
"headers":{"x-api-key": "KEY",
},
};
var json = UrlFetchApp.fetch(url, params);
var jsondata=json.getContentText();
var page = JSON.parse(jsondata);
Logger.log page
return page;
}
The Logger.log gives the correct Data, as you can see in the next link.
Log
However when I run the function in the google sheet, it returns a blank cell.
Please help, thank you.

You should write the Logger.log(page); with parentheses, because sheets is probably hanging on your Logger statement.
I don't have an API key for that site, but I do get the forbidden error response from the API when using =ls() in a cell in sheets.

Related

doPost not running for other users in google appscript

I have deployed my appscript as a form addon and as a web app both.
Everything seems to be working fine in the container form. But now I'm facing this issue where doPost function is not running as I have to run the function as other user. I tried this code from this answer, but this is also giving same authorization error.
function merry2script() {
var url = 'https://script.google.com/macros/s/AKfycbzM97wKyc0en6UrqXnVZuR9KLCf-UZAEpzfzZogbYApD9KChnnM/exec';
var payload = {payloadToSend : 'string to send'};
var method = 'post'
var headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()}
var response = UrlFetchApp.fetch(url, {method : method, payload: payload, headers: headers}).getContentText();
Logger.log(response);
return;
}
Is this the correct way to post to appscript with oauth token?
If not how can I send a post request ?
I deployed the web app with these settings
I'm getting this error
I've been stuck for 3 days any help is appreciated
Thank you
UPDATED QUESTION:
APPSCRIPT DOPOST
function doPost(e) {
var data = JSON.stringify(e);
var jsonData = JSON.parse(data);
let query = jsonData.queryString;
let params = query.split("&");
let destinationId = params[0].split("=")[1];
// code is breaking here saying "you don't have access to the document"
let ss = SpreadsheetApp.openById(destinationId);
let sheetName = ss.getActiveSheet().getSheetName();
let dataSheet = ss.getSheetByName(sheetName);
var uniqueIdCol = dataSheet.getRange("A1:A").getValues();
let rowToUpdate;
// code to update row...
}
BACKEND CODE
// call appscript to update status sheet
const data = {
comment
};
let scriptId = process.env.DEPLOYMENT_SCRIPT_ID;
const config = {
method: "post",
url: `https://script.google.com/macros/s/${scriptId}/exec?destinationId=${destinationId}&uniqueId=${uniqueId}&status=${status}`,
data,
headers: {
Authorization: `Bearer ${respondent.form.oAuthToken}`,
},
};
await axios(config);
These are the scopes which I requested to user
"https://www.googleapis.com/auth/script.container.ui",
"https://www.googleapis.com/auth/forms.currentonly",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/script.send_mail",
"https://www.googleapis.com/auth/forms",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/drive"
UPDATED QUESTION 2
I had made a script which can write to google sheet with some extra data which I send from my node backend.
So my script has doPost function which is invoked from backend. I send destinationId of the sheet to know in which sheet to write as in the code above.
I have deployed the webapp as Execute as: Me and Who has access to the app: Anyone.
I'm able to run the doPost function but not able to write to sheet.
Hope my question is clear
So after struggling for 4 days I was able to send email and write to spreadsheet with users OAuth token by directly interacting with Sheets API and Gmail API instead of doing it through ScriptApp doPost method

error "Invalid argument:" when using UrlFetchApp.fetch(url) with where date 'yyy-MM-dd'

I use this sheet and I want to get the values where the date is > to '2020-07-21',
the data source URL I used with html output is: https://docs.google.com/spreadsheets/d/1u78Qx5YIB2mektPyErz6xYtTXMLLtCapXlEpp63NTYI/gviz/tq?tqx=out:html&tq=select B where date '2020-07-21' > A &gid=0
the problem that when I se the data source URL in chrome browser, I could see the response data but when running that with the function UrlFetchApp.fetch(url) I receice an error.
the code in script editor:
function myFunction() {
var url ="https://docs.google.com/spreadsheets/d/1u78Qx5YIB2mektPyErz6xYtTXMLLtCapXlEpp63NTYI/gviz/tq?tqx=out:csv&tq=select B where date '2020-07-21' > A &gid=0"
var response = UrlFetchApp.fetch(url).getContentText();
Logger.log(response);
}
In your case, there are the following modification points.
Modification points:
Please do the URL encode for select B where date '2020-07-21' > A.
Please request to the endpoint using the access token.
In this case, because the data is retrieved, I think that the scope of https://www.googleapis.com/auth/drive.readonly can be used.
When these points are reflected to your script, it becomes as follows.
Modified script:
function myFunction() {
var query = "select B where date '2020-07-21' > A";
var url ="https://docs.google.com/spreadsheets/d/1u78Qx5YIB2mektPyErz6xYtTXMLLtCapXlEpp63NTYI/gviz/tq?tqx=out:html&tq=" + encodeURIComponent(query) + "&gid=0";
var params = {headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()}};
var response = UrlFetchApp.fetch(url, params).getContentText();
Logger.log(response);
// DriveApp.getFiles() // This line is used for automatically detecting the scope of "https://www.googleapis.com/auth/drive.readonly". So please don't remove this line.
}
When you run the script, the authorization dialog is opened. So please authorize the scopes. By this, the script is run.
Note:
If your Spreadsheet is publicly shared, I think that params is not required. At that time, you can remove // DriveApp.getFiles().
If you want to use the scope of https://www.googleapis.com/auth/drive instead of https://www.googleapis.com/auth/drive.readonly, please use // DriveApp.createFile() instead of // DriveApp.getFiles()
References:
encodeURIComponent()
Class UrlFetchApp

Google script - Delay in the function

I am running this code in sequence editor o google sheet.
I need the script to run seconds after the spreadsheet is modified.
It works but it the delay function is not taking it.
what is my error? thanks!!!
function myFunction(e) {
var url = 'https://exaple.com/?iwp=run&hash=abc123';
Utilities.sleep(10000);
var options = {
'method': 'get'
};
var response = UrlFetchApp.fetch(url, options);
Logger.log(response);
}
Im not sure about delays but you could try using triggers.It can be set to do an action after the spreadsheet has been updated.
Link:https://developers.google.com/apps-script/guides/triggers/
Link:https://courses.benlcollins.com/courses/apps-script-blastoff/lectures/8427243 (There is a example here)

Google Script UrlFetchApp.fetch returns a 404 eventhough the page exist

I am sending automated report with Google spreadsheet and Google script.
So far it was working perfectly. But somehow when I try to create a new report to be emailed, the function "UrlFetchApp.fetch" return a 404. The same situation happened when I tried copying the old report.
The line with "UrlFetchApp.fetch" give me this error:
Request failed for https://docs.google.com/spreadsheets/d/1qm_bCKn4MbLKy7AIuIeu7bTZcTk8ObYBln0GAxwfsX8/pub?gid=195635557&single=true&output=pdf returned code 404. Truncated server response
It seems that I am not the only one having the issue but I cannot find any solution to it.
Here is the code:
function emailSpreadsheetAsCSV() {
var ss = SpreadsheetApp.openById("1qm_bCKn4MbLKy7AIuIeu7bTZcTk8ObYBln0GAxwfsX8");
var url = ss.getUrl();
url = url.replace(/edit$/,'');
var token = ScriptApp.getOAuthToken();
var sheets = ss.getSheets();
//make an empty array to hold your fetched blobs
var blobs = [];
for (var i=0; i<sheets.length; i++) {
var response = UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/1qm_bCKn4MbLKy7AIuIeu7bTZcTk8ObYBln0GAxwfsX8/pub?gid=195635557&single=true&output=pdf", {
headers: {
'Authorization': 'Bearer ' + token
},
'muteHttpExceptions': false
});
//convert the response to a blob and store in our array
blobs[i] = response.getBlob().setName(sheets[i].getName() + '.csv');
}
//create new blob that is a zip file containing our blob array
var zipBlob = Utilities.zip(blobs).setName(ss.getName() + '.zip');
return blobs[0];
}
Thanks a lot for your help.
Aymeric.
I've gotten this problem too and after some research, Spence Easton (question 34573295) solved my issue. I simply added this bogus call to drive so access is granted, and so the script can now get to your file.
Add this near the top before trying to grab the url:
var bogus = DriveApp.getRootFolder();
Now it runs fine with no 404 errors.
Remove the headers from the request:
var response = UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/1qm_bCKn4MbLKy7AIuIeu7bTZcTk8ObYBln0GAxwfsX8/pub?gid=195635557&single=true&output=pdf", {
'muteHttpExceptions': false
});
Check if it works for you.
You use the "pub" url so are you sure the spreadsheet is published on the web ? If you get a 404 it means the page is not published.
If file is published the bearer is not necessary as it is public now.
After I don't really understand your code because you iterate all the sheets of your file
for (var i=0; i<sheets.length; i++)
but the param "gid" (pub?gid=195635557&single=true&output=pdf) for the url in your urlfetch is fixed ?
Second point you get the file as pdf and after you create a csv ?
Why not get the file as csv directly : https://docs.google.com/spreadsheets/export?id=TheIdOfTheFile&exportFormat=csv
By adapting this code you can get the csv directly, see : https://stackoverflow.com/a/28503601/3556215
Take care you will get the first page and not others.
Stéphane
Try with:
var response = UrlFetchApp.fetch(url, options);
var result = JSON.parse(res.getContentText());

UrlFetch from Google Sheet exportLink['application/pdf'] not returning PDF data

I create and send a periodic email as an update from a Google Sheet. For various client reasons this is done 3 ways, as a link to the Sheet, and as attachments (PDF and XLSX).
This was working 'til recently. The XSLX attachment still works, but the PDF is no longer sent as a response to a UrlFetch to the file.exportLinks('application/pdf') url. No matter what the request headers it always returns as Content-Type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Did something else undocumented change that I am missing here?
function exportAsPDF(spreadsheetId) {
spreadsheetId = spreadsheetId || 'SECRET_ID';
var file = Drive.Files.get(spreadsheetId),
url = file.exportLinks['application/pdf'];
url += '&format=pdf&size=7&fzr=true&portrait=true&fitw=true&gid=0&gridlines=false&printtitle=false&sheetnames=false&pagenum=UNDEFINED&attachment=true'
var token = ScriptApp.getOAuthToken(),
response = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
}
});
var headers = response.getAllHeaders(); // revealing content-type returned isn't pdf
var pdfBlob = response.getBlob().getAs('application/pdf');
var pdfString = pdfBlob.getDataAsString(); // this naturally throws an error
return response.getBlob(); // this returns to the send mail script
}
I'm able to get PDFs using the utility from Convert all sheets to PDF with Google Apps Script.
That working script modifies the spreadsheet's edit URL into an export URL, which looks like:
https://docs.google.com/spreadsheets/d/<%SS-ID%>/export?exportFormat=pdf...
The advanced Drive service gives an export URL formatted like:
https://docs.google.com/spreadsheets/export?id=<%SS-ID%>&exportFormat=pdf...
I'd expect the URL provided by exportLinks to be more reliable than the hack in the working script. Apparently, it's not.
This has been raised as Issue 5114. Star it to receive updates.