2ec9e903ce
* feat: implement webhook tasker with async/sync fallback This PR implements a webhook tasker with async/sync fallback architecture to fix failing E2E tests. The solution follows the existing proration tasker pattern and uses Dependency Injection with @evyweb/ioctopus. Key changes: - Create IWebhookTasker interface for webhook delivery - Implement WebhookSyncTasker for immediate execution (E2E tests) - Implement WebhookAsyncTasker for queued execution (production) - Create main WebhookTasker class extending Tasker<IWebhookTasker> - Add DI modules and tokens for all tasker components - Update WebhookTaskerProducerService to use new WebhookTasker - Add unit tests for sync and async taskers The ENABLE_ASYNC_TASKER flag automatically selects the appropriate mode: - Production: Uses WebhookAsyncTasker to queue tasks - E2E Tests: Uses WebhookSyncTasker for immediate execution This ensures webhooks are delivered immediately in E2E tests without requiring the cron job that processes queued tasks. Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com> * fix: update WebhookTaskerProducerService tests for new interface Update tests to use the new deps-based constructor and mockWebhookTasker.deliverWebhook instead of mockTasker.create Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com> * fix: use moduleLoader pattern for WebhookProducerService in container Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com> * refactor: replace InternalTasker with Trigger.dev for webhook delivery This commit refactors the WebhookTasker to use Trigger.dev instead of InternalTasker, following the pattern established in BookingEmailAndSmsTasker and PlatformOrganizationBillingTasker (PR #26803). Changes: - Replace WebhookAsyncTasker with WebhookTriggerTasker that uses trigger.dev - Create trigger.dev task files (deliver-webhook.ts, config.ts, schema.ts) - Update DI modules to use WebhookTriggerTasker - Remove old InternalTasker-based implementation - Update unit tests for new implementation The WebhookSyncTasker continues to execute webhooks immediately for E2E tests where ENABLE_ASYNC_TASKER is automatically false. Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com> * fix: update comments to reflect Trigger.dev usage instead of InternalTasker Co-Authored-By: unknown <> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
53 lines
2.8 KiB
TypeScript
53 lines
2.8 KiB
TypeScript
import type { Container } from "@evyweb/ioctopus";
|
|
|
|
import type { ModuleLoader } from "@calcom/features/di/di";
|
|
import type { WebhookTaskConsumer } from "@calcom/features/webhooks/lib/service/WebhookTaskConsumer";
|
|
|
|
import { moduleLoader as loggerModuleLoader } from "../../shared/services/logger.service";
|
|
import { moduleLoader as prismaModuleLoader } from "../../modules/Prisma";
|
|
import { taskerServiceModule } from "../../shared/services/tasker.service";
|
|
import { SHARED_TOKENS } from "../../shared/shared.tokens";
|
|
import { bookingWebhookDataFetcherModule } from "../modules/BookingWebhookDataFetcher.module";
|
|
import { formWebhookDataFetcherModule } from "../modules/FormWebhookDataFetcher.module";
|
|
import { oooWebhookDataFetcherModule } from "../modules/OOOWebhookDataFetcher.module";
|
|
import { paymentWebhookDataFetcherModule } from "../modules/PaymentWebhookDataFetcher.module";
|
|
import { recordingWebhookDataFetcherModule } from "../modules/RecordingWebhookDataFetcher.module";
|
|
import { webhookModule } from "../modules/Webhook.module";
|
|
import { webhookTaskConsumerModule } from "../modules/WebhookTaskConsumer.module";
|
|
import { WEBHOOK_TOKENS } from "../Webhooks.tokens";
|
|
|
|
const token = WEBHOOK_TOKENS.WEBHOOK_TASK_CONSUMER;
|
|
|
|
const loadModule = (container: Container) => {
|
|
loggerModuleLoader.loadModule(container);
|
|
prismaModuleLoader.loadModule(container);
|
|
container.load(SHARED_TOKENS.TASKER, taskerServiceModule);
|
|
|
|
container.load(WEBHOOK_TOKENS.WEBHOOK_EVENT_TYPE_REPOSITORY, webhookModule);
|
|
container.load(WEBHOOK_TOKENS.WEBHOOK_USER_REPOSITORY, webhookModule);
|
|
container.load(WEBHOOK_TOKENS.WEBHOOK_REPOSITORY, webhookModule);
|
|
container.load(WEBHOOK_TOKENS.WEBHOOK_SERVICE, webhookModule);
|
|
container.load(WEBHOOK_TOKENS.BOOKING_WEBHOOK_SERVICE, webhookModule);
|
|
container.load(WEBHOOK_TOKENS.FORM_WEBHOOK_SERVICE, webhookModule);
|
|
container.load(WEBHOOK_TOKENS.RECORDING_WEBHOOK_SERVICE, webhookModule);
|
|
container.load(WEBHOOK_TOKENS.OOO_WEBHOOK_SERVICE, webhookModule);
|
|
container.load(WEBHOOK_TOKENS.PAYLOAD_BUILDER_FACTORY, webhookModule);
|
|
container.load(WEBHOOK_TOKENS.WEBHOOK_NOTIFICATION_HANDLER, webhookModule);
|
|
container.load(WEBHOOK_TOKENS.WEBHOOK_NOTIFIER, webhookModule);
|
|
|
|
container.load(WEBHOOK_TOKENS.BOOKING_DATA_FETCHER, bookingWebhookDataFetcherModule);
|
|
container.load(WEBHOOK_TOKENS.PAYMENT_DATA_FETCHER, paymentWebhookDataFetcherModule);
|
|
container.load(WEBHOOK_TOKENS.FORM_DATA_FETCHER, formWebhookDataFetcherModule);
|
|
container.load(WEBHOOK_TOKENS.RECORDING_DATA_FETCHER, recordingWebhookDataFetcherModule);
|
|
container.load(WEBHOOK_TOKENS.OOO_DATA_FETCHER, oooWebhookDataFetcherModule);
|
|
|
|
container.load(WEBHOOK_TOKENS.WEBHOOK_TASK_CONSUMER, webhookTaskConsumerModule);
|
|
};
|
|
|
|
export const moduleLoader = {
|
|
token,
|
|
loadModule,
|
|
} satisfies ModuleLoader;
|
|
|
|
export type { WebhookTaskConsumer };
|