Copying and pasting event details from Garoon to Apple Calendar is tedious. This bookmarklet makes it easy to generate an iCal file from any open Garoon event.
Table of Contents
- Usage
- Not working? 🤔
- garoon-to-apple-bookmarklet-v0.js
- What is a Bookmarklet?
-
Code Breakdown
- Wrap the Code in an IIFE
- Get the Garoon Event Object
- Verify the Input
- Main Function - addCalendar
- Formatting the Start and End Times
- Modifying the Origin URL
- Constructing Event URL
- Initializing URL Parameters
- Formatting Event Notes
- Setting URL Parameters
- Handling All-Day Events
- Create & Open the Calendar Event URL
- Logging for Debugging
- Like the Bookmarklet?
- References
Usage
Initial Setup
- Copy the below
garoon-to-apple-bookmarklet-v0.js
code block - Enter
@bookmarks
in the Chrome's address bar - Click on the
⋮
at the top-right-corner - Click
Add new bookmark
& paste the code in the URL field
Export a Garoon Event to Apple Calendar
- Go to the Garoon event's page
- Click on the bookmarklet
- Download the generated iCal file
- Open the file and confirm that the event is now in the Apple Calendar App
Not working? 🤔
- Open the browser console
- Mac:
Command+Option+C
- Windows, Linux, Chrome OS:
Control+Shift+C
- Mac:
- Check if you are getting an error message
garoon-to-apple-bookmarklet-v0.js
javascript: (() => {
const formatTimestamp = (dateString) =>
new Date(dateString).toISOString().replaceAll(/[-:]|\.\d+/g, '');
const bodyFormat = (inputText) => inputText.replace(/\n/g, '\r');
const addCalendar = (event) => {
console.log({ event });
const start = formatTimestamp(event.start.dateTime);
const end = formatTimestamp(event.end.dateTime);
const origin = location.origin.replace(".s.", ".");
const url = `${origin}${location.pathname}?event=${event.id}`;
const params = new URLSearchParams({ service: "apple" });
const body = bodyFormat(event.notes);
params.set("start", start);
params.set("end", end);
params.set("title", event.subject);
params.set("description", body);
params.set("location", url);
params.set("timezone", event.start.timeZone);
params.set("calname", `${start}-${event.id}`);
console.log(params.toString());
open(`https://calndr.link/d/event/?${params.toString()}`);
};
const event = window.garoon?.schedule?.event?.get();
if (event === undefined) {
alert(
`Error: Not on a Garoon schedule.\nPlease open a specific Garoon event.`
);
return;
}
addCalendar(event);
})();
What is a Bookmarklet?
A bookmarklet is a small piece of JavaScript code that can be stored as a bookmark in a web browser.
When you click on it, the code runs on the current web page, making extending the browser's functionality easy.
Code Breakdown
Let's dive into the code and see how it works.
Wrap the Code in an IIFE
First, JavaScript must be specified as the language of the code.
Then, since bookmarklets are executed in the global scope, it is a good practice to wrap the code in an IIFE (Immediately Invoked Function Expression) to avoid polluting the global scope.
javascript: (() => {
// ... (code snippet)
addCalendar(event);
})();
Get the Garoon Event Object
Using the garoon.schedule.event.get()
JavaScript API, get the event object of the open Garoon event.
The window
web API makes accessing the garoon
object from the global scope possible.
const event = window.garoon?.schedule?.event?.get();
Verify the Input
Before continuing, we should verify that the event
object is not undefined
(i.e., the open page is a Garoon event page).
const event = window.garoon?.schedule?.event?.get();
if (event === undefined) {
alert(`Error: Not on a Garoon schedule.\nPlease open a specific Garoon event.`);
return;
}
Main Function - addCalendar
The function takes an event
object as an argument and performs several operations to prepare a URL. This URL, when opened, will automatically populate the fields for a new event in Apple Calendar.
Formatting the Start and End Times
Call the formatTimestamp
helper function to convert the event's start and end date-time strings into the required format.
const start = formatTimestamp(event.start.dateTime);
const end = formatTimestamp(event.end.dateTime);
The function formatTimestamp
takes the date string and formats it to ISO 8601, stripping away hyphens and colons.
const formatTimestamp = (dateString) =>
new Date(dateString).toISOString().replaceAll(/[-:]|\.\d+/g, '');
Modifying the Origin URL
Since the Client Certificate Authentication feature modifies the URL by adding a .s
between the subdomain and the domain, let's remove it before exporting.
const origin = location.origin.replace(".s.", ".");
Constructing Event URL
Generate a clean, short URL for the event by combining the origin URL and the event ID.
const url = `${origin}${location.pathname}?event=${event.id}`;
Initializing URL Parameters
Initialize a URLSearchParams
object and set the service as "apple".
const params = new URLSearchParams({ service: "apple" });
Formatting Event Notes
Call the bodyFormat
helper function to convert the event notes into a specific format.
const body = bodyFormat(event.notes);
The function takes the string and replaces all newlines with carriage returns.
const bodyFormat = (inputText) => inputText.replace(/\n/g, '\r');
Setting URL Parameters
Populate the parameters needed for the Apple Calendar event.
params.set("start", start);
params.set("end", end);
params.set("title", event.subject);
params.set("description", body);
params.set("location", url);
params.set("timezone", event.start.timeZone);
params.set("calname", `${start}-${event.id}`);
Handling All-Day Events
⚠️ Calndr returns an error when the all_day
parameter is set to true
or false
. (2024-01-17)
If the event is all-day, add an all_day
parameter with a true
value.
if (event.isAllDay) { params.set("all_day", "true"); }
Create & Open the Calendar Event URL
calndr.link is a free calendar link generator created by atymic!
Pass the parameters to Calndr's dynamic API and download the iCal file.
open(`https://calndr.link/d/event/?${params.toString()}`);
Logging for Debugging
To help with debugging, log the event
object and the params
object to the console so the input and output of the script are visible to users.
console.log({ event });
// ...
console.log(params.toString());
That is about it ~
Simple script, right? I hope you found it useful ~
Like the Bookmarklet?
Consider buying atymic a coffee for creating calndr.link