import type { Person } from "@calcom/types/Calendar"; import type { JsonValue } from "@calcom/types/JsonObject"; function isObjectButNotArray(obj: unknown): obj is Record { return typeof obj === "object" && !Array.isArray(obj); } type DestinationCalendar = { id: number; integration: string; externalId: string; primaryEmail: string | null; userId: number | null; eventTypeId: number | null; credentialId: number | null; createdAt: Date | null; updatedAt: Date | null; delegationCredentialId: string | null; domainWideDelegationCredentialId: string | null; }; type Response = { label: string; value: string | boolean | string[] | { value: string; optionValue: string } | Record; isHidden?: boolean | undefined; }; interface BaseWebhookPayload { bookingId: number; title: string; eventSlug: string | null; description: string | null; customInputs: JsonValue | null; responses: Record; userFieldsResponses: Record; startTime: string; endTime: string; organizer: Person; attendees: Person[]; uid: string; location: string | null; destinationCalendar: DestinationCalendar | null; cancellationReason: string | null; iCalUID: string | null; smsReminderNumber?: string; cancelledBy: string | null; } interface CancelledEventPayload extends BaseWebhookPayload { cancelledBy: string; cancellationReason: string; } export class BookingWebhookFactory { private getType(params: BaseWebhookPayload) { return params.eventSlug || params.title || ""; } private getTitle(params: BaseWebhookPayload) { return params.title || ""; } private getDestinationCalendar(params: BaseWebhookPayload) { return params.destinationCalendar ? [params.destinationCalendar] : []; } private getCustomInputs(params: BaseWebhookPayload) { return isObjectButNotArray(params.customInputs) ? params.customInputs : undefined; } /** * Creates base webhook payload with common fields */ private createBasePayload(params: BaseWebhookPayload) { const { bookingId, title, eventSlug, description, customInputs, startTime, endTime, uid, location, organizer, attendees, responses, userFieldsResponses, destinationCalendar, smsReminderNumber, iCalUID, } = params; const basePayload = { bookingId, type: this.getType(params), title: this.getTitle(params), description, customInputs: this.getCustomInputs(params), responses, userFieldsResponses, startTime, endTime, organizer, attendees, uid, location, destinationCalendar: this.getDestinationCalendar(params), iCalUID, smsReminderNumber, }; return basePayload; } public createCancelledEventPayload(params: CancelledEventPayload) { const basePayload = this.createBasePayload({ ...params, }); return { ...basePayload, cancelledBy: params.cancelledBy, cancellationReason: params.cancellationReason, }; } }