I\'m creating something of a booking system which is nearly complete. Currently I\'m collecting data from a form, passing it to a sheet, and then using some of that info to
When you retrieve your event from its ID you are (most probably) using the method getEventSerieById(ID) which returns a CalendarEventSeries, not a CalendarEvent.
If you take a look at these 3 referenced docs, you'll notice that CalendarEventSeries class has no setTime()
method.
The error message you get is actually quite explicit in this case.
You should find a few posts that deal with this issue, this one for example : Create Google Calendar Events from Spreadsheet but prevent duplicates
Serge has it right - the problem is that you've retrieved a CalendarEventSeries object, not a CalendarEvent. Since the only method in the service that will look for an event by ID is getEventSeriesById(iCalId), you're kinda stuck.
One option is to use the Advanced Calendar Service instead:
var event = Calendar.Events.get(calendarId, eventId);
For new code, that's a great option, especially for developers already used to Javascript APIs. If you're a beginner or not familiar with the Advanced Services, though, you'll find that there's a steeper learning curve than for the Calendar Service.
In that case, these utilities should help you stick with the CalendarApp and its Classes and Methods, by filling the need for a getEventById()
function.
There are two versions of getEventById()
. This first one utilizes the Advanced Calendar Service, which must be enabled before use. The code is fairly straight-forward. You must provide the Calendar ID explicitly, since this isn't a Class Method. Example:
var calendarId = CalendarApp.getDefaultCalendar().getId();
var eventId = "smmd8h1dfe9lo9bip52hidnqk0";
var event = getEventById(calendarId, eventId);
Code:
/**
* Retrieve a CalendarApp CalendarEvent object from IDs.
* This version utilizes the Advanced Calendar Service, which must be
* enabled before use.
*
* @param {string} calendarId ID of calendar to be searched
* @param {string} eventId Event ID to match
*
* @returns {CalendarEvent} CalendarApp CalendarEvent object or null
*/
function getEventById(calendarId, eventId) {
// Get event by ID.
var event = Calendar.Events.get(calendarId, eventId);
// This isn't a CalendarApp CalendarEvent though, so use the info
// in the event to find it AGAIN as the right type.
// Get start & end times of event. All-day events start at start.date,
// while other events start at start.datetime. Likewise for end.
var startTime = parseDate(event.start.date||event.start.dateTime);
var endTime = parseDate(event.end.date||event.end.dateTime);
// Get array of events that fall between startTime & endTime
var calEvents = CalendarApp.getEvents(startTime, endTime);
// Search through those events, looking for a match by ID
for (var i=0; i<calEvents.length; i++) {
var curId = calEvents[i].getId().split('@')[0]; // extract id from id@calendar.google.com
if (curId == eventId) {
// Mission accomplished; we have an Event object with given id!
return calEvents[i];
}
}
// We did not find matching event
return null;
}
This version utilizes the Calendar API via UrlFetchApp, which doesn't require any special enablement. However, the code is more complex than the previous version.
/**
* Retrieve a CalendarApp CalendarEvent object from IDs.
* This version utilizes the Calendar API via UrlFetchApp, so
* requires no enablement. However, it's more complex.
*
* @param {string} calendarId ID of calendar to be searched
* @param {string} eventId Event ID to match
*
* @returns {CalendarEvent} CalendarApp CalendarEvent object or null
*/
function getEventById(calendarId, eventId) {
// Prepare a GET request to API URL, to Get event by ID.
var url = "https://www.googleapis.com/calendar/v3/calendars/calendarId/events/eventId"
.replace("calendarId",calendarId)
.replace("eventId",eventId);
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
}
// Send request
var response = UrlFetchApp.fetch(url, options);
var rc = response.getResponseCode();
var text = response.getContentText();
// If result code is 200OK, process response text
if (rc == 200) {
// The event is contained in the response text; parse it into an object
var event = JSON.parse(text);
// This isn't a CalendarApp CalendarEvent though, so use the info
// in the event to find it AGAIN as the right type.
// Get start & end times of event. All-day events start at start.date,
// while other events start at start.datetime. Likewise for end.
var startTime = parseDate(event.start.date||event.start.dateTime);
var endTime = parseDate(event.end.date||event.end.dateTime);
// Get array of events that fall between startTime & endTime
var calEvents = CalendarApp.getEvents(startTime, endTime);
// Search through those events, looking for a match by ID
for (var i=0; i<calEvents.length; i++) {
var curId = calEvents[i].getId().split('@')[0]; // extract id from id@calendar.google.com
var desc = calEvents[i].getDescription();
if (curId == eventId) {
// Mission accomplished; we have an Event object with given id!
return calEvents[i];
}
}
// We did not find matching event
return null;
}
else
// An error in fetch, anything BUT 200
throw new Error( ""+rc+JSON.parse(text).message );
}
Both versions of getEventById()
require this helper function, provided in Google's documentation.
/**
* From https://developers.google.com/apps-script/advanced/calendar#listing_events
*
* Parses an RFC 3339 date or datetime string and returns a corresponding Date
* object. This function is provided as a workaround until Apps Script properly
* supports RFC 3339 dates. For more information, see
* https://code.google.com/p/google-apps-script-issues/issues/detail?id=3860
* @param {string} string The RFC 3339 string to parse.
* @return {Date} The parsed date.
*/
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
return new Date(parts.join(' '));
}