diff --git a/lib/CalEventParser.ts b/lib/CalEventParser.ts
new file mode 100644
index 00000000..4668fb77
--- /dev/null
+++ b/lib/CalEventParser.ts
@@ -0,0 +1,108 @@
+import { CalendarEvent } from "./calendarClient";
+import { v5 as uuidv5 } from "uuid";
+import short from "short-uuid";
+import { stripHtml } from "./emails/helpers";
+
+const translator = short();
+
+export default class CalEventParser {
+  calEvent: CalendarEvent;
+
+  constructor(calEvent: CalendarEvent) {
+    this.calEvent = calEvent;
+  }
+
+  /**
+   * Returns a link to reschedule the given booking.
+   */
+  public getRescheduleLink(): string {
+    return process.env.BASE_URL + "/reschedule/" + this.getUid();
+  }
+
+  /**
+   * Returns a link to cancel the given booking.
+   */
+  public getCancelLink(): string {
+    return process.env.BASE_URL + "/cancel/" + this.getUid();
+  }
+
+  /**
+   * Returns a unique identifier for the given calendar event.
+   */
+  public getUid(): string {
+    return translator.fromUUID(uuidv5(JSON.stringify(this.calEvent), uuidv5.URL));
+  }
+
+  /**
+   * Returns a footer section with links to change the event (as HTML).
+   */
+  public getChangeEventFooterHtml(): string {
+    return `
+      
+      
+      Need to change this event?
+      Cancel: ${this.getCancelLink()}
+      Reschedule: ${this.getRescheduleLink()}
+    `;
+  }
+
+  /**
+   * Returns a footer section with links to change the event (as plain text).
+   */
+  public getChangeEventFooter(): string {
+    return stripHtml(this.getChangeEventFooterHtml());
+  }
+
+  /**
+   * Returns an extended description with all important information (as HTML).
+   *
+   * @protected
+   */
+  public getRichDescriptionHtml(): string {
+    return (
+      `
+