DEV Community

Cover image for Export a Garoon Event to Apple Calendar Bookmarklet
ahandsel
ahandsel

Posted on • Edited on • Originally published at github.com

Export a Garoon Event to Apple Calendar Bookmarklet

Bookmarklet Demo: Garoon to Apple Calendar Export

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

Initial Setup

  1. Copy the below garoon-to-apple-bookmarklet-v0.js code block
  2. Enter @bookmarks in the Chrome's address bar
  3. Click on the at the top-right-corner
  4. Click Add new bookmark & paste the code in the URL field

Export a Garoon Event to Apple Calendar

  1. Go to the Garoon event's page
  2. Click on the bookmarklet
  3. Download the generated iCal file
  4. Open the file and confirm that the event is now in the Apple Calendar App

Not working? 🤔

  1. Open the browser console
    • Mac: Command+Option+C
    • Windows, Linux, Chrome OS: Control+Shift+C
  2. 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);
})();
Enter fullscreen mode Exit fullscreen mode

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);
})();
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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, '');
Enter fullscreen mode Exit fullscreen mode

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.", ".");
Enter fullscreen mode Exit fullscreen mode

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}`;
Enter fullscreen mode Exit fullscreen mode

Initializing URL Parameters

Initialize a URLSearchParams object and set the service as "apple".

const params = new URLSearchParams({ service: "apple" });
Enter fullscreen mode Exit fullscreen mode

Formatting Event Notes

Call the bodyFormat helper function to convert the event notes into a specific format.

const body = bodyFormat(event.notes);
Enter fullscreen mode Exit fullscreen mode

The function takes the string and replaces all newlines with carriage returns.

const bodyFormat = (inputText) => inputText.replace(/\n/g, '\r');
Enter fullscreen mode Exit fullscreen mode

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}`);
Enter fullscreen mode Exit fullscreen mode

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"); }
Enter fullscreen mode Exit fullscreen mode

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()}`);
Enter fullscreen mode Exit fullscreen mode

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());
Enter fullscreen mode Exit fullscreen mode

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

References

Top comments (0)