diff --git a/apps/api/src/app/events/dtos/trigger-event-request.dto.ts b/apps/api/src/app/events/dtos/trigger-event-request.dto.ts index 75145e2b0b7..8ec80599976 100644 --- a/apps/api/src/app/events/dtos/trigger-event-request.dto.ts +++ b/apps/api/src/app/events/dtos/trigger-event-request.dto.ts @@ -6,6 +6,7 @@ import { TriggerRecipientsTypeEnum, TriggerRecipientSubscriber, TriggerTenantContext, + TriggerOverrides, } from '@novu/shared'; import { CreateSubscriberRequestDto } from '../../subscribers/dtos'; import { UpdateTenantRequestDto } from '../../tenant/dtos'; @@ -99,7 +100,7 @@ export class TriggerEventRequestDto { }) @IsObject() @IsOptional() - overrides?: Record>; + overrides?: TriggerOverrides; @ApiProperty({ description: 'The recipients list of people who will receive the notification.', diff --git a/apps/api/src/app/events/events.controller.ts b/apps/api/src/app/events/events.controller.ts index 3437769e161..4e9ff0ccfb2 100644 --- a/apps/api/src/app/events/events.controller.ts +++ b/apps/api/src/app/events/events.controller.ts @@ -80,7 +80,7 @@ export class EventsController { organizationId: user.organizationId, identifier: body.name, payload: body.payload || {}, - overrides: body.overrides || {}, + overrides: body.overrides || ({} as any), to: body.to, actor: body.actor, tenant: body.tenant, diff --git a/apps/api/src/app/events/usecases/parse-event-request/parse-event-request.command.ts b/apps/api/src/app/events/usecases/parse-event-request/parse-event-request.command.ts index bb2af9cde75..66ff5a57d51 100644 --- a/apps/api/src/app/events/usecases/parse-event-request/parse-event-request.command.ts +++ b/apps/api/src/app/events/usecases/parse-event-request/parse-event-request.command.ts @@ -6,6 +6,7 @@ import { TriggerRecipientSubscriber, TriggerRequestCategoryEnum, TriggerTenantContext, + TriggerOverrides, } from '@novu/shared'; import { EnvironmentWithUserCommand } from '../../../shared/commands/project.command'; @@ -19,7 +20,7 @@ export class ParseEventRequestBaseCommand extends EnvironmentWithUserCommand { payload: any; // eslint-disable-line @typescript-eslint/no-explicit-any @IsDefined() - overrides: Record>; + overrides: TriggerOverrides | {}; @IsString() @IsOptional() diff --git a/apps/api/src/app/events/usecases/process-bulk-trigger/process-bulk-trigger.usecase.ts b/apps/api/src/app/events/usecases/process-bulk-trigger/process-bulk-trigger.usecase.ts index 64f3d701de2..ad7af3b9cd9 100644 --- a/apps/api/src/app/events/usecases/process-bulk-trigger/process-bulk-trigger.usecase.ts +++ b/apps/api/src/app/events/usecases/process-bulk-trigger/process-bulk-trigger.usecase.ts @@ -23,7 +23,7 @@ export class ProcessBulkTrigger { organizationId: command.organizationId, identifier: event.name, payload: event.payload, - overrides: event.overrides || {}, + overrides: event.overrides || ({} as any), to: event.to, actor: event.actor, tenant: event.tenant, diff --git a/apps/api/src/app/events/usecases/trigger-event-to-all/trigger-event-to-all.usecase.ts b/apps/api/src/app/events/usecases/trigger-event-to-all/trigger-event-to-all.usecase.ts index d789641ecdd..9b297783382 100644 --- a/apps/api/src/app/events/usecases/trigger-event-to-all/trigger-event-to-all.usecase.ts +++ b/apps/api/src/app/events/usecases/trigger-event-to-all/trigger-event-to-all.usecase.ts @@ -1,5 +1,4 @@ import { Injectable } from '@nestjs/common'; -import { SubscriberRepository } from '@novu/dal'; import { AddressingTypeEnum, TriggerEventStatusEnum, TriggerRequestCategoryEnum } from '@novu/shared'; import { TriggerEventToAllCommand } from './trigger-event-to-all.command'; @@ -7,10 +6,7 @@ import { ParseEventRequest, ParseEventRequestBroadcastCommand } from '../parse-e @Injectable() export class TriggerEventToAll { - constructor( - private subscriberRepository: SubscriberRepository, - private parseEventRequest: ParseEventRequest - ) {} + constructor(private parseEventRequest: ParseEventRequest) {} public async execute(command: TriggerEventToAllCommand) { await this.parseEventRequest.execute( @@ -22,7 +18,7 @@ export class TriggerEventToAll { payload: command.payload || {}, addressingType: AddressingTypeEnum.BROADCAST, transactionId: command.transactionId, - overrides: command.overrides || {}, + overrides: command.overrides || ({} as any), actor: command.actor, tenant: command.tenant, requestCategory: TriggerRequestCategoryEnum.SINGLE, diff --git a/apps/worker/src/app/workflow/usecases/send-message/send-message-chat.usecase.ts b/apps/worker/src/app/workflow/usecases/send-message/send-message-chat.usecase.ts index 7a72a6224be..a24698d67f6 100644 --- a/apps/worker/src/app/workflow/usecases/send-message/send-message-chat.usecase.ts +++ b/apps/worker/src/app/workflow/usecases/send-message/send-message-chat.usecase.ts @@ -393,9 +393,12 @@ export class SendMessageChat extends SendMessageBase { ...(command.overrides[integration?.providerId] || {}), }; const bridgeProviderData = command.bridgeData?.providers?.[integration.providerId] || {}; + const triggerOverrides = command.step.stepId + ? command.overrides?.steps?.[command.step.stepId]?.providers[integration.providerId] || {} + : {}; const result = await chatHandler.send({ - bridgeProviderData, + bridgeProviderData: { ...bridgeProviderData, ...triggerOverrides }, phoneNumber, customData: overrides, webhookUrl: chatWebhookUrl, diff --git a/apps/worker/src/app/workflow/usecases/send-message/send-message-email.usecase.ts b/apps/worker/src/app/workflow/usecases/send-message/send-message-email.usecase.ts index c33993a9e85..9ea289223ab 100644 --- a/apps/worker/src/app/workflow/usecases/send-message/send-message-email.usecase.ts +++ b/apps/worker/src/app/workflow/usecases/send-message/send-message-email.usecase.ts @@ -5,7 +5,6 @@ import { addBreadcrumb } from '@sentry/node'; import { MessageRepository, - NotificationStepEntity, SubscriberRepository, EnvironmentRepository, IntegrationEntity, @@ -440,9 +439,15 @@ export class SendMessageEmail extends SendMessageBase { const mailFactory = new MailFactory(); const mailHandler = mailFactory.getHandler(this.buildFactoryIntegration(integration), mailData.from); const bridgeProviderData = command.bridgeData?.providers?.[integration.providerId] || {}; + const triggerOverrides = command.step.stepId + ? command.overrides?.steps?.[command.step.stepId]?.providers[integration.providerId] || {} + : {}; try { - const result = await mailHandler.send({ ...mailData, bridgeProviderData }); + const result = await mailHandler.send({ + ...mailData, + bridgeProviderData: { ...bridgeProviderData, ...triggerOverrides }, + }); Logger.verbose({ command }, 'Email message has been sent', LOG_CONTEXT); diff --git a/apps/worker/src/app/workflow/usecases/send-message/send-message-push.usecase.ts b/apps/worker/src/app/workflow/usecases/send-message/send-message-push.usecase.ts index 05265551636..c17cfac850e 100644 --- a/apps/worker/src/app/workflow/usecases/send-message/send-message-push.usecase.ts +++ b/apps/worker/src/app/workflow/usecases/send-message/send-message-push.usecase.ts @@ -2,14 +2,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { addBreadcrumb } from '@sentry/node'; import { ModuleRef } from '@nestjs/core'; -import { - MessageRepository, - NotificationStepEntity, - SubscriberRepository, - MessageEntity, - IntegrationEntity, - JobEntity, -} from '@novu/dal'; +import { MessageRepository, SubscriberRepository, MessageEntity, IntegrationEntity, JobEntity } from '@novu/dal'; import { ChannelTypeEnum, LogCodeEnum, @@ -298,6 +291,9 @@ export class SendMessagePush extends SendMessageBase { const pushHandler = this.getIntegrationHandler(integration); const bridgeOutputs = command.bridgeData?.outputs; const bridgeProviderData = command.bridgeData?.providers?.[integration.providerId] || {}; + const triggerOverrides = command.step.stepId + ? command.overrides?.steps?.[command.step.stepId]?.providers[integration.providerId] || {} + : {}; const result = await pushHandler.send({ target: [deviceToken], @@ -307,7 +303,7 @@ export class SendMessagePush extends SendMessageBase { overrides, subscriber, step, - bridgeProviderData, + bridgeProviderData: { ...bridgeProviderData, ...triggerOverrides }, }); await this.executionLogRoute.execute( diff --git a/apps/worker/src/app/workflow/usecases/send-message/send-message-sms.usecase.ts b/apps/worker/src/app/workflow/usecases/send-message/send-message-sms.usecase.ts index 247a602d953..7895a8cd695 100644 --- a/apps/worker/src/app/workflow/usecases/send-message/send-message-sms.usecase.ts +++ b/apps/worker/src/app/workflow/usecases/send-message/send-message-sms.usecase.ts @@ -2,13 +2,7 @@ import { Injectable } from '@nestjs/common'; import { addBreadcrumb } from '@sentry/node'; import { ModuleRef } from '@nestjs/core'; -import { - MessageRepository, - NotificationStepEntity, - SubscriberRepository, - MessageEntity, - IntegrationEntity, -} from '@novu/dal'; +import { MessageRepository, SubscriberRepository, MessageEntity, IntegrationEntity } from '@novu/dal'; import { ChannelTypeEnum, LogCodeEnum, ExecutionDetailsSourceEnum, ExecutionDetailsStatusEnum } from '@novu/shared'; import { InstrumentUsecase, @@ -276,6 +270,9 @@ export class SendMessageSms extends SendMessageBase { throw new PlatformException(`Sms handler for provider ${integration.providerId} is not found`); } const bridgeProviderData = command.bridgeData?.providers?.[integration.providerId] || {}; + const triggerOverrides = command.step.stepId + ? command.overrides?.steps?.[command.step.stepId]?.providers[integration.providerId] || {} + : {}; const result = await smsHandler.send({ to: overrides.to || phone, @@ -283,7 +280,7 @@ export class SendMessageSms extends SendMessageBase { content: bridgeBody || overrides.content || content, id: message._id, customData: overrides.customData || {}, - bridgeProviderData, + bridgeProviderData: { ...bridgeProviderData, ...triggerOverrides }, }); await this.executionLogRoute.execute( diff --git a/apps/worker/src/app/workflow/usecases/send-message/send-message.command.ts b/apps/worker/src/app/workflow/usecases/send-message/send-message.command.ts index b4ae980e29c..e0074700f2e 100644 --- a/apps/worker/src/app/workflow/usecases/send-message/send-message.command.ts +++ b/apps/worker/src/app/workflow/usecases/send-message/send-message.command.ts @@ -2,7 +2,7 @@ import { IsDefined, IsOptional, IsString } from 'class-validator'; import { NotificationStepEntity, JobEntity } from '@novu/dal'; import { EnvironmentWithUserCommand } from '@novu/application-generic'; import { ExecuteOutput } from '@novu/framework/internal'; -import { WorkflowPreferences } from '@novu/shared'; +import { WorkflowPreferences, TriggerOverrides } from '@novu/shared'; export class SendMessageCommand extends EnvironmentWithUserCommand { @IsDefined() @@ -16,7 +16,7 @@ export class SendMessageCommand extends EnvironmentWithUserCommand { compileContext?: any; // eslint-disable-line @typescript-eslint/no-explicit-any @IsDefined() - overrides: Record>; + overrides: TriggerOverrides; @IsDefined() step: NotificationStepEntity; diff --git a/packages/framework/src/index.ts b/packages/framework/src/index.ts index 754f749c5d4..1f4b7e7dc88 100644 --- a/packages/framework/src/index.ts +++ b/packages/framework/src/index.ts @@ -3,3 +3,4 @@ export { NovuRequestHandler, type ServeHandlerOptions } from './handler'; export { workflow } from './resources'; export type { Workflow } from './types'; export { CronExpression } from './constants'; +export { providerSchemas } from './schemas'; diff --git a/packages/shared/src/dto/events/event.interface.ts b/packages/shared/src/dto/events/event.interface.ts index 7f8aa7870b3..1848d02b583 100644 --- a/packages/shared/src/dto/events/event.interface.ts +++ b/packages/shared/src/dto/events/event.interface.ts @@ -1,4 +1,4 @@ -import { ISubscribersDefine, ITenantDefine, ITopic } from '../../types'; +import { ISubscribersDefine, ITenantDefine, ITopic, ProvidersIdEnum } from '../../types'; export type TriggerRecipientSubscriber = string | ISubscribersDefine; @@ -9,3 +9,13 @@ export type TriggerRecipients = TriggerRecipient[]; export type TriggerRecipientsPayload = TriggerRecipientSubscriber | TriggerRecipients; export type TriggerTenantContext = string | ITenantDefine; + +export type TriggerOverrides = { + steps: Record< + string, + { + providers: Record>; + } + >; + [key: string]: Record>; +};