I have a simple script that pulls about 30,000 characters of JSON.
I get SyntaxError: Unexpected token: F (line 12) when I try to parse it with JSON.parse() or Utilities.jsonParse();
function refresh() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
sheet.clear();
var text = UrlFetchApp.fetch("http://blablah/json");
Logger.log(text.getContentText());
//error SyntaxError: Unexpected token: F (line 12)
json = JSON.parse(text);
)
The logger only shows about 59 lines of the JSON, but I was told that the logger has a space limit - but I'm not so sure that's it.
Running on my own server, JSON.parse parses the data just fine and so does jQuery get().
So I'm thinking UrlFetchApp.fetch() just can't get long files?
Hard to accept and I've found no documentation about it :(
You can check the UrlFetch and other services limitations on the new Apps Script dashboard. From my experience, Logger.log has a much more tighter limitation for a single log than UrlFetch, it's possible that UrlFetch is getting it fine, Logger.log is not showing it and you're running into other problem.
Try placing the getContentText result somewhere else, e.g. a spreadsheet cell. Or split it and call logger log in a for-loop.
A possible error that you might be facing (besides the quota limitation) is character encoding, getContentText has an optional parameter where you might inform the encoding of the page, have you checked that?
Related
when running my script to import .csv content from gmail it works and runs fine without any errors. But the content within the sheet is off. Strange thing is same script for other files works without problems - so I am wondering what is causing it. I checked the .csv and it is actually separated by semi colons (;) and structure wise it is exactly same as other .csvs where the script works fine. So I am really puzzled as why its not working, and it is every file from this person that I get daily that this doesnt work with.
var threads = GmailApp.search('from:xyz#gmail.com subject:xyz');
var messages = threads[0].getMessages();
var file = messages[0].getAttachments()[0];
var contents = Utilities.parseCsv(file.getDataAsString(), ";");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh0 = ss.getSheetByName("Test");
sh0.clearContents();
sh0.getRange(1, 1, contents.length, contents[0].length).setValues(contents);
This is what it looks like after the script ran successfully
Similar thing with another file in another sheet
Any help would be highly appreciated!
Kind regards
EDIT*:
Used belows formula. Unfortunately this only reduced the amount of symbols in the sheet.
(Compare it to above pictures)
If I increase the slicer to be more than the symbols I get following error:
TypeError: Cannot read property 'length' of undefined
*EDIT2:
Console log shows the same symbol as in screenshot. Here is the file: https://file.io/uh9thiY0ZKko
First as above
Removed onyl few symbols
Since I tend to ramble, first a short version and if you need more information read the long one.
TL;DR
Why is this:
function doGet(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var jobsCreated = sheet.getRange(12,2).getValue();
Browser.msgBox(jobsCreated);
var params = JSON.stringify({number:jobsCreated});
return ContentService.createTextOutput(params);
}
returning this when I published as website and then open:
{"number":""}
when it should look more like this {"number":2451}
Full Version:
First of all, I learned to program back in uni for my Computer science degree (10 years ago) but since then I haven't done much programming so I am basically a newbie.
Now to the question. I have a very simple script that a created with the script editor from Google Sheets
function doGet(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var jobsCreated = sheet.getRange(12,2).getValue();
Browser.msgBox(jobsCreated);
var params = JSON.stringify({number:jobsCreated});
return ContentService.createTextOutput(params);
}
First I get the sheet I am working on
Then I select a cell from that sheet
now if I use a msgBox to make sure that I have the right number and run the script, it works and it shows the message.
next, I format the variable as JSON and finally I just create a text output.
Now I deploy as Web app
Execute as ME
Anyone, even anonymous
And when I access the website I can only see this:
{"number":""}
If I change the code and give jobsCreated and static value it works fine
var jobsCreated = 100;
{"number":100}
So my conclusion is that the problem is with accessing the value of the cell when running the script from the published link compare to running it directly from the editor, but I have no idea how to fix this.
A little bit more information, i am trying to use this for a counter called Smiirl, i got most of the information from here
https://medium.com/#m_nebra/bootstrapping-your-company-counter-22f5d4bc7dd4
try this:
function doGet(e) {
return ContentService.createTextOutput(Utilities.formatString('number: %s',SpreadsheetApp.getActiveSheet().getRange(12,2).getValue());
}
Ok as I replied to #Aerials, thank you again for your help btw. Seeing other codes that should work not working with my script, I decided to create a new sheet and script as a test and with the exact same code it works.
But now checking on it a little bit more, something that I didn't think it was a problem since it was getting the number without any problems. The cell it's being populated by a GoogleAnalytics add-on. Now when setting up the add-on again to get the information the script from the website returns an empty value again. SO it seems the issue is with the script getting the information from the sheet (only the published version) when its being populated by the add on
Your issue is in the use of JSON.stringify
In JSON, functions are not allowed as object values.
The JSON.stringify() function will omit or change to null any functions from a JavaScript object.
That said, you can do the following:
function doGet(e){
// Get the value of the range
var sheet = SpreadsheetApp.getActiveSheet();
var jobsCreated = sheet.getRange(12,2).getValue();
// JSON Stringify it
var params = JSON.stringify({"number" : number=jobsCreated});
// Return JSON string
return ContentService.createTextOutput(params);
}
Returns:
{"number":123} if jobsCreated is the number 123, or
{"number":"Mangos"} if jobsCreated is the string "Mangos".
See it the script deployed here, and the sheet to play with.
Note:
You should avoid using functions in JSON, the functions will lose their scope, and you would have to use eval() to convert them back into functions.
Today I can't run scripts connected to a specific Google Spreadsheet which contains .next() function calls, which I use to access other Spreadsheets by name. It shows Running script Cancel Dismiss message at the top of spreadsheet until exceeding maximum execution time. The strange thing is that I have similar files for every day with exactly same scripts, and the one for yesterday works fine. I created MWE below. So, when I run it I can get the alerts for the first 2 messages, but not the 3rd one.
function test_script_hanging() {
var ui = SpreadsheetApp.getUi();
ui.alert("before getting files by name");
var getFilefile = DriveApp.getFilesByName("file");
ui.alert("after getting files by name");
var getID = getFilefile.next().getId();
ui.alert("after getting Id");
}
In some situations I notice an error message saying something like "Authorization is needed to perform this action" on the line where the .next() function is being called. I tried to revoke authorization of the file and give authorization again, but that didn't help. I tried to give full access to a given script, but couldn't google the way to do it.
Maybe I can add some more functions in my script to require full access during authorization, and maybe that will help to run my main function.
My questions are:
Why the script hangs?
How to fix this?
Can such kind of things (randomly and without any notice) happen in a free version of Google account?
This works for me:
var fldr = DriveApp.getFolderById(folderID)
var file = fldr.getFilesByName(filename);
while(file.hasNext())
{
var fi = file.next();
if(fi.getName() == filename)
{
var id=fi.getId();
}
}
I use the following timed trigger on a Google Spreadsheet. It runs every ten minutes:
function timedTriggerWatchFiles(rootFolder) {
// make an array with all the names of the childfolder
if (DriveApp.getFoldersByName(rootFolder).hasNext()) {
var childFolders = DriveApp.getFoldersByName(rootFolder).next().getFolders();
}
var childFoldersA = [];
while (childFolders.hasNext()) {
childFoldersA.push(childFolders.next().getName());
}
// run watchfiles for each child folder
for ( var i=0 ; i < childFoldersA.length ; i++) {
watchFiles(rootFolder, childFoldersA[i]);
}
}
function timedTrigger() {
timedTriggerWatchFiles("folder");
}
At least once a day I get a 'failure report' in my Inbox, saying:
We're sorry, a server error occurred. Please wait a bit
and try again. (line 242, file "Code")
The execution log gives the following message:
[14-01-22 17:29:38:363 CET] Execution failed: We're sorry,
a server error occurred. Please wait a bit and try again.
(line 242, file "Code") [37.016 seconds total runtime]
The lines are always different, but also always contain the function hasNext(). This is line 242:
while (childFolders.hasNext()) {
What am I doing wrong here? My script works as it is supposed to work. I just don't understand why I am receiving the error messages.
In the Drive SDK documentation there is a section about exponential backoff that you should check out. You could try the GASRetry library to simplify this in Apps Script.
#Greg's answer points to all the right resources for working with APIs in Google Apps Scripts.
Although it may appear that access to things like ScriptDB, DriveApp, SpreadsheetApp etc is native to Apps Scripts, in fact there are access limitations for aggressive use. The simplest of solutions is Utilities.sleep(1000);.
However, if you have a script that is running tightly within the 600 second limit, or you need to ensure that every request is made as quickly as possibly, then the resources in #Greg's answer will be of great assistance.
I get an "Unexpected Error" from the following function:
function getBomgarFeedbackXML(){
var url = "https://help.tradingtechnologies.com/api/reporting.ns?" +
"username=xxxxxx&password=xxxxxx&generate_report=SupportCustExitSurvey&" +
"start_date=2000-01-01&duration=0&report_type=rep&id=all";
var response = UrlFetchApp.fetch(url).getContentText();
Logger.log(response);
return(Xml.parse(response, true));
}
The line that causes the error is:
var response = UrlFetchApp.fetch(url).getContentText();
I am able to fetch the URL programatically using other scripting languages, such as python
I have tried fetching the URL in my browser which I was able to do successfully
I can fetch "http://www.google.com" from Google apps script successfully
I get the following warning when navigating to the URL in chrome, could this be related to the issue ?
Any help is appreciated
Thanks
The last bit with the untrusted certs is the big clue here. Seems like the SSL cert associated with 'help.tradingtechnologies.com'is not valid or signed by a trusted CA per the Google Data Centers (from where the UrlFetch calls originate).
To work around this try this line of code instead of your UrlFetch call. Note the additional option for validateHttpsCertificates documented here.
var response = UrlFetchApp.fetch(url, {'validateHttpsCertificates':false}).getContentText();