2021-06-29 21:43:18 +00:00
import short from "short-uuid" ;
2021-09-22 19:52:38 +00:00
import { v5 as uuidv5 } from "uuid" ;
2021-09-23 08:49:17 +00:00
import { getIntegrationName } from "@lib/integrations" ;
import { VideoCallData } from "@lib/videoClient" ;
2021-09-22 19:52:38 +00:00
import { CalendarEvent } from "./calendarClient" ;
2021-06-29 21:43:18 +00:00
import { stripHtml } from "./emails/helpers" ;
const translator = short ( ) ;
export default class CalEventParser {
2021-07-25 17:15:31 +00:00
protected calEvent : CalendarEvent ;
2021-09-22 22:43:10 +00:00
protected maybeUid? : string ;
protected optionalVideoCallData? : VideoCallData ;
2021-06-29 21:43:18 +00:00
2021-09-22 22:43:10 +00:00
constructor ( calEvent : CalendarEvent , maybeUid? : string , optionalVideoCallData? : VideoCallData ) {
2021-06-29 21:43:18 +00:00
this . calEvent = calEvent ;
2021-07-25 17:15:31 +00:00
this . maybeUid = maybeUid ;
2021-09-22 22:43:10 +00:00
this . optionalVideoCallData = optionalVideoCallData ;
2021-06-29 21:43:18 +00:00
}
/ * *
* 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 {
2021-07-25 17:15:31 +00:00
return this . maybeUid ? ? translator . fromUUID ( uuidv5 ( JSON . stringify ( this . calEvent ) , uuidv5 . URL ) ) ;
2021-06-29 21:43:18 +00:00
}
/ * *
* Returns a footer section with links to change the event ( as HTML ) .
* /
public getChangeEventFooterHtml ( ) : string {
2021-08-05 19:49:32 +00:00
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> ` ;
2021-06-29 21:43:18 +00:00
}
/ * *
* 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 {
2021-06-29 22:31:30 +00:00
// This odd indentation is necessary because otherwise the leading tabs will be applied into the event description.
2021-06-29 21:43:18 +00:00
return (
`
2021-06-29 22:50:34 +00:00
< 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 / >
2021-06-29 22:31:30 +00:00
` +
2021-09-22 22:43:10 +00:00
( this . getLocation ( )
? ` <strong>Location:</strong><br /> ${ this . getLocation ( ) } <br />
2021-06-29 22:31:30 +00:00
`
2021-06-29 21:43:18 +00:00
: "" ) +
2021-06-29 22:50:34 +00:00
` <strong>Invitee Time Zone:</strong><br /> ${ this . calEvent . attendees [ 0 ] . timeZone } <br />
2021-09-22 22:43:10 +00:00
< strong > Additional notes : < / strong > < br / > $ { this . getDescriptionText ( ) } < br / > ` +
2021-06-29 22:11:16 +00:00
this . getChangeEventFooterHtml ( )
2021-06-29 21:43:18 +00:00
) ;
}
2021-09-22 22:43:10 +00:00
/ * *
* 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 ;
}
2021-06-29 21:43:18 +00:00
/ * *
* 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 } ;
2021-06-29 21:47:50 +00:00
eventCopy . description = this . getRichDescriptionHtml ( ) ;
2021-09-22 22:43:10 +00:00
eventCopy . location = this . getLocation ( ) ;
2021-06-29 21:43:18 +00:00
return eventCopy ;
}
2021-07-21 12:01:48 +00:00
/ * *
* Returns a calendar event with rich description as plain text .
* /
public asRichEventPlain ( ) : CalendarEvent {
const eventCopy : CalendarEvent = { . . . this . calEvent } ;
eventCopy . description = this . getRichDescription ( ) ;
2021-09-22 22:43:10 +00:00
eventCopy . location = this . getLocation ( ) ;
2021-07-21 12:01:48 +00:00
return eventCopy ;
}
2021-06-29 21:43:18 +00:00
}