From 91341cbba403460fac033f95003ce2e2911d4a4e Mon Sep 17 00:00:00 2001 From: Romit <85230081+romitg2@users.noreply.github.com> Date: Fri, 1 May 2026 08:11:32 +0530 Subject: [PATCH] cleanup(webhooks): remove instant meeting trigger support (#29022) * cleanup(webhooks): remove instant meeting trigger support * remove dead code * remove instant meeting from prisma enums and related cleanup * fix(webhooks): make instant meeting enum migration atomic --- .../webhooks/components/WebhookForm.tsx | 10 +---- packages/features/webhooks/lib/constants.ts | 1 - packages/features/webhooks/lib/dto/types.ts | 12 ------ .../base/BaseInstantMeetingBuilder.test.ts | 40 ------------------- .../factory/base/BaseInstantMeetingBuilder.ts | 20 ---------- .../webhooks/lib/factory/base/index.ts | 1 - .../features/webhooks/lib/factory/types.ts | 11 ----- .../versioned/PayloadBuilderFactory.test.ts | 16 -------- .../versioned/PayloadBuilderFactory.ts | 12 ------ .../lib/factory/versioned/registry.test.ts | 8 ---- .../lib/factory/versioned/registry.ts | 2 - .../v2021-10-20/InstantMeetingBuilder.ts | 30 -------------- .../factory/versioned/v2021-10-20/index.ts | 1 - .../migration.sql | 33 +++++++++++++++ packages/prisma/schema.prisma | 1 - 15 files changed, 35 insertions(+), 163 deletions(-) delete mode 100644 packages/features/webhooks/lib/factory/base/BaseInstantMeetingBuilder.test.ts delete mode 100644 packages/features/webhooks/lib/factory/base/BaseInstantMeetingBuilder.ts delete mode 100644 packages/features/webhooks/lib/factory/versioned/v2021-10-20/InstantMeetingBuilder.ts create mode 100644 packages/prisma/migrations/20260430000000_drop_instant_meeting_webhook_trigger/migration.sql diff --git a/apps/web/modules/webhooks/components/WebhookForm.tsx b/apps/web/modules/webhooks/components/WebhookForm.tsx index 1d740e387d..8b7b62bbe5 100644 --- a/apps/web/modules/webhooks/components/WebhookForm.tsx +++ b/apps/web/modules/webhooks/components/WebhookForm.tsx @@ -56,7 +56,6 @@ const WEBHOOK_TRIGGER_EVENTS_GROUPED_BY_APP_V2: Record void; onCancel?: () => void; - selectOnlyInstantMeetingOption?: boolean; headerWrapper?: ( formMethods: ReturnType>, children: React.ReactNode ) => React.ReactNode; }) => { - const { apps = [], selectOnlyInstantMeetingOption = false, overrideTriggerOptions } = props; + const { apps = [], overrideTriggerOptions } = props; const { t } = useLocale(); const webhookVariables = getWebhookVariables(t); @@ -273,11 +271,7 @@ const WebhookForm = (props: { const getEventTriggers = () => { if (props.webhook) return props.webhook.eventTriggers; - return ( - selectOnlyInstantMeetingOption - ? translatedTriggerOptions.filter((option) => option.value === WebhookTriggerEvents.INSTANT_MEETING) - : translatedTriggerOptions.filter((option) => option.value !== WebhookTriggerEvents.INSTANT_MEETING) - ).map((option) => option.value); + return translatedTriggerOptions.map((option) => option.value); }; const formMethods = useForm({ diff --git a/packages/features/webhooks/lib/constants.ts b/packages/features/webhooks/lib/constants.ts index 4f18cf51f6..c46746c9ef 100644 --- a/packages/features/webhooks/lib/constants.ts +++ b/packages/features/webhooks/lib/constants.ts @@ -54,7 +54,6 @@ export const WEBHOOK_TRIGGER_EVENTS_GROUPED_BY_APP = { WebhookTriggerEvents.BOOKING_REQUESTED, WebhookTriggerEvents.BOOKING_REJECTED, WebhookTriggerEvents.RECORDING_READY, - WebhookTriggerEvents.INSTANT_MEETING, WebhookTriggerEvents.RECORDING_TRANSCRIPTION_GENERATED, WebhookTriggerEvents.BOOKING_NO_SHOW_UPDATED, WebhookTriggerEvents.OOO_CREATED, diff --git a/packages/features/webhooks/lib/dto/types.ts b/packages/features/webhooks/lib/dto/types.ts index 09d93fd035..07fe072a01 100644 --- a/packages/features/webhooks/lib/dto/types.ts +++ b/packages/features/webhooks/lib/dto/types.ts @@ -301,17 +301,6 @@ export interface MeetingEndedDTO extends BaseEventDTO { }; } -export interface InstantMeetingDTO extends BaseEventDTO { - triggerEvent: typeof WebhookTriggerEvents.INSTANT_MEETING; - title: string; - body: string; - icon?: string; - url?: string; - actions?: { action: string; title: string; type: string; image: string | null }[]; - requireInteraction?: boolean; - type: string; -} - export interface AfterHostsNoShowDTO extends BaseEventDTO { triggerEvent: typeof WebhookTriggerEvents.AFTER_HOSTS_CAL_VIDEO_NO_SHOW; bookingId: number; @@ -350,7 +339,6 @@ export type WebhookEventDTO = | TranscriptionGeneratedDTO | MeetingStartedDTO | MeetingEndedDTO - | InstantMeetingDTO | AfterHostsNoShowDTO | AfterGuestsNoShowDTO; diff --git a/packages/features/webhooks/lib/factory/base/BaseInstantMeetingBuilder.test.ts b/packages/features/webhooks/lib/factory/base/BaseInstantMeetingBuilder.test.ts deleted file mode 100644 index e82b94041a..0000000000 --- a/packages/features/webhooks/lib/factory/base/BaseInstantMeetingBuilder.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { WebhookTriggerEvents } from "@calcom/prisma/enums"; - -import type { InstantMeetingDTO } from "../../dto/types"; -import { InstantMeetingBuilder } from "../versioned/v2021-10-20/InstantMeetingBuilder"; - -describe("InstantMeetingBuilder (v2021-10-20)", () => { - const builder = new InstantMeetingBuilder(); - - describe("INSTANT_MEETING", () => { - it("should build payload with all instant meeting fields", () => { - const dto: InstantMeetingDTO = { - triggerEvent: WebhookTriggerEvents.INSTANT_MEETING, - createdAt: "2024-01-15T10:00:00Z", - title: "Instant Meeting Request", - body: "Someone is requesting an instant meeting", - icon: "https://cal.com/icon.png", - url: "https://cal.com/meeting/instant-123", - actions: [ - { action: "accept", title: "Accept" }, - { action: "decline", title: "Decline" }, - ], - requireInteraction: true, - type: "instant", - }; - - const payload = builder.build(dto); - - expect(payload.triggerEvent).toBe(WebhookTriggerEvents.INSTANT_MEETING); - expect(payload.createdAt).toBe("2024-01-15T10:00:00Z"); - expect(payload.payload.title).toBe("Instant Meeting Request"); - expect(payload.payload.body).toBe("Someone is requesting an instant meeting"); - expect(payload.payload.icon).toBe("https://cal.com/icon.png"); - expect(payload.payload.url).toBe("https://cal.com/meeting/instant-123"); - expect(payload.payload.actions).toHaveLength(2); - expect(payload.payload.requireInteraction).toBe(true); - expect(payload.payload.type).toBe("instant"); - }); - }); -}); diff --git a/packages/features/webhooks/lib/factory/base/BaseInstantMeetingBuilder.ts b/packages/features/webhooks/lib/factory/base/BaseInstantMeetingBuilder.ts deleted file mode 100644 index 339054137c..0000000000 --- a/packages/features/webhooks/lib/factory/base/BaseInstantMeetingBuilder.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { InstantMeetingDTO } from "../../dto/types"; -import type { WebhookPayload } from "../types"; -import type { IInstantMeetingBuilder } from "../versioned/PayloadBuilderFactory"; - -/** - * Abstract base class for instant meeting payload builders. - * - * This class defines the interface that all version-specific instant meeting - * payload builders must implement. It does NOT contain any version-specific payload logic. - * - * Each webhook version should have its own concrete implementation in - * versioned/v{VERSION}/InstantMeetingBuilder.ts - */ -export abstract class BaseInstantMeetingBuilder implements IInstantMeetingBuilder { - /** - * Build the instant meeting webhook payload. - * Each version must implement this method with its specific payload structure. - */ - abstract build(dto: InstantMeetingDTO): WebhookPayload; -} diff --git a/packages/features/webhooks/lib/factory/base/index.ts b/packages/features/webhooks/lib/factory/base/index.ts index 6ed8052e90..498e7e3352 100644 --- a/packages/features/webhooks/lib/factory/base/index.ts +++ b/packages/features/webhooks/lib/factory/base/index.ts @@ -15,5 +15,4 @@ export { BaseBookingPayloadBuilder } from "./BaseBookingPayloadBuilder"; export { BaseMeetingPayloadBuilder } from "./BaseMeetingPayloadBuilder"; export { BaseRecordingPayloadBuilder } from "./BaseRecordingPayloadBuilder"; export { BaseOOOPayloadBuilder } from "./BaseOOOPayloadBuilder"; -export { BaseInstantMeetingBuilder } from "./BaseInstantMeetingBuilder"; export type { BookingExtraDataMap, BookingPayloadParams } from "./BaseBookingPayloadBuilder"; diff --git a/packages/features/webhooks/lib/factory/types.ts b/packages/features/webhooks/lib/factory/types.ts index 9e1acdb28d..f5f0453a35 100644 --- a/packages/features/webhooks/lib/factory/types.ts +++ b/packages/features/webhooks/lib/factory/types.ts @@ -63,16 +63,6 @@ export interface MeetingPayload { }[]; } -export interface InstantMeetingPayload { - title: string; - body: string; - icon?: string; - url?: string; - actions?: { action: string; title: string; type: string; image: string | null }[]; - requireInteraction?: boolean; - type: string; -} - export interface NoShowWebhookPayload { bookingId: number; webhook: { @@ -93,6 +83,5 @@ export interface WebhookPayload { | FormSubmittedPayload | RecordingPayload | MeetingPayload - | InstantMeetingPayload | NoShowWebhookPayload; } diff --git a/packages/features/webhooks/lib/factory/versioned/PayloadBuilderFactory.test.ts b/packages/features/webhooks/lib/factory/versioned/PayloadBuilderFactory.test.ts index 458bdc3e32..2d38ec3327 100644 --- a/packages/features/webhooks/lib/factory/versioned/PayloadBuilderFactory.test.ts +++ b/packages/features/webhooks/lib/factory/versioned/PayloadBuilderFactory.test.ts @@ -16,7 +16,6 @@ describe("PayloadBuilderFactory", () => { ooo: new V2021_10_20.OOOPayloadBuilder(), recording: new V2021_10_20.RecordingPayloadBuilder(), meeting: new V2021_10_20.MeetingPayloadBuilder(), - instantMeeting: new V2021_10_20.InstantMeetingBuilder(), }; factory = new PayloadBuilderFactory(WebhookVersionEnum.V_2021_10_20, defaultBuilders); @@ -42,7 +41,6 @@ describe("PayloadBuilderFactory", () => { ooo: new V2021_10_20.OOOPayloadBuilder(), recording: new V2021_10_20.RecordingPayloadBuilder(), meeting: new V2021_10_20.MeetingPayloadBuilder(), - instantMeeting: new V2021_10_20.InstantMeetingBuilder(), }; factory.registerVersion("2024-12-01", newVersionBuilders); @@ -57,7 +55,6 @@ describe("PayloadBuilderFactory", () => { ooo: new V2021_10_20.OOOPayloadBuilder(), recording: new V2021_10_20.RecordingPayloadBuilder(), meeting: new V2021_10_20.MeetingPayloadBuilder(), - instantMeeting: new V2021_10_20.InstantMeetingBuilder(), }; factory.registerVersion(WebhookVersionEnum.V_2021_10_20, newBuilders); @@ -111,13 +108,6 @@ describe("PayloadBuilderFactory", () => { }); }); - it("should route instant meeting events to instant meeting builder", () => { - const builder = factory.getBuilder( - WebhookVersionEnum.V_2021_10_20, - WebhookTriggerEvents.INSTANT_MEETING - ); - expect(builder).toBe(defaultBuilders.instantMeeting); - }); }); describe("Fallback Behavior", () => { @@ -166,17 +156,12 @@ describe("PayloadBuilderFactory", () => { WebhookVersionEnum.V_2021_10_20, WebhookTriggerEvents.MEETING_STARTED ); - const instantBuilder = factory.getBuilder( - WebhookVersionEnum.V_2021_10_20, - WebhookTriggerEvents.INSTANT_MEETING - ); // Runtime verification expect(bookingBuilder).toBeDefined(); expect(oooBuilder).toBeDefined(); expect(recordingBuilder).toBeDefined(); expect(meetingBuilder).toBeDefined(); - expect(instantBuilder).toBeDefined(); }); it("should build valid payload with correctly typed DTO", () => { @@ -244,7 +229,6 @@ describe("PayloadBuilderFactory", () => { ooo: new V2021_10_20.OOOPayloadBuilder(), recording: new V2021_10_20.RecordingPayloadBuilder(), meeting: new V2021_10_20.MeetingPayloadBuilder(), - instantMeeting: new V2021_10_20.InstantMeetingBuilder(), }; factory.registerVersion(WebhookVersionEnum.V_2024_12_01, v2Builders); diff --git a/packages/features/webhooks/lib/factory/versioned/PayloadBuilderFactory.ts b/packages/features/webhooks/lib/factory/versioned/PayloadBuilderFactory.ts index 82223e1acf..7f44c299b8 100644 --- a/packages/features/webhooks/lib/factory/versioned/PayloadBuilderFactory.ts +++ b/packages/features/webhooks/lib/factory/versioned/PayloadBuilderFactory.ts @@ -4,7 +4,6 @@ import type { AfterGuestsNoShowDTO, AfterHostsNoShowDTO, BookingWebhookEventDTO, - InstantMeetingDTO, MeetingEndedDTO, MeetingStartedDTO, OOOCreatedDTO, @@ -44,16 +43,11 @@ export interface IMeetingPayloadBuilder ): WebhookPayload; } -export interface IInstantMeetingBuilder extends IPayloadBuilder { - build(dto: InstantMeetingDTO): WebhookPayload; -} - export interface PayloadBuilderSet { booking: IBookingPayloadBuilder; ooo: IOOOPayloadBuilder; recording: IRecordingPayloadBuilder; meeting: IMeetingPayloadBuilder; - instantMeeting: IInstantMeetingBuilder; } type BuilderCategory = keyof PayloadBuilderSet; @@ -92,9 +86,6 @@ const TRIGGER_TO_BUILDER_CATEGORY: Record [WebhookTriggerEvents.AFTER_HOSTS_CAL_VIDEO_NO_SHOW]: "meeting", [WebhookTriggerEvents.AFTER_GUESTS_CAL_VIDEO_NO_SHOW]: "meeting", - // Instant meeting events - [WebhookTriggerEvents.INSTANT_MEETING]: "instantMeeting", - // Delegation events (enterprise feature removed, mapped to booking as fallback) [WebhookTriggerEvents.DELEGATION_CREDENTIAL_ERROR]: "booking", @@ -128,8 +119,6 @@ export type MeetingTriggerEvents = | typeof WebhookTriggerEvents.AFTER_HOSTS_CAL_VIDEO_NO_SHOW | typeof WebhookTriggerEvents.AFTER_GUESTS_CAL_VIDEO_NO_SHOW; -export type InstantMeetingTriggerEvents = typeof WebhookTriggerEvents.INSTANT_MEETING; - /** * Factory that routes to version-specific payload builders * @@ -192,7 +181,6 @@ export class PayloadBuilderFactory { getBuilder(version: WebhookVersion, triggerEvent: OOOTriggerEvents): IOOOPayloadBuilder; getBuilder(version: WebhookVersion, triggerEvent: RecordingTriggerEvents): IRecordingPayloadBuilder; getBuilder(version: WebhookVersion, triggerEvent: MeetingTriggerEvents): IMeetingPayloadBuilder; - getBuilder(version: WebhookVersion, triggerEvent: InstantMeetingTriggerEvents): IInstantMeetingBuilder; getBuilder(version: WebhookVersion, triggerEvent: WebhookTriggerEvents): IPayloadBuilder; getBuilder(version: WebhookVersion, triggerEvent: WebhookTriggerEvents): IPayloadBuilder { const builderSet = this.getBuilderSet(version); diff --git a/packages/features/webhooks/lib/factory/versioned/registry.test.ts b/packages/features/webhooks/lib/factory/versioned/registry.test.ts index 6be2c2d8c3..2336793682 100644 --- a/packages/features/webhooks/lib/factory/versioned/registry.test.ts +++ b/packages/features/webhooks/lib/factory/versioned/registry.test.ts @@ -31,16 +31,11 @@ describe("Payload Builder Registry", () => { DEFAULT_WEBHOOK_VERSION, WebhookTriggerEvents.MEETING_STARTED ); - const instantBuilder = factory.getBuilder( - DEFAULT_WEBHOOK_VERSION, - WebhookTriggerEvents.INSTANT_MEETING - ); expect(bookingBuilder).toBeDefined(); expect(oooBuilder).toBeDefined(); expect(recordingBuilder).toBeDefined(); expect(meetingBuilder).toBeDefined(); - expect(instantBuilder).toBeDefined(); }); it("should register v2021-10-20 builders", () => { @@ -92,7 +87,6 @@ describe("Payload Builder Registry", () => { ooo: new V2021_10_20.OOOPayloadBuilder(), recording: new V2021_10_20.RecordingPayloadBuilder(), meeting: new V2021_10_20.MeetingPayloadBuilder(), - instantMeeting: new V2021_10_20.InstantMeetingBuilder(), }; factory.registerVersion(NEW_VERSION, newVersionBuilders); @@ -111,7 +105,6 @@ describe("Payload Builder Registry", () => { ooo: new V2021_10_20.OOOPayloadBuilder(), recording: new V2021_10_20.RecordingPayloadBuilder(), meeting: new V2021_10_20.MeetingPayloadBuilder(), - instantMeeting: new V2021_10_20.InstantMeetingBuilder(), }; factory.registerVersion(NEW_VERSION, v2Builders); @@ -140,7 +133,6 @@ describe("Payload Builder Registry", () => { ooo: new V2021_10_20.OOOPayloadBuilder(), recording: new V2021_10_20.RecordingPayloadBuilder(), meeting: new V2021_10_20.MeetingPayloadBuilder(), - instantMeeting: new V2021_10_20.InstantMeetingBuilder(), }); expect(factory1.getRegisteredVersions()).not.toEqual(factory2.getRegisteredVersions()); diff --git a/packages/features/webhooks/lib/factory/versioned/registry.ts b/packages/features/webhooks/lib/factory/versioned/registry.ts index 92832b2e10..5b2ac227e2 100644 --- a/packages/features/webhooks/lib/factory/versioned/registry.ts +++ b/packages/features/webhooks/lib/factory/versioned/registry.ts @@ -26,7 +26,6 @@ export { DEFAULT_WEBHOOK_VERSION } from "../../interface/IWebhookRepository"; * ooo: new V2024_12_01.OOOPayloadBuilder(), * recording: new V2024_12_01.RecordingPayloadBuilder(), * meeting: new V2024_12_01.MeetingPayloadBuilder(), - * instantMeeting: new V2024_12_01.InstantMeetingBuilder(), * }); * ``` */ @@ -36,7 +35,6 @@ export function createPayloadBuilderFactory(): PayloadBuilderFactory { ooo: new V2021_10_20.OOOPayloadBuilder(), recording: new V2021_10_20.RecordingPayloadBuilder(), meeting: new V2021_10_20.MeetingPayloadBuilder(), - instantMeeting: new V2021_10_20.InstantMeetingBuilder(), }; const factory = new PayloadBuilderFactory(DEFAULT_WEBHOOK_VERSION, defaultBuilders); diff --git a/packages/features/webhooks/lib/factory/versioned/v2021-10-20/InstantMeetingBuilder.ts b/packages/features/webhooks/lib/factory/versioned/v2021-10-20/InstantMeetingBuilder.ts deleted file mode 100644 index a3d7889c7a..0000000000 --- a/packages/features/webhooks/lib/factory/versioned/v2021-10-20/InstantMeetingBuilder.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { InstantMeetingDTO } from "../../../dto/types"; -import type { WebhookPayload } from "../../types"; -import { BaseInstantMeetingBuilder } from "../../base/BaseInstantMeetingBuilder"; - -/** - * Instant meeting payload builder for webhook version v2021-10-20. - * - * This is the initial instant meeting webhook payload format. - * It includes notification-style data (title, body, icon, url, actions). - */ -export class InstantMeetingBuilder extends BaseInstantMeetingBuilder { - /** - * Build the instant meeting webhook payload for v2021-10-20. - */ - build(dto: InstantMeetingDTO): WebhookPayload { - return { - triggerEvent: dto.triggerEvent, - createdAt: dto.createdAt, - payload: { - title: dto.title, - body: dto.body, - icon: dto.icon, - url: dto.url, - actions: dto.actions, - requireInteraction: dto.requireInteraction, - type: dto.type, - }, - }; - } -} diff --git a/packages/features/webhooks/lib/factory/versioned/v2021-10-20/index.ts b/packages/features/webhooks/lib/factory/versioned/v2021-10-20/index.ts index 5caed485a9..4d816fb65f 100644 --- a/packages/features/webhooks/lib/factory/versioned/v2021-10-20/index.ts +++ b/packages/features/webhooks/lib/factory/versioned/v2021-10-20/index.ts @@ -10,4 +10,3 @@ export { BookingPayloadBuilder } from "./BookingPayloadBuilder"; export { MeetingPayloadBuilder } from "./MeetingPayloadBuilder"; export { RecordingPayloadBuilder } from "./RecordingPayloadBuilder"; export { OOOPayloadBuilder } from "./OOOPayloadBuilder"; -export { InstantMeetingBuilder } from "./InstantMeetingBuilder"; diff --git a/packages/prisma/migrations/20260430000000_drop_instant_meeting_webhook_trigger/migration.sql b/packages/prisma/migrations/20260430000000_drop_instant_meeting_webhook_trigger/migration.sql new file mode 100644 index 0000000000..6897fe0ed3 --- /dev/null +++ b/packages/prisma/migrations/20260430000000_drop_instant_meeting_webhook_trigger/migration.sql @@ -0,0 +1,33 @@ +BEGIN; +UPDATE "public"."Webhook" +SET "eventTriggers" = array_remove("eventTriggers", 'INSTANT_MEETING'::"public"."WebhookTriggerEvents") +WHERE "eventTriggers" @> ARRAY['INSTANT_MEETING']::"public"."WebhookTriggerEvents"[]; + +CREATE TYPE "public"."WebhookTriggerEvents_new" AS ENUM ( + 'BOOKING_CREATED', + 'BOOKING_PAYMENT_INITIATED', + 'BOOKING_PAID', + 'BOOKING_RESCHEDULED', + 'BOOKING_REQUESTED', + 'BOOKING_CANCELLED', + 'BOOKING_REJECTED', + 'BOOKING_NO_SHOW_UPDATED', + 'FORM_SUBMITTED', + 'MEETING_ENDED', + 'MEETING_STARTED', + 'RECORDING_READY', + 'RECORDING_TRANSCRIPTION_GENERATED', + 'OOO_CREATED', + 'AFTER_HOSTS_CAL_VIDEO_NO_SHOW', + 'AFTER_GUESTS_CAL_VIDEO_NO_SHOW', + 'FORM_SUBMITTED_NO_EVENT', + 'DELEGATION_CREDENTIAL_ERROR', + 'WRONG_ASSIGNMENT_REPORT' +); +ALTER TABLE "public"."Webhook" +ALTER COLUMN "eventTriggers" TYPE "public"."WebhookTriggerEvents_new"[] +USING ("eventTriggers"::text::"public"."WebhookTriggerEvents_new"[]); +ALTER TYPE "public"."WebhookTriggerEvents" RENAME TO "WebhookTriggerEvents_old"; +ALTER TYPE "public"."WebhookTriggerEvents_new" RENAME TO "WebhookTriggerEvents"; +DROP TYPE "public"."WebhookTriggerEvents_old"; +COMMIT; diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index cef62a052f..743ca56040 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -1130,7 +1130,6 @@ enum WebhookTriggerEvents { MEETING_ENDED MEETING_STARTED RECORDING_READY - INSTANT_MEETING RECORDING_TRANSCRIPTION_GENERATED OOO_CREATED AFTER_HOSTS_CAL_VIDEO_NO_SHOW