"getCalendarById" is not defined - google-apps-script

What is wrong with my Code.gs that gives me "getCalendarById" is not defined? Also If I add CalendarApp. in front of the getCalendarById method the whole thing breaks and the URL returns nothing but a drive error.
Solution:
I do have to add CalendarApp in front of getCalendarById I read the doc wrong (doc link). In that doc under the section 'Granting Access Rights' I read -
Scripts do not request authorization if they...or if you access the script as a web app that runs under the script owner's user identity.
I was running the script under my own identity but failed to realize that the quote above meant it will not go out and get authorization, not that it still requires you to get it yourself . Many thanks to Serge insas for his great help, sticking with me and understanding.
Code.gs:
function doGet() {
return HtmlService.createHtmlOutputFromFile('index.html').setSandboxMode(HtmlService.SandboxMode.NATIVE);
}
function listEvents(dateSelected) {
var calendar = getCalendarById('en.usa#holiday#group.v.calendar.google.com').getEventsForDay(new Date(dateSelected)); // if I put calendarapp. the whole thing returns an error from the URL
Logger.log('Number of events: ' + calendar.length);
}
html:
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/themes/redmond/jquery-ui.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<div class="container" >
<div>
<h1>Welcome</h1>
<p>Please select a date below.</p>
<p>Click Here: <input type="text" name="date" id="datepicker" /><p>
</div>
</div>
<div id='test'></div>
<script>
$("#datepicker").datepicker();
$("#datepicker").on("change", function () {
var dateSelected = $(this).val()
$("#test").text(dateSelected);
google.script.run.listEvents(dateSelected);
});
</script>

getCalendarById() is a method of the calendarApp service, the correct syntax is as follows :
var calendar = CalendarApp.getCalendarById("xxxxxxxx");
See doc here

Related

There was an error during the transport or processing of this request. Error code = 10, Path = /wardeninit

I'm trying to pass an object (contents of a sheet row) to an apps script template. You can see the row in the screenshot.
my function in apps script contains:
var sendableRows = rows.filter(function (row) { //ONLY CHECKED ROWS.
return row['Index'] == true;
});
var sendableRow = sendableRows[0];
Logger.log('sendableRow '+ JSON.stringify( sendableRow));
var html = HtmlService.createTemplateFromFile('RowPopup');
html.row = JSON.stringify(sendableRow);
var h =html.evaluate();
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showModalDialog(h, 'Create Documents');
The logger statement produces:
sendableRow {"Index":true,"Timestamp":"2019-02-12T21:09:14.000Z","FROM":222222,"CONVERSATION":"THIS IS A TEST","ME":"","relativeRow":14,"absoluteRow":15}
My Rowpopup.html is :
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('forms');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function handleFormSubmit(formObject) {
// the output from form goes to processDocBuildHtml
google.script.run
.withSuccessHandler(updateUrl)
.processRowPopupHTML(formObject);
}
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = 'Sent!';
}
</script>
</head>
<body>
<form id="myForm" onsubmit="handleFormSubmit(this)">
<div>
<label for="optionList">Click me</label>
<select id="optionList" name="email">
<option>Loading...</option>
</select>
</div>
<br>
<div>
</div>
<br>
<div>
<textarea name="message" rows="10" cols="30">
The cat was playing in the garden.
</textarea>
</div>
<div id="textboxes"></div>
<div id="insert"></div>
<input type="submit" value="Submit" />
</form>
<div id="output">
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="//rawgithub.com/indrimuska/jquery-editable-select/master/dist/jquery-editable-select.min.js"></script>
<link href="//rawgithub.com/indrimuska/jquery-editable-select/master/dist/jquery-editable-select.min.css" rel="stylesheet">
<script>
function getConversations() {
var jsonRow = <?= row ?>; //PASSED IN JSON
console.log('row');
var myObj = JSON.parse(jsonRow);
console.log(myObj['CONVERSATION']);
return myObj['CONVERSATION'];
}
</script>
</body>
When I run this I see:
Which shows some issue with "warden".
Also, I don't see the expected data outputted to console in:
console.log('row');
var myObj = JSON.parse(jsonRow);
console.log(myObj['CONVERSATION']);
What am I doing wrong?
Your client side code never calls getConversations, that is why you don't see it on the console. Among many ways to do this, you could add an IIFE to call that function by adding the following on between <script> tags
(function (){getConversations()}());
By the other hand, the referred error message on the Chrome Developers Tools Console occurs even with the simplest code like the following
function myFunction(){
var html = HtmlService.createHtmlOutputFromFile('index');
SpreadsheetApp.getUi().showModalDialog(html, 'Test')
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Hello world!
</body>
</html>
So it's not you, it's Google
I know this answer is not related to this OP and the place I should post is not appropriate, but for the other people who reach this page in future, I leave an answer here because I struggled to solve similar problems.
I think this error means we cannot connect from an HTML file to the scripts written in Script Editor.
So basically you can ignore this error message(maybe. If not, tell me the correct feature.)
To me, the error has occurred when executing google.script.run.myFunction(). So, at the first, I thought the error prevents this execution. However, the error was completely unrelated to this execution. It was another problem and I detected why my issue had happened by using withFailureHandler(onFailure). It emits an error message. (See more information at https://stackoverflow.com/a/33008218/3077059)
As Mr. Rubén says "So it's not you, it's Google", this error can be replayed, easily. Please don't be puzzled by this message. The error message("There was an error during the transport or processing of this request. Error code = 10, Path = /wardeninit") is useless, I think.
Ruben's great post is this -> https://stackoverflow.com/a/54756933/3077059
You have only declared the function getConversations. It's not executed until call it ().
To execute directly on loading, try
(function getConversations(){})()
I had a similar problem. But in my case, most of my users didn't have the issue. Just some users in some PCs. Then I found out that, in these cases (about 10%), if they installed Firefox and ran the app, everything worked just fine. So that was my solution: suggest Firefox when this behavior occurred.
My solution: use versioned deployments of library scripts.
I had a similar issue where I was unable to run my own functions from the sidebar in Google Sheets. The issue seemed to be connected with using a library, even though the scripts that I was attempting to execute were not dependent on the library.
When the library was connected to the container script i couldn't get functions in the sidebar to execute. When I removed the library it all worked fine. I was using the head version of the library, meaning the most current development. I decided to try managing deployments and creating versions of the project. I added a Library deployment and version, then updated my library reference, and everything works again.
References:
Why does my apps script deployed as API executable return Permission Denied?
https://developers.google.com/apps-script/concepts/deployments
A descriptive alert from Google would be helpful.
To anyone getting this error. Try to run the code in another browser, Safari, or in guest mode.
In my case, it was probably some extension, I'm still not sure but I have already spent hours on this so I won't further investigate.

Google apps script get user input with no length limit

I want to take user input (HTML specifically) using either:
var ui = SpreadsheetApp.getUi();
var response = ui.prompt('Paste HTML below');
or
var input = Browser.inputBox('Paste HTML below', Browser.Buttons.OK_CANCEL);
These work fine for small inputs, however when copying over the entire HTML for a page of interest an error occurs (in each case). This error cannot be caught, it simply crashes the script.
Do you know why this is happening? I can't find anything in the docs that mention limits on input size.
Any experience doing this a different way?
Edit: as per a suggestion in the comments, I have tried another method (below). This also fails (with no error message) when passed large input.
First I set up Page.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Paste Sitemap Content Below
<textarea id="user-input-box" rows="4" cols="50"></textarea>
<script>
function logToConsole() {
var userInput = document.getElementById("user-input-box").value;
google.script.run.doSomething(userInput);
}
</script>
<input type="button" value="Close" onclick="logToConsole();google.script.host.close();" />
</body>
</html>
Then in file Code.gs
function testDialog() {
var html = HtmlService.createHtmlOutputFromFile('Page')
.setWidth(400)
.setHeight(300);
SpreadsheetApp.getUi()
.showModalDialog(html, 'My custom dialog');
}
function doSomething(userInput){
Logger.log(userInput);
}
I just ran into the same problem and couldn't log the error. In my case as is yours, you're calling your logToConsole() function and then directly after you're closing the dialog by using google.script.host.close();
google.script.host.close() is the problem. For some reason it can cancel the script execution - this typically happens when you're sending a lot of data back. The trick is to use a successHandler when you call your script which then calls google.script.host.close(). This way, the data transfer from the dialog finishes correctly and when you call withSuccessHandler(), that callback closes the dialog. Try this amendment to your code:
<script>
function logToConsole() {
var userInput = document.getElementById("user-input-box").value;
google.script.run.withSuccessHandler(closeDialog).doSomething(userInput);
}
function closeDialog() {
google.script.host.close();
}
</script>
<input type="button" value="Close" onclick="logToConsole()" />

Upload a file to google drive by an anonymous user

I use a Google Apps Script for that.
Code.gs
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html').setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function uploadFile(form) {
var folderId = "folder_id";
try {
var folder = DriveApp.getFolderById(folderId);
var blob = form.picToLoad;
var file = folder.createFile(blob);
return "File uploaded successfully " + file.getUrl();
} catch (error) {
Logger.log(error);
return error.toString();
}
}
form.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1 id="main-heading">Main Heading</h1>
<br/>
<div id="formDiv">
<form id="myForm">
<input name="picToLoad" type="file" /><br/>
<input type="button" value="Submit" onclick="picUploadJs(this.parentNode)" />
</form>
</div>
<div id="status" style="display: none">
Uploading. Please wait...
</div>
</body>
<script>
function picUploadJs(frmData) {
document.getElementById('status').style.display = 'inline';
google.script.run
.withSuccessHandler(updateOutput)
.uploadFile(frmData)
};
function updateOutput() {
var outputDiv = document.getElementById('status');
outputDiv.innerHTML = "The File was UPLOADED!";
}
</script>
</html>
It all works fine when I'm authenticated within my domain (I use G Suite).
However, if I'm logged into Google as another user (e.g. a normal Gmail user) or not logged at all, I still can access the page, but the script doesn't execute properly with the following error in the console:
Error
google.script.run.withSuccessHandler(...).processForm is not a function
at picUploadJs (VM84 userCodeAppPanel:9)
at HTMLInputElement.onclick (VM104 userCodeAppPanel:1)
No additional logs are shown in the Log at the level of Apps Script.
I have deployed the script as:
Execute the app as: Me (and authorised it)
Who can access the app: Anyone, even anonymous
So, I think all should work fine and anyone should be able to upload a file to my drive. Unfortunately that's not the case.
Again, this happens only when I access the script from outside of my domain.
Can anyone see what's wrong?
As it was suggested in the comments by Zig Mandel, making a copy of the script and running it solved the problem. This restarted the process of authorisation so perhaps there was something wrongly initiallised with the permissions.

Getting the "You do not have permission to call getFolderByID" error, when calling that method in HTML

I am going through the book Google Apps Scripts, 2nd Edition. The lesson I am on for creating a web app asked me to use the following code:
function doGet() {
var html = HtmlService.createTemplateFromFile('index').evaluate()
.setTitle('06 Automating Forms')
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
return html;
}
However, when I run this code I get the "You do not have permission to call getFolderById" error message. I don't understand why I am getting this error message. Also, it says the error is on line 2.
I am calling the "getFolderByID" method in my index.html file. Here is that code:
<div class="body">
<div><h2>This App will allow you to create a form from a template
in Google Docs.</h2></div>
<hr>
<div id="options">
<?var files =
DriveApp.getFolderById('0B6YzuBeNxooXSWE3Vm9WMlVnWkk').getFiles();?>
<select id='template'>
<option value="notSel">Select a Template</option>
<?while (files.hasNext()){
var file = files.next();?>
<option value="<?=file.getId()?>"><?=file.getName()?></option>
<?}?>
</select>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
</script>
<style>
.body{
padding: 10px;
}
</style>
Is there a way to get permission to call that method? I thought if I run the code a box pops up and allowing me access to that area of Drive.
Only script files have the ability to ask for authorization, html files don't.
The simplest thing to do is to add a dummy function in your code.gs file like this :
function myFunction() {
DriveApp.getFolderById('0B6YzuBeNxooXSWE3Vm9WMlVnWkk');
}
run it from the script editor and you will get the authorization request as expected.

HTMLService forms and responses

New to Google scripts. I cannot for the life of me get a Google script for forms working. The documentation is not helpful and I could not find any complete examples.
In sheets, I went to the script section. I created a basic "hello world" html. I added a function useMyForm, that will call on the script that has the form in it. After submit I cannot get the form to call the other script that has onFormSubmit.
Can someone write me a form with one entry and a call to the function that will process the data? Maybe my functions shouldn't be in separate scripts.
I write c, php, java..... this google script stuff is killing me.
Here is the sample code from the documentation, if there is something you don't understand please post your own version of the code that is not working:
https://developers.google.com/apps-script/guides/html/communication#forms
Code.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile('index')
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
}
function processForm(formObject) {
var formBlob = formObject.myFile;
var driveFile = DriveApp.createFile(formBlob);
return driveFile.getUrl();
}
index.html
<script>
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = 'Got it!';
}
</script>
<form id="myForm">
<input name="myFile" type="file" />
<input type="button" value="Submit"
onclick="google.script.run
.withSuccessHandler(updateUrl)
.processForm(this.parentNode)" />
</form>
<div id="output"></div>
The one thing that took me a while to grasp is that when you run google.script.run.withSuccessHandler(updateUrl).processForm(this.parentNode)
.processForm(variable) will run a function in the .gs file.
The return from that function (in the .gs file) gets sent to the .withSuccessHandler(updateUrl) function. Which in the example above is the "url" variable from function updateUrl(url)