calcom/lib/CalEventParser.ts
Nico 3764a9d462
Bugfix/include zoom location (#715)
* Store video data in event location; fixed several types

* fixed malformed id

* Insert Zoom data when updating as well

* Add columns to store (video) meetings

* Store meeting data

* fixed type

* Use stored videoCallData

* Store location in field as well

* Use meta field for booking reference

* Introduced meta field in code

* Revert "Introduced meta field in code"

This reverts commit 535baccee3d87e3e793e84c4b91f8cad0e09063f.

* Revert "Use meta field for booking reference"

This reverts commit 174c252f672bcc3e461c8b3b975ac7541066d6a8.

* Linting fixes

Co-authored-by: nicolas <privat@nicolasjessen.de>
Co-authored-by: Peer_Rich <peeroke@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: Bailey Pumfleet <pumfleet@hey.com>
2021-09-22 23:43:10 +01:00

136 lines
4.2 KiB
TypeScript

import short from "short-uuid";
import { v5 as uuidv5 } from "uuid";
import { CalendarEvent } from "./calendarClient";
import { stripHtml } from "./emails/helpers";
import { VideoCallData } from "@lib/videoClient";
import { getIntegrationName } from "@lib/integrations";
const translator = short();
export default class CalEventParser {
protected calEvent: CalendarEvent;
protected maybeUid?: string;
protected optionalVideoCallData?: VideoCallData;
constructor(calEvent: CalendarEvent, maybeUid?: string, optionalVideoCallData?: VideoCallData) {
this.calEvent = calEvent;
this.maybeUid = maybeUid;
this.optionalVideoCallData = optionalVideoCallData;
}
/**
* 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 this.maybeUid ?? 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 `<p style="color: #4b5563; margin-top: 20px;">Need to make a change? <a href="${this.getCancelLink()}" style="color: #161e2e;">Cancel</a> or <a href="${this.getRescheduleLink()}" style="color: #161e2e;">reschedule</a></p>`;
}
/**
* 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 {
// This odd indentation is necessary because otherwise the leading tabs will be applied into the event description.
return (
`
<strong>Event Type:</strong><br />${this.calEvent.type}<br />
<strong>Invitee Email:</strong><br /><a href="mailto:${this.calEvent.attendees[0].email}">${this.calEvent.attendees[0].email}</a><br />
` +
(this.getLocation()
? `<strong>Location:</strong><br />${this.getLocation()}<br />
`
: "") +
`<strong>Invitee Time Zone:</strong><br />${this.calEvent.attendees[0].timeZone}<br />
<strong>Additional notes:</strong><br />${this.getDescriptionText()}<br />` +
this.getChangeEventFooterHtml()
);
}
/**
* Conditionally returns the event's location. When VideoCallData is set,
* it returns the meeting url. Otherwise, the regular location is returned.
*
* @protected
*/
protected getLocation(): string | undefined {
if (this.optionalVideoCallData) {
return this.optionalVideoCallData.url;
}
return this.calEvent.location;
}
/**
* Returns the event's description text. If VideoCallData is set, it prepends
* some video call information before the text as well.
*
* @protected
*/
protected getDescriptionText(): string | undefined {
if (this.optionalVideoCallData) {
return `
${getIntegrationName(this.optionalVideoCallData.type)} meeting
ID: ${this.optionalVideoCallData.id}
Password: ${this.optionalVideoCallData.password}
${this.calEvent.description}`;
}
return this.calEvent.description;
}
/**
* Returns an extended description with all important information (as plain text).
*
* @protected
*/
public getRichDescription(): string {
return stripHtml(this.getRichDescriptionHtml());
}
/**
* Returns a calendar event with rich description.
*/
public asRichEvent(): CalendarEvent {
const eventCopy: CalendarEvent = { ...this.calEvent };
eventCopy.description = this.getRichDescriptionHtml();
eventCopy.location = this.getLocation();
return eventCopy;
}
/**
* Returns a calendar event with rich description as plain text.
*/
public asRichEventPlain(): CalendarEvent {
const eventCopy: CalendarEvent = { ...this.calEvent };
eventCopy.description = this.getRichDescription();
eventCopy.location = this.getLocation();
return eventCopy;
}
}