I had a syntax error with a simple code line of google sheet app scripts, I am not experienced in app scripts but this is pretty straight forward syntax from any programming language. Kindly show me if I'm missing something?
I tried changing header into 'header' or "header" but syntax error was on it not recognizing the format
function loadInformation(){
//Set up service and check access
var firebaseService = getFirebaseService();
if (firebaseService.hasAccess()) {
//Set up google sheet and header row
var ss = SpreadsheetApp.getActiveSpreadsheet();
var Sheet = ss.getSheetByName("<YOUR SHEETNAME>");
Sheet.clearContents();
Sheet.appendRow([<YOUR SHEET HEADERS>]);
//Set up reference
var databaseURL = "https://xxxxxx.firebaseio.com/";
var ref = "xxxxxx";
var requestURL = databaseURL+ref+".json";
//API Call
var response = UrlFetchApp.fetch(requestURL, {
headers: {
Authorization: 'Bearer ' + firebaseService.getAccessToken()
},
method: 'get'
});
//Parse JSON
var data = JSON.parse(response.getContentText());
//Loop through JSON and append row
for (item in data){
var newRow = [item,];
Sheet.appendRow(newRow);
}
}
} else {
//Show authorization URL to user
var authorizationUrl = firebaseService.getAuthorizationUrl();
showDialog(authorizationUrl);
}
}
Error Result :
Syntax error. (line 20, file "loadInformation") Dismiss
Your "else" is outside the function. Delete the " } " before the "else".
Also, if this line is left like this it will throw another error. Be sure to have the headers actually there:
Sheet.appendRow([<YOUR SHEET HEADERS>]);
like this:
Sheet.appendRow(["a", "b", "c"]);
Like Mark said, your 'else' is outside the function.
And if you change this
Sheet.appendRow([<YOUR SHEET HEADERS>]);
to
Sheet.appendRow(["<YOUR SHEET HEADERS>"]);
the syntax error should go away.
Related
I've mashed together a couple of functions for Google Apps Script but I'm getting a syntax error at the end. I'm a beginner and I'm not sure why Google Sheets Script editor is giving me the syntax error on the very last line.
function CheckSales() {
// Fetch the monthly sales
var monthSalesRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Day Breakdown").getRange("K35");
var monthSales = monthSalesRange.getValue();
// Check totals sales
if (monthSales > 999){
function sendEmail() {
var recipient = "myemail";
var subject = "SubjectTest";
var body = "Simple Message + monthSales variable tag here.";
MailApp.sendEmail(recipient, subject, body);
}
}
Syntax error: SyntaxError: Unexpected end of input line: 13 file: unit_notifier.gs
I'm a beginnier so I didn't know what to do or where to turn.
I tried deleting the trailing "}".
Removing part of the script.
I would appreciate learning what I did wrong and any tips on resources for the future. I'm am incredibly grateful. Thank you.
try it this way:
function checkSales() {
var monthSalesRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Day Breakdown").getRange("K35");
var monthSales = monthSalesRange.getValue();
if (monthSales > 999) {
var recipient = "myemail";
var subject = "SubjectTest";
var body = "Simple Message " + monthSales;
MailApp.sendEmail(recipient, subject, body);
}
}
If you wish to create a standalone sendEmail function then you can but you need to have some parameters to pass recipient, subject and body and the call would simply be something like sendEmail(recipient,subject,body);
It appears to be that the sendEmail function is defined but you never called it and the variable monthSales is not included in the body of the email. Try this possible approach.
function checkSales(){
// Fetch the monthly sales
var monthSalesRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Day Breakdown").getRange("K35");
var monthSales = monthSalesRange.getValue();
// Check totals sales
if (monthSales > 999){
sendEmail(monthSales);
}
}
function sendEmail(monthSales) {
var recipient = "myemail";
var subject = "SubjectTest";
var body = "Simple Message. Total sales for the month: " + monthSales;
MailApp.sendEmail(recipient, subject, body);
}
I'm trying to figure out how to send request to URL, so that it populates in Google Sheets. At this moment the log throws error "Order not found". It's my first time writing script for that request. So far I have:
function myFunction() {
var data = {
"date":"2021-07-01",
"reference":"REFERENCE",
"products":[
{
"id":"31565598851174",
"quantity":15
},
{
"id":"31424655589478",
"quantity":10
}
]
}
var options = {
'method' : 'post',
'contentType': 'application/json',
// Convert the JavaScript object to a JSON string.
'payload' : JSON.stringify(data)
};
var url = "https://stockists.rerootedorganic.co.uk/api/order/?key=example"
var response = UrlFetchApp.fetch(url, options);
Logger.log(response);
}
I think that the problem might be with the syntax in query. Any help to identify what I'm doing wrong would be amazing, thank you.
Errors:
Execution log
11:45:18 AM Notice Execution started
11:45:19 AM Info
{"error":{"message":"Order not found"}}
11:45:19 AM Info null
11:45:20 AM Info
{"error":{"message":"Order not found"}}
11:45:20 AM Info {error={message=Order not found}}
11:45:19 AM Notice Execution completed
Adapt this code
function myFunction() {
var url = 'https://stockists.rerootedorganic.co.uk/api/order/?key=example&date='
var when = '2021-07-01' // string format
var data = JSON.parse(UrlFetchApp.fetch(url+when).getContentText())
Logger.log(data.order.reference)
for (var i=0;i<data.order.products.length;i++){
Logger.log(data.order.products[i].id + ' qty: ' + data.order.products[i].quantity)
}
}
to populate the sheet
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('** Menu **')
.addItem('request','myFunction')
.addToUi();
}
function myFunction() {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var d = Utilities.formatDate(sh.getRange('B3').getValue(), "GMT+2", "yyyy-MM-dd")
var url = sh.getRange('B1').getValue() + '?key=' + sh.getRange('B2').getValue() + '&date=' + d
var data = JSON.parse(UrlFetchApp.fetch(url).getContentText())
for (var i=0;i<data.order.products.length;i++){
sh.appendRow([data.order.reference,data.order.products[i].id,data.order.products[i].quantity])
}
}
I am trying to automate the collection of statistics on Youtube videos in google spreadsheets. To do this, I use code in spreadsheets script editor with the getYoutubeViews function, as well as with the GETURL, linkURL functions, and so on.
Here is the getYoutubeViews function sample
function getYoutubeViews(videoId){
var url = "https://www.googleapis.com/youtube/v3/videos?part=statistics&id=" + videoId;
url = url + "&key=mykey";
//Utilities.sleep(Math.random(15000))
var videoListResponse = UrlFetchApp.fetch(url);
var json = JSON.parse(videoListResponse.getContentText());
return json["items"][0]["statistics"]["viewCount"];
}
function GETURL(input) {
var range = SpreadsheetApp.getActiveSheet().getRange(input);
var url = /"(.*?)"/.exec(range.getFormulaR1C1())[1];
return url;
}
I ran into two problems.
The script starts working when the user loads the table. This starts a large number of processes, since the number of videos in the table exceeds 600 pieces. This causes the error: "Service invoked too many times in a short time: exec qps".
But fixing it with Utilities.sleep does not make sense, because there is a second problem. Google’s API key quota of 10,000 points ends after 3-4 hours of work and regular table reloads.
I tried to minimize functions and actions on list, and use Utilities.sleep, to avoid this error:
Service invoked too many times in a short time: exec qps.
Try Utilities.sleep(1000) between calls. (строка 0).
But it seems that this does not help to solve the quota problem.
It seems to me that I can somehow save data in cells, activating functions only when updating data. I tried to use change triggers for these purposes, but either I did it wrong or it didn't help.
The second assumption is that it would be possible to somehow save the previous data, so that there would be some data in the cells even in case of a script error. But I do not know how this can be done.
An approach to avoid using custom functions (which will make all requests each time), is to use an onOpen() trigger to add a menu [1] that when clicked runs the getYoutubeViews() function. This function will make the request and insert the response data (views count) in the spreadsheet. It'll take the videoIds from B column (starting from 2nd row) and set the views count in D column. I put an "If" condition so that only makes the request (an update the values) for the empty views cells.
To manipulate the data on the spreadsheet I used SpreadsheetApp class [2]
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('Actions')
.addItem('Add views', 'getYoutubeViews')
.addToUi();
}
function getYoutubeViews(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet2");
var videoIdArray = sheet.getRange(2, 2, sheet.getLastRow()-1, 1).getValues();
var views = sheet.getRange(2, 4, sheet.getLastRow()-1, 1);
for(var i=0; i<videoIdArray.length ; i++) {
var videoId = videoIdArray[i][0];
var viewsCell = sheet.getRange(2 + i, 4);
if(viewsCell.getValue() == "") {
var url = "https://www.googleapis.com/youtube/v3/videos?part=statistics&id=" + videoId;
url = url + "&key=AAIzaSyAUjC5AchndLg9BRIrRBYKLuKf-fFkMC9M";
var options = {
'muteHttpExceptions' : true,
'headers': {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
}
};
var videoListResponse = UrlFetchApp.fetch(url, options);
var json = JSON.parse(videoListResponse.getContentText());
Logger.log(json)
var views = json["items"][0]["statistics"]["viewCount"];
viewsCell.setValue(views);
}
}
}
You can not run the code directly with the onEdit() function because triggers have restrictions [3], among which there's one that says:
They cannot access services that require authorization.
UrlFetchApp.fetch() is a service that requires authorization from the user.
[1] https://developers.google.com/apps-script/guides/menus
[2] https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app
[3] https://developers.google.com/apps-script/guides/triggers/#restrictions
I'm writing a script that takes google sheet data and uploads my mailchimp subscriber data, where the edited cell values are sent over as updated merge tags. The original code came from here. I've got the script running successfully, accept for this one error:
"Invalid Resource","status":400,"detail":"Blank email address"
I understand the error according to the documentation in the mailchimp api documentation, but I'm not sure why it's not recognizing the subscriber data from the script:
var emHash = md5(em.toLowerCase()); //this is pulled from my md5 function
var payload = JSON.stringify({
"status_if_new": "subscribed",
"email_address": em,
"merge_fields": {
"LEAD": lead,
//rest of vars following same syntax
}
});
var options = {
"headers" : headers,
"payload": payload,
"method" : "put",
"muteHttpExceptions" : true
};
var response = UrlFetchApp.fetch('https://us15.api.mailchimp.com/3.0' + '/lists/' + 'xxxxxxx' + '/members/' + emHash,options);
Logger.log(response);
}
Last is the function triggered by editing so that changed values get sent over via the function above
function onEdit(e) {
var activeSheet = e.source.getActiveSheet();
var range = e.range;
var rowedited = range.getRowIndex();
if (activeSheet.getName() !== "ATTENDANCE"){
return;
Logger.log("Oops :(");
}
else {
var values = sheet.getRange(rowedited, 1, 1, 13).getValues()[0];
var em = values[2];
var lead = values[1];
//remaining vars omitted for brevity
sendToMailChimp_(em,lead...[etc.]);
}
Any thoughts?
I figured it out - I pulled an amateur move and had the columns attributed to the wrong array element.... So yes, I started at 1 and not 0
facepalm
It is now working!
All the variables are returning correct values but the the urlfetch response returns 403 or 401 (access denied).
First log output:
var payload = {
"apikey": API_KEY,
"filters": {
"sendtime_start": REPORT_START_DATE,
"sendtime_end": REPORT_END_DATE
}
};
Logger.log(payload );
Second log output:
var params = {
"method": "POST", //what MC specifies
"muteHttpExceptions": true,
"payload": payload,
"limit": 100
};
Logger.log(params);
Third log output:
var apiCall = function(endpoint) {
//issue with syntax here?
var apiResponse = UrlFetchApp.fetch(automationsList, params);
var json = JSON.parse(apiResponse);
Logger.log(apiResponse);
return json;
};
Automation API Call that is not working:
var automations = apiCall(automationsList);
var automationsData = automations.data;
for (var i = 0; i < automationsData.length; i++) {
// are these response parameters? are these specific values getting pulled from MC - these are the type of values i want?
var a = automationsData[i];
var aid = a.id; // identifies unique campaign *** does this have anything to do with the call function above - it used to be as cid b/c this was for campaigns before??
var emails_sent = a.emails_sent;
var recipients = a.recipients;
var report_summary = a.report_summary;
var settings = a.settings;
if (send_time) {
var r = apiCall(reports, cid); // why does this have cid? but the other one didn't??
var emails_sent = r.emails_sent;
var opens = r.opens;
var unique_opens = r.unique_opens;
var clicks = r.clicks;
var unique_clicks = r.unique_clicks;
var open_rate = (unique_opens / emails_sent).toFixed(4);
var click_rate = (unique_clicks / emails_sent).toFixed(4);
}
The for loop is not even gets executed because I get following error for automationsData:
TypeError: Cannot read property "data" from undefined. (line 82, file "Code")
The apiResponse there is somehow not working, any help is appreciated.
The problem is in how you set up your project in the Developers Console. Try to follow again the process here for you to verify if you already do it in the correct way.
You can also check the solution here in this SO question, he/she explained it here, why he/she get the same 401 and 403 error that you get.
As it turns out, I was using v3.0 for the Mailchimp api whereas I needed to use 2.0.