Replacement needed for eventdelete function to delete google calendar event - google-apps-script

I want to delete selected calendar events but eventdelete function is now void in new scripts.
I have google script attached to a google spreadsheet which contains All Day event details. Collaborators use menus run the script to create or delete events in a google calendar.
The script loops through and selects the relevant events including its stored google calendar EventID and deletes or creates it in the google calendar. This all works fine.
I created a new google user account, new Google Calendar and new spreadsheet in a new Drive.
Having copied the Script to the new Sheet adjusting the CalendarID etc. it fails..
The EventDelete is now a Void function The error message is TypeError: CalendarApp.deleteEventSeries is not a function. Checking the list the function deleteEventSeries is now Void.
I have tested code and am able to edit description so the code is working as expected but I cannot find a function/method for deleting a google calendar event in the Calendar.
function DeleteCalendarEvents() {
var CalID = "myUserName#gmail.com"
var cal =CalendarApp.getCalendarById(CalID);
// I have removed code which loops each row in a google spreadsheet
// and selects events marked delete grabbing its stored eventID.
{
var EventID = ("The event ID eg scrambledLettersNumbers#google.com");
var event = cal.getEventSeriesById(EventID);
CalendarApp.deleteEventSeries();
}
}

I think you are confusing some fundamentals of OOP.
Is normal that your code is failing because the class CalendarApp has no function called deleteEventSeries(). You could try to find in the reference for the class.
What you want to delete is actually the object that you have retrieved by invoking the method getEventSeriesById in the Calendar object which type is CalendarEventSeries.
So to delete that Event series you will need to indeed call the method deleteEventSeries() but you need to use CalendarEventSeries object not CalendarApp.
function DeleteCalendarEvents() {
var CalID = "myUserName#gmail.com"
var cal =CalendarApp.getCalendarById(CalID);
var eventSeriesID = "<Id of the event Series>";
var eventSeries = cal.getEventSeriesById(eventSeriesID);
eventSeries.deleteEventSeries();
}
The functions are not deprecated as you have suggest in the comments. The returning type being void just means that the function will not return any variable which make sense because you have just deleted the event.
var a = eventSeries.deleteEventSeries();
>>> a == null // True

Related

Google app script to construct URL from spreadsheet values and execute it

I am basically creating a CRM upon a spreadsheet, that is being populated by a google form.
Everytime there is a new entry, I would like to notify an external server by calling a postback URL.
So URL parameters must be taken from the spreadsheet cells of the new entry (the last row), and then executed.
Something like this:
http://www.myserver.com/script.php?value1=[lastrow.cell1]&value2=[lastrow.cell2]....
Then I need to call the URL.
How would you code it?
I Guess this script can be triggered on new line creation on the spreadsheet.
You can use Installable Triggers and UrlFetchApp.fetch() to automate the process of submitting a form to your spreadsheet and then sending an HTTP request to your server containing the form's values.
This is an example of how you would do it (Adapt it to your own form's questions):
// Installable trigger function
function formSubmit(e) {
// Take values from the form submitted
var channelResp = e.namedValues["Channel"];
var question1 = e.namedValues["Question 1"];
// Get values form Parameters sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var parametersSheet = ss.getSheetByName("Parameters");
var parametersArray = parametersSheet.getRange("A2:B4").getValues();
try {
// Verify if the value in channel was well submitted and search for it
var [channel, variable] = parametersArray.find(element => element[0] == channelResp);
// Build the params with your form's answers
var params = `value1=${question1}&value2=${variable}`;
// Add the params to your url
var url = `http://www.myserver.com/script.php?${params}`;
// Make the request
UrlFetchApp.fetch(url);
} catch(e) {
// Throw an exception if the value in channel was not well-submitted
// Or there was an HTTP error
Logger.log(e);
}
}
Notice that e represents the Event Object Form Submit. Now, for setting up the installable trigger, do the following:
1) Go to your Apps Script project
2) Click Edit->Current project's triggers
3) Click "+ Add Trigger"
4) Select :
Choose which function to run -> Function Name
Select event source-> From spreadsheet
Select event type -> On form submit
5) Click Save
Restrictions
Keep in mind the Installable Trigger restrictions
Class UrlFetchApp will not work if you're executing your server as a local server because it will not be able to reach it.

Writing into another Spreadsheet with SetValue fails without errors/exceptions

I'm trying to update a spreadsheet from a script running on another spreadsheet.
Nothing seems to have any effect on the table (SetValue(), SetBackgroundRGB(), etc.).
I've checked the scope, it includes "https://www.googleapis.com/auth/spreadsheets" permission; besides, this same script has no problem writing to another spreadsheet that it creates in runtime.
function updateAnotheSpreadsheet() {
var targetSpreadsheet = SpreadsheetApp.openById('<target spreadsheet id>');
var sheet = targetSpreadsheet.getSheetByName('<sheet name>');
Browser.msgBox(sheet.getRange("A1").getValue()); // Here I see that my getSheetByName worked
sheet.getRange("A1").setValue('Test value'); // But this does nothing
}
There are no errors but also no effect: nothing changes in the target spreadsheet.
Hi I was testing and was able to do what you are trying to do. You can try to declare a variable for the message, here is what I was able to do, I hope this resolves your inquiry.
function updateAnotherSpreadsheet() {
//Opening the second Spreadsheet by ID
var targetSpreadSheet = SpreadsheetApp.openById("<SpreadSheetId>");
var sheet = targetSpreadSheet.getSheetByName("<SheetName>");
//Getting the range to show on msgBox.
var msg = sheet.getRange("A1:A1").getValue();
//Displaying old data on A1:A1 from the secondary Spreadsheet.
Browser.msgBox("Old data on secondary spreadsheet: " + msg);
//Getting the range and setting new values
sheet.getRange("A1:A1").setValue('Test value').setBackground("teal").setFontColor("white");
}
I would suggest to check for more information here https://developers.google.com/apps-script/guides/sheets.
I hope this helps, greetings.
I found the problem.
A function called from OnEdit() can't ask for permissions. I needed to first update that other spreadsheet from any function called by something "active", like a button; then, after the script asks for permission once, it can do its thing from OnEdit() the next time it runs.

Time-driven triggers scope in Google Script

UPD:
I have a published application as Spreadsheets addon and a few spreadsheets, that use this addon and execute time driven trigger:
ScriptApp.newTrigger("myFunction")
.timeBased()
.everyHours(1)
.create();
All works fine, but I'm a little confused, in what scope does this trigger work?
Since this is a published addon, the script is one and the time driven function is also one, right? As Diego said: "It works with the user scopes of the user who initiated the trigger". Okay, but what about spreadsheets?
I need to write (if trigger sees only this spreadsheet):
function myFunction(){
var ss = SpreadsheetApp.getActive();
}
Or (if it runs without binding to a specific spreadsheet):
function myFunction(){
var ss = SpreadsheetApp.openById('<some id>');
}
In other words, when I set the trigger, do I set it only for the current document or for all?
Thanks!
It works with the user scopes of the user who initiated the trigger. Here's how you can check:
Create a User property value i and set it to zero
In a new function, get the user property i, write it to a sheet, increment i and save it back to the property.
Create a trigger so that function runs every minute.
View the spreadsheet as a different user.
As the different user, repeat steps 1 & 2 to see that now i has started again from zero, but the 1-minute trigger is still iterating the original i value (because the different user can't access the first user's properties).
Here's the code:
function getAndPrintUserProperty() {
var userProperties = PropertiesService.getUserProperties();
var i = userProperties.getProperty("i");
i++;
SpreadsheetApp.getActive().getSheetByName("Sheet1").appendRow([i]);
userProperties.setProperty("i", i);
}
function addUserProperty() {
PropertiesService.getUserProperties().setProperty("i", 0);
}

How to trigger Google Apps script function based on insert row via api

I have a Google Sheet with 5 columns (First Name, Address, SKU, Quote, Status).
I have an apps script function (createQuote) which looks at the above variable's values from google sheet row and create a google document quote replacing the variables to values.
I use Zapier to insert row into my above google sheet.
What am struggling with-:
I need a way to trigger my createQuote function right when a new row is inserted via zapier (Google Sheet API call).
I tried playing with triggers but couldn't make it, any help is appreciated.
thank you
here is the code for my function-
function quoteCreator(){
docTemplate = "googledocidgoeshere"
docName = "Proposal"
var sheet = SpreadsheetApp.getActive().getSheetByName("Main")
var values = sheet.getDataRange().getValues()
var full_name = values[1][0]
var copyId = DriveApp.getFileById(docTemplate).makeCopy(docName+" for "+full_name).getId()
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document’s body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys/tags,
copyBody.replaceText("keyFullName", full_name);
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// put the link of created quote in the quote column
var url = DocumentApp.openById(copyId).getUrl()
var last = sheet.getRange(2, 7, 1, 1).setValue(url)
}
Note-: I haven't put the loop yet in above, i'll do that once it starts working as per my requirements.
Changes made via Sheets API or Apps Script do not fire onEdit triggers. I give two workarounds for this.
Web app
Have whatever process updates the sheet also send a GET or POST request to your script, deployed as a web application. As an example, a GET version might access https://script.google.com/.../exec?run=quoteCreator
function doGet(e) {
if (e.parameter.run == "quoteCreator") {
quoteCreator();
return ContentService.createTextOutput("Quote updated");
}
else {
return ContentService.createTextOutput("Unrecognized command");
}
}
The web application should be published in a way that makes it possible for your other process to do the above; usually this means "everyone, even anonymous". If security is an issue, adding a token parameter may help, e.g., the URL would have &token=myToken where myToken is a string that the webapp will check using e.parameter.token.
GET method is used for illustration here, you may find that POST makes more sense for this operation.
Important: when execution is triggered by a GET or POST request, the methods getActive... are not available. You'll need to open any spreadsheets you need using their Id or URL (see openById, openByUrl).
Timed trigger
Have a function running on time intervals (say, every 5 minutes) that checks the number of rows in the sheet and fires quoteCreator if needed. The function checkNewRows stores the number of nonempty rows in Script Properties, so changes can be detected.
function checkNewRows() {
var sp = PropertiesService.getScriptProperties();
var oldRows = sp.getProperty("rows") || 0;
var newRows = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Main").getLastRow();
if (newRows > oldRows) {
sp.setProperty("rows", newRows);
quoteCreator();
}
}

Explain purpose of `e` event parameter in onEdit

I have some question, hope guys can answer me. In this following function, I can't understand event 'e'. What is the 'e'? how we call the function or where's the function called? Give me some example, please!
function my_on_edit(e) {
var s = findSheetById_(e.gridId);
var r = e.range;
s.getRange(r.rowStart, r.columnEnd+1).setValue( s.getName() );
}
function findSheetById_(id) {
var sheets = SpreadsheetApp.getActive().getSheets();
for( var i in sheets )
if( sheets[i].getSheetId() == id )
return sheets[i];
throw 'Unable to find sheet with id: '+id;
}
Function my_on_edit is probably bound to onEdit trigger, check out Google Script triggers. List of active triggers is available in script editor in Resources menu.
On each edit action on your spreadsheet this handler is called with edit event object passed. e contain fields:
{
String user,
SpreadSheet source,
Range range,
Object value
}
You can find more detailed description at section "Spreadsheet Edit Events"
You know, I had the same question: what was that "е" in onOpen(e). I found an answer right there on Google website:
The e parameter in the function names above is an event object that is passed to the function.
https://developers.google.com/apps-script/guides/triggers.
And then they explain that the event object contains information about the context that caused the trigger to fire.