Create an Event with an ID to Google Calendar: Google Script - google-apps-script

I am trying to add an event to Google Calendar, and I am not getting an event added when doing so. I am sure the code is working around it. Does anyone have any ideas why an event is not being added to the calendar?
I would add the entire code, but I feel like it misses the point.
var calendarId = "Typed Out ID of Calendar";
var calendar = CalendarApp.getCalendarById(calendarId);
calendar.createEvent('Breakfast',
new Date("April 19, 2021"));

You can use this to display your calendar ids:
function displayCalendarInfo() {
var cals=CalendarApp.getAllCalendars();
var s='Calendar Information';
for(var i=0;i<cals.length;i++)
{
s+=Utilities.formatString('<br />Name: %s Id: %s', cals[i].getName(),cals[i].getId());
}
s+='<br /><input type="button" value="Close" onClick="google.script.host.close();" />';
var ui=HtmlService.createHtmlOutput(s).setWidth(1200).setHeight(450);
SpreadsheetApp.getUi().showModelessDialog(ui, 'Calendar Data');
}
Just to make sure that you using the correct id.
Create Event: (It works)
function createEvent() {
const cal = CalendarApp.getCalendarById('id');
const start = new Date(2021,3,20,10,30,0,0);//4/20/2021 10:30:00
const end = new Date(2021,3,20,11,30,0,0);//4/20/2021 11:30:00
cal.createEvent('new event',start,end);
}
Months range from Jan - Dec which is 0 - 11 which one less than you would expect

Related

google calendar api v3 get id of last modified event

I want to script behavior when people insert event in my calendar.
(e.g. when they add something into my "focus time"). I was able to connect an appscript "trigger" to call onEventUpdate. Sadly AppScript does not give you the event id for the event that was modified... (can you confirm the API does not offer this?).
So I tried to fetch the "last updated" events instead:
function getOptions() {
var now = new Date();
var yesterday = new Date();
yesterday.setDate(now.getDate() - 1);
console.log(yesterday.toISOString())
return {
updateMin: yesterday.toISOString(),
maxResults: 2,
orderBy: 'updated',
singleEvents: true,
showDeleted: false
}
}
function onEventUpdate() {
var options = getOptions();
var calendarId = Session.getActiveUser().getEmail();
// var calendar = CalendarApp.getCalendarById(calendarId);
// console.log(calendar.getName());
var events = Calendar.Events.list(calendarId, options);
if(!events.items) return
for (var i = 0; i < events.items.length; i++) {
var event = events.items[i];
console.log(event.summary + " # " + event.start['dateTime']);
}
}
Yet, I have just modified an event, but instead I am getting events from the past (i.e. August, 2mo ago...):
5:11:21 PM Notice Execution started
5:11:21 PM Info 2022-10-29T00:11:21.826Z
5:11:22 PM Info Old Meeting # 2022-08-08T17:00:00-07:00
5:11:22 PM Info Old Meeting # 2022-08-03T14:00:00-07:00
5:11:22 PM Notice Execution completed
Thoughts?
I believe your goal is as follows.
You want to retrieve the last updated event in a Google Calendar using Google Apps Script.
In the current stage, orderBy of "Events: list" can be used with only "ascending". When I saw your script, I thought that the reason for your current issue might be due to this. If "descending" was used with orderBy, your script might be able to be used. But, in the current stage, it seems that this cannot be used.
So, in the current stage, in order to retrieve the last updated event, I thought that it is required to retrieve all events with your getOptions(), and the last element is required to be retrieved. When this is reflected in your script, how about the following modification?
Modified script:
function getOptions() {
var now = new Date();
var yesterday = new Date();
yesterday.setDate(now.getDate() - 1);
console.log(yesterday.toISOString())
return {
updatedMin: yesterday.toISOString(),
maxResults: 2500, // Modified
orderBy: 'updated',
singleEvents: true,
showDeleted: false
}
}
function onEventUpdate() {
var options = getOptions();
var calendarId = Session.getActiveUser().getEmail();
// I modified the below script.
var eventList = [];
var pageToken = null;
do {
options.pageToken = pageToken;
var events = Calendar.Events.list(calendarId, options);
if (events.items.length > 0) {
eventList = [...eventList, ...events.items];
}
pageToken = events.nextPageToken;
} while (pageToken);
var lastUpdatedEvent = eventList.pop(); // You can retrieve the last updated event.
var lastUpdatedEventId = lastUpdatedEvent.id; // You can retrieve the event ID of the last updated event.
}
Note:
About I was able to connect an appscript "trigger" to call onEventUpdate. Sadly AppScript does not give you the event id for the event that was modified, how about reporting this to the Google issue tracker as a future request?
Reference:
Events: list
Alright, I achieved what I wanted to (thanks for spotting my typo). I take some risk, as I assume there is no more than 50 edited events in the last hour (although risk could be reduced by making this delta smaller).
This is what the overly-convoluted way appscript needs (i.e. they could have just given me a calendar-event object as an argument to the trigger? oh well)
This is just a simple example, as now I can programmatically edit my calendar at will :)
function getOptions() {
var now = new Date();
TIME_DIFF = 60 * 60 * 1000;
var earlier = new Date(now.getTime() - TIME_DIFF)
return {
updatedMin: earlier.toISOString(),
maxResults: 50,
orderBy: 'updated',
singleEvents: true,
showDeleted: false
}
}
function getLastEditedEvent() {
// returns https://developers.google.com/apps-script/reference/calendar/calendar-event
var options = getOptions();
var calendarId = Session.getActiveUser().getEmail();
var events = Calendar.Events.list(calendarId, options);
if(!events.items) return undefined;
var _event = events.items[events.items.length-1];
return CalendarApp.getEventById(_event.id);
}
function onEventUpdate() {
// sadly event update contains no information
var event = getLastEditedEvent()
if(event == undefined) return;
console.log('Modifying: ' + event.getTitle() + ' # ' + event.getStartTime());
event.setColor(CalendarApp.EventColor.PALE_BLUE);
}

Apps Script getEventById() returns null

I am new to Apps Script and struggling with the "getEventById()" function.
My goal is to delete an event entry on Google Calendar via Google Sheets when you press a button.
I already managed to get the event id via Apps Script and it´s Google API V3, but when I hand it over to "getEventById" as parameter, it returns null, even when I "hardcode" the id.
Here´s my code. I removed some parts since those aren´t important I think:
function calDate(){
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
var calId = spreadsheet.getRange("N1").getValue();
var calEvent = CalendarApp.getCalendarById(calId);
var ui = SpreadsheetApp.getUi();
var selection = spreadsheet.getSelection();
var selectedRow = selection.getActiveRange().getA1Notation();
var rowRange = sheet.getRange(selectedRow);
var rowNumber = rowRange.getRow();
var colRange = sheet.getRange(selectedRow);
var colNumber = colRange.getColumn();
if (colNumber !== 15){
//wait for showtime
}
else{
// its showtime
var combinedRange = "O" + rowNumber;
var sheetData = sheet.getRange(rowNumber, 3, 1, 15).getValues();
if(sheetData[0][12] == false){
var dateStart = new Date(sheetData[0][7]);
var dateEnd = new Date(sheetData[0][8]);
var KdName = sheetData[0][0];
var BV = event_id[0][4];
var combinedNames = KdName + " - " + BV;
var items = Calendar.Events.list(calId, {
timeMin: dateStart.toISOString(),
timeMax: dateEnd.toISOString(),
q: combinedNames
}).items;
}
else{
var testVar = calEvent.getEventById(/*This is where I would put the htmlLink (the event-id)*/);
console.log(testVar);
}
}
}
Hopefully those informations are enough and if not, feel free to ask for more.
I really hope you guys can help me out!
Kind regards
EDIT & SOLUTION
Okay guys, thanks to Mateo Randwolf, who kindly opened an issue at Google about this, I was able to figure it out. This is the link with an example how to get the the ID from the event and hand that id over to the "getEventById()" function. Or here as a code-block:
function findEventID() {
var now = new Date();
var nextEvent = new Date(now.getTime() + (2 * 60 * 60 * 1000));
var event = CalendarApp.getDefaultCalendar().getEvents(now, nextEvent);
ID = event[0].getId();
Logger.log('EventID: ' + event[0].getId());
Logger.log(CalendarApp.getDefaultCalendar().getEventById(ID));
}
Now it gets funny. This line:
Logger.log('EventID: ' + event[0].getId());
returns the event-id like it should.
But this one:
Logger.log(CalendarApp.getDefaultCalendar().getEventById(ID));
doesn´t show anything except "{}", which is weird.
But if you apply "deleteEvent()" on it, like so:
calEvent.getEventById(ID).deleteEvent(); //calEvent is a CalendarApp, see above
It actually deletes the event from the calendar!
With that, I´d say we found the solution or at least a bypass.
Issue
Hi ! So it seems to me that getEventById() has a bug that returns null instead of the event object as I was getting the exact same behaviour you were reporting in this question. I have filed this behaviour to the public issue tracker, you can find it here with all the discussion on this behaviour.
I hope this has helped you. Let me know if you need anything else or if you did not understood something. :)
Using the Calendar API search query to find events in a calendar
function calDate(){
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sh=ss.getActiveSheet();
var calId=ss.getRange("N1").getValue();
var calEvent=CalendarApp.getCalendarById(calId);
var row=ss.getActiveRange().getRow();
var col=ss.getActiveRange().getColumn()
if (col!=15){
//wait for showtime
}else{
var vs=sh.getRange(row, 3, 1, 15).getValues();
if(vs[0][12] == false){
var dateStart=new Date(vs[0][7]);//col J
var dateEnd=new Date(vs[0][8]);//col K
var KdName=vs[0][0];//col 3
event_id below is not defined
var BV=event_id[0][4];//col G
var combinedNames=KdName + " - " + BV;
var items=Calendar.Events.list(calId, {timeMin: dateStart.toISOString(),timeMax: dateEnd.toISOString(),q: combinedNames}).items;
}
else{
var testVar=calEvent.getEventById(/*This is where I would put the htmlLink (the event-id)*/);
console.log(testVar);
}
}
}
Since you couldn't share your spreadsheet I share mine with an example
One thing that helps a lot is playing with the API explorer to figure what works and what doesn't. If you want to display all of the fields you can use * and this example proved very helpful as well
Here's the code:
function myOwnEventSearch() {
var calendarId='***********calendar id**************';
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Sheet235');
var sr=2;
var sc=2
var rg=sh.getRange(sr,sc,sh.getLastRow()-sr+1,sh.getLastColumn()-sc+1);
var vA=rg.getValues();
var hA=sh.getRange(sr-1,sc,1,sh.getLastColumn()-sc+1).getValues()[0];
var idx={};//locates the data index from column header names
hA.forEach(function(h,i){idx[h]=i;});
var cal=CalendarApp.getCalendarById(calendarId);
var html='<style>td,th{}</style><table><tr><th>Summary</th><th>Start</th><th>End</th><th>Id</th></tr>'
for(var i=0;i<vA.length;i++) {
if(!vA[i][idx['Id']] && vA[i][idx['DateFrom']] && vA[i][idx['DateTo']] && vA[i][idx['SearchString']]) {
var request={timeMin:new Date(vA[i][idx["DateFrom"]]).toISOString(),timeMax:new Date(vA[i][idx["DateTo"]]).toISOString(),q:vA[i][idx["SearchString"]],showDeleted: false,singleEvents:true,maxResults:10,orderBy:"startTime"};
var resp=Calendar.Events.list(calendarId, request);
if(resp.items.length>0) {
var idA=[];
resp.items.forEach(function(item,j){
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>', item.summary,item.start,item.end,item.id);
idA.push(item.id);
});
sh.getRange(i+sr,idx['Id']+sc).setValue(idA.join(', '))
}
}
}
html+='<table>';
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutput(html).setWidth(800), "My Events")
}
Here's the spreadsheet before the script runs.
Here's the dialog that displays the search results.
Here's what the spreadsheet looks like after running script:
The Event Ids were copied into the Id Column
And these were the four events I created on my calendar::
Here is how I worked around this. I stored all the events (from the range I was interested in) in a JavaScript Map() so I can find them later:
var cal = CalendarApp.getCalendarById("/* supply your calendar ID here*/");
if (!cal) {
Logger.log("Calendar not found for ID:" + calendarID);
} else {
var calEvents = cal.getEvents(new Date("March 8, 2010"), new Date("March 14, 2025"));
// Store them by eventId for easy access later
var calEventMap = new Map();
for (var j in calEvents) {
calEventMap.set(calEvents[j].getId(), calEvents[j]);
}
/* Later when you need to look up by iCalID... */
var calEvent = calEventMap.get(eventID);
}
Works for me when you get the calendar by id like this:
const calendar = CalendarApp.getCalendarById("theCalendarId");
const event = calendar.getEventById("someEventId");
Now the event is not null, but the actual event, and you can do whatever you want with it from here!

Listing Google calendar events using API

I am trying to write a Google Apps script to modify calendar events so I have modified an example to list events first. When I try debugging this it reports an error that "Calendar is not defined" on the line "events = Calendar.Events.list(calendarId, options);"
I have enabled the advanced calendar API, and am basing my script on one from the Google documentation, so I assume that one worked. Is there anything else I need to do to access the relevant objects and methods?
/*
Adapted from code in https://developers.google.com/apps-script/advanced/calendar
*/
function syncColourCode() {
var calendarId = CalendarApp.getDefaultCalendar();
var properties = PropertiesService.getUserProperties();
var fullSync = properties.getProperty('fullSync'); // sync status is stored in user properties
var options = {
maxResults: 100
};
var syncToken = properties.getProperty('syncToken'); // pointer token from last sync also stored in user properties
if (syncToken && !fullSync) { // if there is a sync token from last time and sync status has not been set to full sync
options.syncToken = syncToken; // adds the current sync token to the list of sync options
} else {
// Sync events from today onwards.
options.timeMin = new Date().toISOString(); //change to new Date().toISOString() from getRelativeDate(-1, 0).toISOString()
}
// Retrieve events one page at a time.
var events;
var pageToken;
do {
try {
options.pageToken = pageToken;
events = Calendar.Events.list(calendarId, options);
} catch (e) {
Not a google-apps expert, but from reviewing the code, I see a possible problem. At no point do I see your code checking to see if getDefaultCalendar() actually returned a valid calendar ID. Later your code uses that ID under the assumption that it is good. Have you checked the value of calendarId that is returned?
Sometimes you have to read a little deeper into the message, but I always try to start with trusting the error return. In this case "Calendar is not defined" makes me question the value of calendarId.
It seem that Google made some change so that there is no Calendar reference from the AppScript API.
Anyway to get the event you may use this API:
CalendarApp.getEvents(startTime, endTime)
https://developers.google.com/apps-script/reference/calendar/calendar-app#geteventsstarttime-endtime
Below are my example function running within google sheet.
function listEventsWithinTwoMonth(){
var calendar = CalendarApp.getDefaultCalendar();
var spreadsheet = SpreadsheetApp.getActiveSheet();
var now = new Date();
var twoMonthFromNow = new Date(now.getTime() + (24 * 60 * 60 * 30 * 4 * 1000));
var events = calendar.getEvents(now, twoMonthFromNow);
if (events.length > 0) {
// Header Rows
spreadsheet.appendRow(["#่","id","StartTime","EndTime","Title","Description"]);
for (i = 0; i < events.length; i++) {
var event = events[i];
Logger.log("" + (i+1) + event.getId() +" "+ event.getStartTime()+" "+event.getEndTime()+" "+event.getTitle()+" "+event.getDescription())
spreadsheet.appendRow([(i+1),event.getId(),event.getStartTime(),event.getEndTime(),event.getTitle(),event.getDescription()]);
}
} else {
Logger.log('No upcoming events found.');
}
}
Hope this help.
CalendarApp.getDefaultCalendar() retrieves an object of the class Calendar that has multiple properties, among others an Id.
To retrieve the calendar Id, you need to define
var calendarId = CalendarApp.getDefaultCalendar().getId();

Google Apps Script - Creating Calendar Events with Appointment Color

So I have a script that creates calendar events just fine, I am now trying to have the appointment color red without success. What is the best way to do this? Here is a portion of the code that I am currently using.
Here is the revised code that is now working!
function createCalendarEvent(eventObject) {
//Get a calendar object by opening the calendar using the
//calendar id stored in the GLOBAL variable object
//var startTime = eventObject.startDate+" "+eventObject.startTime
//var endTime = eventObject.endDate+" "+eventObject.endTime
var calendar = CalendarApp.getCalendarById(GLOBAL.calendarId),
//The title for the event that will be created
title = eventObject.eventTitle,
//The start time and date of the event that will be created
startTime1 = moment(eventObject.startDate+" "+eventObject.startTime).toDate(),
//The end time and date of the event that will be created ---moved up
APLength = eventObject.AppLength1;
//an options object containing the description and guest list
//for the event that will be created
var comboDescription = title+" in "+ eventObject.county +" is interested in a "+eventObject.deckStyle+". The referral source was "+eventObject.referral+". "+" Their email address is "+eventObject.Cemail+"."+" They can be reached at "+eventObject.phone1+" "+eventObject.phone2+" "+eventObject.Gdescription+" "+eventObject.Qdescription;
var options = {
description : comboDescription,
guests: eventObject.Cemail,
location: eventObject.location,
};
if(APLength=="1 hour") {var endTime1 = moment(eventObject.startDate+" "+eventObject.startTime).add(1, 'h').toDate()};
if(APLength=="2 hour") {var endTime1 = moment(eventObject.startDate+" "+eventObject.startTime).add(2, 'h').toDate()};
//////Send a reminder email
//MailApp.sendEmail ("-----------", "New Appointment with "+title, "I have added the following information to your calender. The appointment range is "+moment(startTime1).format("dddd, MMM Do YYYY, h:mm:ss a")+" till "+ moment(endTime1).format("dddd, MMM Do YYYY, h:mm:ss a")+" See the following appointment details....."+comboDescription);
try {
//create a calendar event with given title, start time,
//end time, and description and guests stored in an
//options argument
//calendarEvent.setColor(11);
//eventObject.colorId: 11
var event = calendar.createEvent(title, startTime1, endTime1, options)
event.setColor("11")
//var event = Calendar.Events.insert(title, startTime1, endTime1, options)
//CalendarApp.event.setColor("10")
} catch (e) {
//delete the guest property from the options variable,
//as an invalid email address with cause this method to
//throw an error.
delete options.guests
//create the event without including the guest
//var eventObject.colorId = 11
//var event = calendar.createEvent(title, startTime1, endTime1, options)
var event = calendar.createEvent(title, startTime1, endTime1, options)
event.setColor("11")
//CalendarApp.event.setColor("10")
//var event = calendarEvent.setColor(11);
//colorId: Red
}
return event;
}
Does calendarEvent.setColor not work for you?
https://developers.google.com/apps-script/reference/calendar/calendar-event#setColor(String)
In your code above, have you tried adding:
event.setColor(CalendarEvent.EventColor.RED)?

Duplicate new google calendar event to another calendar with google script

I'm trying to create a script so when I create an event in one google calendar it automatically duplicates the event in another google calendar. I have tried using the code below (swapping Calendar IDs with my own - assuming I use the full ID e.g. xyz#group.google etc):
function myFunction() {
var calendarSource = CalendarApp.getCalendarById("calendarID");
var calendarDestination = CalendarApp.getCalendarById("calendarID");
var eventToCopy = calendarSource.getEvents(new Date("July 21, 2009 EST"), new Date("July 22, 2009 EST"));
//read up: https://developers.google.com/apps-script/class_recurrence
var newRecurrence = CalendarApp.newRecurrence().addWeeklyRule().times(10);
for (var i in eventToCopy){
if (eventToCopy[i].getTitle() == "event name"){
var newEvent = calendarDestination.createEventSeries(eventToCopy[i].getTitle(), eventToCopy[i].getStartTime(), eventToCopy[i].getEndTime(), newRecurrence);
}
}
Nothing seems to happen though. Anyone give me a headstart? I only want this to trigger on creation of a NEW event.
In the code snippet you posted, events are only copied to the new calendar if their title equals "event name" due to the line if (eventToCopy[i].getTitle() == "event name"){. The events you have in your source calendar probably don't have this title, so nothing is being copied. You should be able to remove this if condition to get all events to copy.
function myFunction() {
var calendarSource = CalendarApp.getCalendarById("calendarID");
var calendarDestination = CalendarApp.getCalendarById("calendarID");
var eventToCopy = calendarSource.getEvents(new Date("July 21, 2009 EST"), new Date("July 22, 2009 EST"));
//read up: https://developers.google.com/apps-script/class_recurrence
var newRecurrence = CalendarApp.newRecurrence().addWeeklyRule().times(10);
for (var i in eventToCopy){
var newEvent = calendarDestination.createEventSeries(eventToCopy[i].getTitle(), eventToCopy[i].getStartTime(), eventToCopy[i].getEndTime(), newRecurrence);
}
}