How do I construct a link to a Google Calendar event? - google-apps-script

If I have the event ID of a Google Calendar event, for example:
4htgpmm1hmak744r0kbkdcodar#google.com
How can I construct a URL to view the event details in the Google Calendar interface?
For example, if I go to a google calendar event, I see a URL such as this:
https://calendar.google.com/calendar/r/eventedit/NGh0Z3BtbTFobWFrNzQ0cjBrYmtkY29kYXIgZXVndTlrYW4xZGRpMXBtaTZzazNpYjWoNmdAZw
What function/algorithm can I run to go from 4htgpmm1hmak744r0kbkdcodar#google.com to NGh0Z3BtbTFobWFrNzQ0cjBrYmtkY29kYXIgZXVndTlrYW4xZGRpMXBtaTZzazNpYjWoNmdAZw?
Bonus: A bonus would be if there was also a shortcut method that worked on a CalendarEvent via Google Apps Script. For example, if there was a method such as getUrl() just like there is a getId() method.

Since the same event can exist in multiple calendars (e.g. by inviting others to it), the event id is not sufficient information.
To construct a URL you need both the event id (refresher for how find it), AND the Calendar ID (see below for instructions as to how to find it). You'll then need to encode both as base64, and finally you'll you have a valid Google Calendar event link.
For the following instructions, imagine we have an event, Event1, and it exists in both calendars, CalendarA and CalendarB.
In the Google Calendar interface, you would be able to view any of these combinations:
Event1 in CalendarA
Event1 in CalendarB
Let's assign the following IDs:
Event1 ID: 4htgpmm1hmak744r0kbkdcodar#google.com
CalendarA ID: eugu9kan1ddi1pmi6sk3ib56g#group.calendar.google.com
CalendarB ID: afd3zeuguoepmi32s5i56g#group.calendar.google.com
To construct an event URL:
Get the event-id, which is the event id without the #google.com
E.g. for Event1 we have 4htgpmm1hmak744r0kbkdcodar
Get the calendar-id, which is the calendar id with the #group.calendar.google.com replaced with #g
E.g. for CalendarA we have eugu9kan1ddi1pmi6sk3ib56g#g
Join the two values with a space in the middle.
<event-id> <calendar-id>
E.g. for Event1 + CalendarA, we have:
4htgpmm1hmak744r0kbkdcodar eugu9kan1ddi1pmi6sk3ib56g#g
Encode the value as base64 (e.g. on https://www.base64decode.org):
NGh0Z3BtbTFobWFrNzQ0cjBrYmtkY29kYXIgZXVndTlrYW4xZGRpMXBtaTZzazNpYjWoNmdAZw==
Remove the training ==:
NGh0Z3BtbTFobWFrNzQ0cjBrYmtkY29kYXIgZXVndTlrYW4xZGRpMXBtaTZzazNpYjWoNmdAZw
You can now append this value to https://www.google.com/calendar/event?eid= (view event page) or https://calendar.google.com/calendar/r/eventedit/ (edit event page):
https://www.google.com/calendar/event?eid=NGh0Z3BtbTFobWFrNzQ0cjBrYmtkY29kYXIgZXVndTlrYW4xZGRpMXBtaTZzazNpYjWoNmdAZw
or
https://calendar.google.com/calendar/r/eventedit/NGh0Z3BtbTFobWFrNzQ0cjBrYmtkY29kYXIgZXVndTlrYW4xZGRpMXBtaTZzazNpYjWoNmdAZw
You're done! That URL will take you to the calendar event in the Google interface.
How to find the calendar ID
If you need instructions for how to find the calendar id...
To find the calendar ID:
Go to the calendar settings
Scroll down until you find the calendar id field.
This might be a value that ends with #group.calendar.google.com, your email address, or some other value.
If you are having trouble finding the calendar id, another tool that might help is adding the eventdeb=1 parameter to the URL, going to the Troubleshooting info of an event, and then looking for either the organizer or participant values, both of which contain calendar ids.
In Apps Script
var eventUrl = "https://www.google.com/calendar/event?eid=" +
Utilities.base64Encode(event.getId().split('#')[0] +
" " +
event.getOriginalCalendarId())
.replace(/\=/g, '');

#Senseful had was a super helpful answer, and it works!
A few important things to note adding to the above. Firstly, when base64 encoding, you'll end up with a == at the end, remove that
Second, the base calendar URL will not work when the calendar the event belongs to does not belong in the primary account the user is logged in with. For example, if you're logged into 3 accounts, you'll have a different URL for each one e.g.
https://calendar.google.com/calendar/r/...
https://calendar.google.com/calendar/b/2/r/...
https://calendar.google.com/calendar/b/3/r/...
and so on... I don't think there's a solution that'll help with this situation since it's impossible to predict what accounts a specific user is logged into at any time.

Related

Sender information in CalendarApp.CalendarEvent

I'm a bit baffled! Many of my customers send me GCal invites but the creator shows up as me. I want to extract the actual sender address from the CalendarEvent. See screen shot as an example. Kathryn is the sender but I am listed as the sender.
Sample screen shot showing different sender vs. creator
Issue:
The main name that is displayed in the UI refers to the organizer of the event, which isn't necessarily the same as the event creator (for example, the event creator might call Events: move to move the event to another calendar, changing the event's organizer - see Organizers).
Solution:
You can retrieve the event organizer if you use Calendar API (I don't think that's possible with Apps Script Calendar service, since GuestStatus doesn't seem to return OWNER in all appropriate cases, at least from my experience).
An easy way to use the API in Apps Script is to use the Advanced Calendar Service (in order to use that, you'll have to enable the advance service first).
Then, using the API you could:
Use Events.list to list the events in your desired calendar according to a time range, as you are already doing with CalendarApp.
Retrieve your desired event.
Access the field organizer of your event, which contains the organizer's email address as well as other information about this user.
Code sample:
function getOrganizer() {
const calendarId = "YOUR_CALENDAR_ID";
const optionalArgs = {
"timeMin": "2021-05-17T00:00:00-02:00", // Change accordingly, min end time to filter
"timeMax": "2021-05-19T00:00:00-02:00" // Change accordingly, max start time to filter
};
const events = Calendar.Events.list(calendarId, optionalArgs)["items"];
const event = events[0];
const organizer = event["organizer"];
console.log(organizer);
const organizerEmailAddress = organizer["email"];
console.log(organizerEmailAddress);
}

How to adjust variable to sync events from one calendar to a group calendar

I'm trying to create/modify a script where a team member can add an event in their calendar under a certain keyword. I used this script because I also needed the group calendar I'm using the script on to have vacation and OOO time auto-populated. This works fine, but my additional keywords aren't working.
I'm using the script in this link for reference: https://developers.google.com/gsuite/solutions/vacation-calendar
I've added my google group email, calendar ID, and I've added additional keywords outside of what's already set up.
I've modified my sync timeframe from 1hr to minutes.
OOO, Out of Office keywords work perfectly, but not the ones I've added.
Here's the script after the group email and calendar ID request - these two work fine, so there's not an issue with that piece of code... modified based on what I need (keywords).
Using that reference script, I've only modified the keywords section:
var KEYWORDS = ['vacation', 'ooo', 'out of office', 'offline', 'FV2'];
I expect that a user under this group email will be able to create a calendar event using any of the keywords above and that it will automatically populate onto the group calendar.
The script contains the lines
if (event.summary.toLowerCase().indexOf(keyword) < 0) {
return false;
}
This means that it sets the events retrieved from the user's calendar to lowercase and compares them against the keywords.
If your keyword is in uppercase - the script will not find the event within the keyword array.
Modification point:
Use only lowercase keywords, e.g.
var KEYWORDS = ['vacation', 'ooo', 'out of office', 'offline', 'fv2'];

CalendarApp Event ID

Using Google Apps Script, I am trying to create an Event in CalendarApp and store a Link to the event in a spreadsheet.
To create a link to the event I need to get the event ID, however using event.getID() in Google Apps Script returns the incorrect event ID.
Format for the link should be:
https://calendar.google.com/calendar/event?eid={eventID}=%7BAmerica/Chicago%7D
Event ID should look something like:
tmFmbHZydmU1aDBDZGhlYmMwaWdqcW1wZGMgdDY1HT6yhuHI5YXJwYW5lMHV2OTYzamtAZw
getID() is returning this:
065cvve58nriutnkuses332fkf#google.com
var event = CalendarApp.getCalendarById(calID).createAllDayEvent(eventName, new Date (eventDate));
var eventID = event.getId();
var eventLink = "https://www.google.com/calendar/event?eid=" + eventID + "&ctz={America/Chicago}";
Logger.log(eventLink);
Why is GAS returning the ID in this format?
According to this documentation,
getId()
Gets the ID of the calendar. The ID for a user's default calendar is
their email address.
You must have a specific id for your event.
You may check this links too:
FormResponse.getId() returns the wrong value right after the response is submitted
The id of a FormResponse when a response is submitted is different when you list all FormResponses
Based from this link, the IDs are not always the same, they are equal, apparently assigned a temporary ID until they are synchronized.
The ID that is returned is an iCalUID and is not interchangeable with the event ID used for specific events. See a related answer on StackExchange by "luc".
The iCalUID ID is used when handling events in multiple calendar systems. For using IDs only within Google Calendar, use luc's recommended method to obtain the event ID via the advanced Calendar services by listing out all events and matching against the iCalUID.
For testing purposes, you can get the event ID by navigating to Google Calendar, clicking on the event, clicking edit, and then copying the part of the URL after "https://calendar.google.com/calendar/r/eventedit/".
The id that is being returned to you is a calendar ID (065cvve58nriutnkuses332fkf#google.com)
If you double check that this matches the id for the calendar you want to create events in - go to settings and sharing for the calendar as shown in the screenshot.
Then you can use this id to call the calendar you want to work with:
calendar = CalendarApp.getCalendarById('065cvve58nriutnkuses332fkf#google.com');
then you can follow up with your original intent...
eventId = calendar.createAllDayEvent(eventName, new Date (eventDate)).getId;

Submitting value that is different to item label, Google Forms (Google Script)

I am fairly new to Google Script and I have come across an issue.
I would like to submit a different value to the label of the multiple choice option selected.
I am writing a script that generates a form to signup for any one of the events happening with in the next two weeks. These events are pulled from a calendar. For disambiguation reasons I am adding the event date to the event name before adding the array to the MulipleChoice item list.
I want to submit the Event ID rather than the newly created name as it will make the script's management of the responses so much simpler.
Hence This is what the multiple choice list would look like:
[] Event 1 20/06/14
[] Event 2 22/06/14
[] Event 3 23/06/14
[] Event 4 27/06/14
[] Event 5 29/06/14
Then If the user selects Event 2, I would like the value submitted to the responses spreadsheet to be Event 2's ID rather than "Event 2 22/06/14".
Please help me!
Maybe you could use an easier way:
Create a sheet where you store Events name and corresponding ID.
Then add a column in your answer sheet which will get the ID corresponding to the event name using either a script or ARRAYFORMULA + Vlookup
Hope this help,

Copy a programmatically created recurring event?

Using Google Apps Script, I created a calendar that has a complex recurring event. However, I'm not able to copy that event to another calendar as a recurring event. Note: the recurring rule can't be generated or edited via the web interface.
For a real example, let's say a user wants to copy the recurring event from this publicly shared Google calendar. The event is a kind of template event for a course schedule of a Thursday course at my university.
Here are two difficulties preventing the user from copying the recurring event into another calendar the user has access to:
clicking on an instance of the event and saying "copy to my calendar" only copies that single event, even though the event is defined as repeating. This is not a good solution, since the user would have to do this more than 10 times to get all the events for a semester.
clicking on an instance of the event and then "More details" , then trying to "Copy to xxxx" under the "More actions" menu (where xxxx is a calendar the user owns) appears to work. However, when clicking Save, there is an error: "An error has occurred. Please try again later."
EDIT here's a screen shot of what the Event looks like in Google Calendar (click on event, "more details").
Note that this recurring event is every Monday from the start of the semester to the end, with several exceptions. No holidays (e.g., Mon 2013-02-25), but also including Wed 2013-02-27, on which day the courses will be given as if it were a Monday (according to the university course schedule).
I repeat: the recurring events look fine in Google Calendar, but they can't be copied in there entirety to another calendar.
The GAS function that creates the calendars (not all the code is here):
function createCalendar(calendarName, courseCode, weekday, times, room, isLab) {
Logger.log("Last day: " + LAST_TRIMESTER_DATE);
// hack the last day so that it's not midnight but rather just before the next day, i.e., 23:59:59
var adjustedLastDay = LAST_TRIMESTER_DATE;
adjustedLastDay.setTime(adjustedLastDay.getTime() + (23*60*60*1000) + (59*60*1000) + (59*1000));
Logger.log("Adjusted last day: " + adjustedLastDay);
var eventRecurrence = CalendarApp.newRecurrence();
eventRecurrence.addDailyRule().until(adjustedLastDay).interval(1).onlyOnWeekday(weekday);
// get the day of the week of the first day
var weekdayOfFirstDay = Utilities.formatDate(FIRST_TRIMESTER_DATE, LONG_TIME_ZONE, "EEEE").toUpperCase();
// if this calendar is for a lab, exclude the first week of days
if (isLab) {
eventRecurrence.addDailyExclusion().times(1);
} else {
// it's a course, so exclude the first day if it's not the course day
// -- this is kind of a bug, since the "first day" of the event will always try to be created, even if it's not "onlyOnWeekday" specified
if (weekdayOfFirstDay != weekday.toString()) {
eventRecurrence.addDailyExclusion().times(1);
// eventRecurrence.addDateExclusion(FIRST_TRIMESTER_DATE);
}
}
// Exclude all holidays
for (var i = 0; i
This appears to be a bug in Google Calendar, in that it has trouble copying complex recurrence rules. You can report it to the team by using the "Send feedback" link under the gear icon in the Google Calendar interface.
The other option would be to try and export the ICA and have the user import it. You might be even able to do both with some sort of link button. Here is an example of how to obtain the ica file for a google event;
http://google.com/calendar/ical/[CALENDARID]/public[or private depending]/full/[eventID].ics
This should give the code to the user and they can manually import it into their calendars. You can generate the url and send in an email to all students who sign up for the named course.
T