chore: Add initial webhook wiring (TRPC handlers) to the new architecture (#27170)
* --init * clean up * unnecessary comment * remove comment * fix factory resolver * Add active filter to webhook query
This commit is contained in:
@@ -13,6 +13,8 @@ export const WEBHOOK_TOKENS = {
|
||||
|
||||
// Repositories
|
||||
WEBHOOK_REPOSITORY: Symbol("IWebhookRepository"),
|
||||
WEBHOOK_EVENT_TYPE_REPOSITORY: Symbol("IEventTypeRepository"),
|
||||
WEBHOOK_USER_REPOSITORY: Symbol("IUserRepository"),
|
||||
|
||||
// Producer/Consumer
|
||||
WEBHOOK_PRODUCER_SERVICE: Symbol("IWebhookProducerService"),
|
||||
|
||||
@@ -32,7 +32,9 @@ loggerModuleLoader.loadModule(webhookContainer);
|
||||
prismaModuleLoader.loadModule(webhookContainer);
|
||||
webhookContainer.load(SHARED_TOKENS.TASKER, taskerServiceModule);
|
||||
|
||||
// Load webhook module
|
||||
// Load webhook module (includes cross-table repositories + all webhook services)
|
||||
webhookContainer.load(WEBHOOK_TOKENS.WEBHOOK_EVENT_TYPE_REPOSITORY, webhookModule);
|
||||
webhookContainer.load(WEBHOOK_TOKENS.WEBHOOK_USER_REPOSITORY, webhookModule);
|
||||
webhookContainer.load(WEBHOOK_TOKENS.WEBHOOK_REPOSITORY, webhookModule);
|
||||
webhookContainer.load(WEBHOOK_TOKENS.WEBHOOK_SERVICE, webhookModule);
|
||||
webhookContainer.load(WEBHOOK_TOKENS.BOOKING_WEBHOOK_SERVICE, webhookModule);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createModule } from "@evyweb/ioctopus";
|
||||
|
||||
import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository";
|
||||
import { UsersRepository } from "@calcom/features/users/users.repository";
|
||||
import { createPayloadBuilderFactory } from "@calcom/features/webhooks/lib/factory/versioned/registry";
|
||||
import { WebhookRepository } from "@calcom/features/webhooks/lib/repository/WebhookRepository";
|
||||
import { BookingWebhookService } from "@calcom/features/webhooks/lib/service/BookingWebhookService";
|
||||
@@ -9,17 +9,28 @@ import { RecordingWebhookService } from "@calcom/features/webhooks/lib/service/R
|
||||
import { WebhookNotificationHandler } from "@calcom/features/webhooks/lib/service/WebhookNotificationHandler";
|
||||
import { WebhookNotifier } from "@calcom/features/webhooks/lib/service/WebhookNotifier";
|
||||
import { WebhookService } from "@calcom/features/webhooks/lib/service/WebhookService";
|
||||
|
||||
import { DI_TOKENS } from "../../tokens";
|
||||
import { createModule } from "@evyweb/ioctopus";
|
||||
import { SHARED_TOKENS } from "../../shared/shared.tokens";
|
||||
import { DI_TOKENS } from "../../tokens";
|
||||
import { WEBHOOK_TOKENS } from "../Webhooks.tokens";
|
||||
|
||||
export const webhookModule = createModule();
|
||||
const webhookModule = createModule();
|
||||
|
||||
// Bind repository with Prisma dependency
|
||||
// Bind cross-table repositories (used by WebhookRepository)
|
||||
webhookModule
|
||||
.bind(WEBHOOK_TOKENS.WEBHOOK_EVENT_TYPE_REPOSITORY)
|
||||
.toClass(EventTypeRepository, [DI_TOKENS.PRISMA_CLIENT]);
|
||||
|
||||
webhookModule.bind(WEBHOOK_TOKENS.WEBHOOK_USER_REPOSITORY).toClass(UsersRepository, []);
|
||||
|
||||
// Bind webhook repository with dependencies (Repository Pattern compliance)
|
||||
webhookModule
|
||||
.bind(WEBHOOK_TOKENS.WEBHOOK_REPOSITORY)
|
||||
.toClass(WebhookRepository, [DI_TOKENS.PRISMA_CLIENT]);
|
||||
.toClass(WebhookRepository, [
|
||||
DI_TOKENS.PRISMA_CLIENT,
|
||||
WEBHOOK_TOKENS.WEBHOOK_EVENT_TYPE_REPOSITORY,
|
||||
WEBHOOK_TOKENS.WEBHOOK_USER_REPOSITORY,
|
||||
]);
|
||||
|
||||
// Bind services
|
||||
webhookModule
|
||||
@@ -68,3 +79,5 @@ webhookModule
|
||||
webhookModule
|
||||
.bind(WEBHOOK_TOKENS.WEBHOOK_NOTIFIER)
|
||||
.toClass(WebhookNotifier, [WEBHOOK_TOKENS.WEBHOOK_NOTIFICATION_HANDLER, SHARED_TOKENS.LOGGER]);
|
||||
|
||||
export { webhookModule };
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { IWebhookDataFetcher } from "@calcom/features/webhooks/lib/interfac
|
||||
import type { IWebhookRepository } from "@calcom/features/webhooks/lib/interface/IWebhookRepository";
|
||||
import type { ILogger } from "@calcom/features/webhooks/lib/interface/infrastructure";
|
||||
import { WebhookTaskConsumer } from "@calcom/features/webhooks/lib/service/WebhookTaskConsumer";
|
||||
import type { Container } from "@evyweb/ioctopus";
|
||||
import type { ResolveFunction } from "@evyweb/ioctopus";
|
||||
import { createModule } from "@evyweb/ioctopus";
|
||||
import { SHARED_TOKENS } from "../../shared/shared.tokens";
|
||||
import { WEBHOOK_TOKENS } from "../Webhooks.tokens";
|
||||
@@ -18,16 +18,16 @@ import { WEBHOOK_TOKENS } from "../Webhooks.tokens";
|
||||
*/
|
||||
export const webhookTaskConsumerModule = createModule();
|
||||
|
||||
webhookTaskConsumerModule.bind(WEBHOOK_TOKENS.WEBHOOK_TASK_CONSUMER).toFactory((container: Container) => {
|
||||
const webhookRepository = container.get<IWebhookRepository>(WEBHOOK_TOKENS.WEBHOOK_REPOSITORY);
|
||||
webhookTaskConsumerModule.bind(WEBHOOK_TOKENS.WEBHOOK_TASK_CONSUMER).toFactory((resolve: ResolveFunction) => {
|
||||
const webhookRepository = resolve(WEBHOOK_TOKENS.WEBHOOK_REPOSITORY) as IWebhookRepository;
|
||||
const dataFetchers: IWebhookDataFetcher[] = [
|
||||
container.get<IWebhookDataFetcher>(WEBHOOK_TOKENS.BOOKING_DATA_FETCHER),
|
||||
container.get<IWebhookDataFetcher>(WEBHOOK_TOKENS.PAYMENT_DATA_FETCHER),
|
||||
container.get<IWebhookDataFetcher>(WEBHOOK_TOKENS.FORM_DATA_FETCHER),
|
||||
container.get<IWebhookDataFetcher>(WEBHOOK_TOKENS.RECORDING_DATA_FETCHER),
|
||||
container.get<IWebhookDataFetcher>(WEBHOOK_TOKENS.OOO_DATA_FETCHER),
|
||||
resolve(WEBHOOK_TOKENS.BOOKING_DATA_FETCHER) as IWebhookDataFetcher,
|
||||
resolve(WEBHOOK_TOKENS.PAYMENT_DATA_FETCHER) as IWebhookDataFetcher,
|
||||
resolve(WEBHOOK_TOKENS.FORM_DATA_FETCHER) as IWebhookDataFetcher,
|
||||
resolve(WEBHOOK_TOKENS.RECORDING_DATA_FETCHER) as IWebhookDataFetcher,
|
||||
resolve(WEBHOOK_TOKENS.OOO_DATA_FETCHER) as IWebhookDataFetcher,
|
||||
];
|
||||
const logger = container.get<ILogger>(SHARED_TOKENS.LOGGER);
|
||||
const logger = resolve(SHARED_TOKENS.LOGGER) as ILogger;
|
||||
|
||||
return new WebhookTaskConsumer(webhookRepository, dataFetchers, logger);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* EventTypes Repository Interface
|
||||
*
|
||||
* Central interface for EventType repository methods.
|
||||
*/
|
||||
|
||||
export interface IEventTypesRepository {
|
||||
/**
|
||||
* @param eventTypeId - The event type to check
|
||||
* @returns Parent ID if this is a managed child event type, null otherwise
|
||||
*/
|
||||
findParentEventTypeId(eventTypeId: number): Promise<number | null>;
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { IEventTypesRepository } from "@calcom/features/eventtypes/eventtypes.repository.interface";
|
||||
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
|
||||
import { LookupTarget, ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository";
|
||||
import type { UserWithLegacySelectedCalendars } from "@calcom/features/users/repositories/UserRepository";
|
||||
@@ -9,8 +10,7 @@ import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import { eventTypeSelect } from "@calcom/lib/server/eventTypeSelect";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import { availabilityUserSelect, userSelect as userSelectWithSelectedCalendars } from "@calcom/prisma";
|
||||
import type { EventType as PrismaEventType } from "@calcom/prisma/client";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import type { Prisma, EventType as PrismaEventType } from "@calcom/prisma/client";
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
|
||||
import { EventTypeMetaDataSchema, rrSegmentQueryValueSchema } from "@calcom/prisma/zod-utils";
|
||||
@@ -78,9 +78,25 @@ function usersWithSelectedCalendars<
|
||||
return users.map((user) => withSelectedCalendars(user));
|
||||
}
|
||||
|
||||
export class EventTypeRepository {
|
||||
export class EventTypeRepository implements IEventTypesRepository {
|
||||
constructor(private prismaClient: PrismaClient) {}
|
||||
|
||||
async findParentEventTypeId(eventTypeId: number): Promise<number | null> {
|
||||
const managedChildEventType = await this.prismaClient.eventType.findFirst({
|
||||
where: {
|
||||
id: eventTypeId,
|
||||
parentId: {
|
||||
not: null,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
parentId: true,
|
||||
},
|
||||
});
|
||||
|
||||
return managedChildEventType?.parentId ?? null;
|
||||
}
|
||||
|
||||
private generateCreateEventTypeData = (eventTypeCreateData: IEventType) => {
|
||||
const {
|
||||
userId,
|
||||
|
||||
@@ -2,4 +2,10 @@ import type { User } from "@calcom/prisma/client";
|
||||
|
||||
export interface IUsersRepository {
|
||||
updateLastActiveAt(userId: number): Promise<User>;
|
||||
|
||||
/**
|
||||
* @param userId - The user ID to query
|
||||
* @returns User with team memberships, or null if user not found
|
||||
*/
|
||||
findUserTeams(userId: number): Promise<{ teams: { teamId: number }[] } | null>;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import db, { prisma } from "@calcom/prisma";
|
||||
import { captureException } from "@sentry/nextjs";
|
||||
|
||||
import db from "@calcom/prisma";
|
||||
|
||||
import type { IUsersRepository } from "./users.repository.interface";
|
||||
|
||||
export class UsersRepository implements IUsersRepository {
|
||||
@@ -17,4 +15,23 @@ export class UsersRepository implements IUsersRepository {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async findUserTeams(userId: number): Promise<{ teams: { teamId: number }[] } | null> {
|
||||
try {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: {
|
||||
teams: {
|
||||
select: {
|
||||
teamId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
return user;
|
||||
} catch (err) {
|
||||
captureException(err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { WebhookTriggerEvents, UserPermissionRole } from "@calcom/prisma/enums";
|
||||
|
||||
import type { Webhook, WebhookSubscriber, WebhookGroup } from "../dto/types";
|
||||
import type { UserPermissionRole, WebhookTriggerEvents } from "@calcom/prisma/enums";
|
||||
import type { Webhook, WebhookGroup, WebhookSubscriber } from "../dto/types";
|
||||
|
||||
/**
|
||||
* Webhook Version enum - defines the payload format versions.
|
||||
@@ -8,20 +7,20 @@ import type { Webhook, WebhookSubscriber, WebhookGroup } from "../dto/types";
|
||||
* This is a TypeScript-only enum (not Prisma).
|
||||
* DB operations go through the repository which enforces these values.
|
||||
*/
|
||||
export const WebhookVersion = {
|
||||
const WebhookVersion = {
|
||||
V_2021_10_20: "2021-10-20",
|
||||
} as const;
|
||||
|
||||
export type WebhookVersion = (typeof WebhookVersion)[keyof typeof WebhookVersion];
|
||||
type WebhookVersion = (typeof WebhookVersion)[keyof typeof WebhookVersion];
|
||||
|
||||
/**
|
||||
* Default webhook version - used for new webhooks and as fallback
|
||||
*/
|
||||
export const DEFAULT_WEBHOOK_VERSION = WebhookVersion.V_2021_10_20;
|
||||
|
||||
const VALID_WEBHOOK_VERSIONS = new Set<string>(Object.values(WebhookVersion));
|
||||
const DEFAULT_WEBHOOK_VERSION: WebhookVersion = WebhookVersion.V_2021_10_20;
|
||||
|
||||
const VALID_WEBHOOK_VERSIONS: Set<string> = new Set<string>(Object.values(WebhookVersion));
|
||||
|
||||
export { WebhookVersion, DEFAULT_WEBHOOK_VERSION, VALID_WEBHOOK_VERSIONS };
|
||||
export function isValidWebhookVersion(value: string): value is WebhookVersion {
|
||||
return VALID_WEBHOOK_VERSIONS.has(value);
|
||||
}
|
||||
@@ -71,6 +70,10 @@ export interface IWebhookRepository {
|
||||
timeUnit: string | null;
|
||||
version: WebhookVersion;
|
||||
}>;
|
||||
findByOrgIdAndTrigger(options: {
|
||||
orgId: number;
|
||||
triggerEvent: WebhookTriggerEvents;
|
||||
}): Promise<WebhookSubscriber[]>;
|
||||
getFilteredWebhooksForUser(options: { userId: number; userRole?: UserPermissionRole }): Promise<{
|
||||
webhookGroups: WebhookGroup[];
|
||||
profiles: {
|
||||
@@ -84,4 +87,3 @@ export interface IWebhookRepository {
|
||||
}>;
|
||||
listWebhooks(options: ListWebhooksOptions): Promise<Webhook[]>;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import type { IEventTypesRepository } from "@calcom/features/eventtypes/eventtypes.repository.interface";
|
||||
import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository";
|
||||
import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service";
|
||||
import { UsersRepository } from "@calcom/features/users/users.repository";
|
||||
import type { IUsersRepository } from "@calcom/features/users/users.repository.interface";
|
||||
import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
|
||||
import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
@@ -30,7 +34,7 @@ interface WebhookQueryResult {
|
||||
priority: number; // This field is added by the query and removed before returning
|
||||
}
|
||||
|
||||
const filterWebhooks = (webhook: { appId: string | null }) => {
|
||||
const filterWebhooks = (webhook: { appId: string | null }): boolean => {
|
||||
const appIds = [
|
||||
"zapier",
|
||||
"make",
|
||||
@@ -41,17 +45,30 @@ const filterWebhooks = (webhook: { appId: string | null }) => {
|
||||
};
|
||||
|
||||
export class WebhookRepository implements IWebhookRepository {
|
||||
private static _instance: WebhookRepository;
|
||||
private static _instance: WebhookRepository | undefined;
|
||||
|
||||
constructor(private readonly prisma: typeof defaultPrisma = defaultPrisma) {}
|
||||
constructor(
|
||||
private readonly prisma: PrismaClient,
|
||||
private readonly eventTypeRepository: IEventTypesRepository,
|
||||
private readonly userRepository: IUsersRepository
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Singleton accessor for backward compatibility.
|
||||
* @deprecated Use DI container (getWebhookFeature().repository) instead
|
||||
*
|
||||
* @deprecated Use DI container instead:
|
||||
* ```typescript
|
||||
* import { getWebhookFeature } from "@calcom/features/di/webhooks/containers/webhook";
|
||||
* const { repository } = getWebhookFeature();
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
static getInstance(): WebhookRepository {
|
||||
if (!WebhookRepository._instance) {
|
||||
WebhookRepository._instance = new WebhookRepository(defaultPrisma);
|
||||
WebhookRepository._instance = new WebhookRepository(
|
||||
defaultPrisma,
|
||||
new EventTypeRepository(defaultPrisma),
|
||||
new UsersRepository()
|
||||
);
|
||||
}
|
||||
return WebhookRepository._instance;
|
||||
}
|
||||
@@ -66,18 +83,8 @@ export class WebhookRepository implements IWebhookRepository {
|
||||
|
||||
let managedParentEventTypeId: number | undefined;
|
||||
if (eventTypeId) {
|
||||
const managedChildEventType = await this.prisma.eventType.findFirst({
|
||||
where: {
|
||||
id: eventTypeId,
|
||||
parentId: {
|
||||
not: null,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
parentId: true,
|
||||
},
|
||||
});
|
||||
managedParentEventTypeId = managedChildEventType?.parentId ?? undefined;
|
||||
managedParentEventTypeId =
|
||||
(await this.eventTypeRepository.findParentEventTypeId(eventTypeId)) ?? undefined;
|
||||
}
|
||||
|
||||
const webhooks = await this.getSubscribersRaw({
|
||||
@@ -277,6 +284,7 @@ export class WebhookRepository implements IWebhookRepository {
|
||||
teamId: orgId,
|
||||
platform: false,
|
||||
eventTriggers: { has: triggerEvent },
|
||||
active: true,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
@@ -508,26 +516,15 @@ export class WebhookRepository implements IWebhookRepository {
|
||||
{ appId: appId ?? null },
|
||||
];
|
||||
|
||||
// Get user's teams
|
||||
const user = await this.prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { teams: true },
|
||||
});
|
||||
const user = await this.userRepository.findUserTeams(userId);
|
||||
|
||||
if (eventTypeId) {
|
||||
// Check for managed event type parent
|
||||
const managedParentEvt = await this.prisma.eventType.findFirst({
|
||||
where: {
|
||||
id: eventTypeId,
|
||||
parentId: { not: null },
|
||||
},
|
||||
select: { parentId: true },
|
||||
});
|
||||
const managedParentId = await this.eventTypeRepository.findParentEventTypeId(eventTypeId);
|
||||
|
||||
if (managedParentEvt?.parentId) {
|
||||
if (managedParentId) {
|
||||
// Include webhooks from both the event type and its parent (if active)
|
||||
whereConditions.push({
|
||||
OR: [{ eventTypeId }, { eventTypeId: managedParentEvt.parentId, active: true }],
|
||||
OR: [{ eventTypeId }, { eventTypeId: managedParentId, active: true }],
|
||||
});
|
||||
} else {
|
||||
whereConditions.push({ eventTypeId });
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { DelegationCredentialRepository } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository";
|
||||
import { DelegationCredentialErrorPayloadType } from "@calcom/features/webhooks/lib/dto/types";
|
||||
import { getWebhookFeature } from "@calcom/features/di/webhooks/containers/webhook";
|
||||
import type { DelegationCredentialErrorPayloadType } from "@calcom/features/webhooks/lib/dto/types";
|
||||
import type { CalendarAppDelegationCredentialError } from "@calcom/lib/CalendarAppError";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { WebhookTriggerEvents } from "@calcom/prisma/enums";
|
||||
|
||||
import { WebhookRepository } from "./repository/WebhookRepository";
|
||||
import sendPayload from "./sendPayload";
|
||||
|
||||
const log = logger.getSubLogger({ prefix: ["triggerDelegationCredentialErrorWebhook"] });
|
||||
@@ -30,7 +29,7 @@ export async function triggerDelegationCredentialErrorWebhook(params: {
|
||||
return;
|
||||
}
|
||||
|
||||
const webhookRepository = WebhookRepository.getInstance();
|
||||
const { repository: webhookRepository } = getWebhookFeature();
|
||||
const webhooks = await webhookRepository.findByOrgIdAndTrigger({
|
||||
orgId: delegationCredential.organizationId,
|
||||
triggerEvent: WebhookTriggerEvents.DELEGATION_CREDENTIAL_ERROR,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { WebhookRepository } from "@calcom/features/webhooks/lib/repository/WebhookRepository";
|
||||
import { getWebhookFeature } from "@calcom/features/di/webhooks/containers/webhook";
|
||||
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
|
||||
|
||||
import type { TGetInputSchema } from "./get.schema";
|
||||
|
||||
type GetOptions = {
|
||||
@@ -11,6 +10,6 @@ type GetOptions = {
|
||||
};
|
||||
|
||||
export const getHandler = async ({ ctx: _ctx, input }: GetOptions) => {
|
||||
const webhookRepository = WebhookRepository.getInstance();
|
||||
const { repository: webhookRepository } = getWebhookFeature();
|
||||
return await webhookRepository.findByWebhookId(input.webhookId);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getWebhookFeature } from "@calcom/features/di/webhooks/containers/webhook";
|
||||
import type { WebhookGroup } from "@calcom/features/webhooks/lib/dto/types";
|
||||
import { WebhookRepository } from "@calcom/features/webhooks/lib/repository/WebhookRepository";
|
||||
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
|
||||
|
||||
type GetByViewerOptions = {
|
||||
@@ -21,7 +21,7 @@ export type WebhooksByViewer = {
|
||||
|
||||
export const getByViewerHandler = async ({ ctx }: GetByViewerOptions): Promise<WebhooksByViewer> => {
|
||||
// Use the singleton instance to avoid creating new instances repeatedly
|
||||
const webhookRepository = WebhookRepository.getInstance();
|
||||
const { repository: webhookRepository } = getWebhookFeature();
|
||||
return await webhookRepository.getFilteredWebhooksForUser({
|
||||
userId: ctx.user.id,
|
||||
userRole: ctx.user.role,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { getWebhookFeature } from "@calcom/features/di/webhooks/containers/webhook";
|
||||
import type { Webhook } from "@calcom/features/webhooks/lib/dto/types";
|
||||
import { WebhookRepository } from "@calcom/features/webhooks/lib/repository/WebhookRepository";
|
||||
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
|
||||
|
||||
import type { TListInputSchema } from "./list.schema";
|
||||
|
||||
type ListOptions = {
|
||||
@@ -12,7 +11,7 @@ type ListOptions = {
|
||||
};
|
||||
|
||||
export const listHandler = async ({ ctx, input }: ListOptions): Promise<Webhook[]> => {
|
||||
const repository = WebhookRepository.getInstance();
|
||||
const { repository } = getWebhookFeature();
|
||||
|
||||
return repository.listWebhooks({
|
||||
userId: ctx.user.id,
|
||||
|
||||
Reference in New Issue
Block a user