diff --git a/apps/web/src/components/execution-detail/ExecutionDetailTrigger.tsx b/apps/web/src/components/execution-detail/ExecutionDetailTrigger.tsx index 232c0a74367..d27e17e8e9e 100644 --- a/apps/web/src/components/execution-detail/ExecutionDetailTrigger.tsx +++ b/apps/web/src/components/execution-detail/ExecutionDetailTrigger.tsx @@ -10,10 +10,10 @@ const TriggerTitle = styled(Text)` padding-bottom: 20px; `; -export const ExecutionDetailTrigger = ({ identifier, step, subscriberVariables }) => { +export const ExecutionDetailTrigger = ({ identifier, step, subscriberVariables, actorVariables }) => { const { payload, overrides } = step || {}; - const curlSnippet = getCurlTriggerSnippet(identifier, subscriberVariables, payload, overrides); + const curlSnippet = getCurlTriggerSnippet(identifier, subscriberVariables, actorVariables, payload, overrides); return ( <> diff --git a/apps/web/src/components/execution-detail/ExecutionDetailsAccordion.tsx b/apps/web/src/components/execution-detail/ExecutionDetailsAccordion.tsx index 19f5765f0f2..27b251c5df7 100644 --- a/apps/web/src/components/execution-detail/ExecutionDetailsAccordion.tsx +++ b/apps/web/src/components/execution-detail/ExecutionDetailsAccordion.tsx @@ -34,7 +34,7 @@ const useStyles = createStyles((theme) => ({ }, })); -export const ExecutionDetailsAccordion = ({ identifier, steps, subscriberVariables }) => { +export const ExecutionDetailsAccordion = ({ identifier, steps, subscriberVariables, actorVariables }) => { const { classes } = useStyles(); if (!steps || steps.length <= 0) { @@ -54,6 +54,7 @@ export const ExecutionDetailsAccordion = ({ identifier, steps, subscriberVariabl identifier={identifier} step={step} subscriberVariables={subscriberVariables} + actorVariables={actorVariables} /> diff --git a/apps/web/src/components/execution-detail/ExecutionDetailsModal.tsx b/apps/web/src/components/execution-detail/ExecutionDetailsModal.tsx index d529ab20b55..0b42b9ec8cf 100644 --- a/apps/web/src/components/execution-detail/ExecutionDetailsModal.tsx +++ b/apps/web/src/components/execution-detail/ExecutionDetailsModal.tsx @@ -44,6 +44,7 @@ export function ExecutionDetailsModal({ jobs, _digestedNotificationId: digestedNotificationId, to: subscriberVariables, + actor: actorVariables, template, } = response?.data || {}; const { triggers } = template || {}; @@ -82,7 +83,12 @@ export function ExecutionDetailsModal({ data-test-id="execution-details-modal-loading-overlay" /> - +
diff --git a/apps/web/src/components/execution-detail/ExecutionDetailsStepContent.tsx b/apps/web/src/components/execution-detail/ExecutionDetailsStepContent.tsx index 2641ed456ef..113d9cf4f70 100644 --- a/apps/web/src/components/execution-detail/ExecutionDetailsStepContent.tsx +++ b/apps/web/src/components/execution-detail/ExecutionDetailsStepContent.tsx @@ -26,7 +26,7 @@ const GridColContainer = styled(Container)` padding: 20px; `; -export const ExecutionDetailsStepContent = ({ identifier, step, subscriberVariables }) => { +export const ExecutionDetailsStepContent = ({ identifier, step, subscriberVariables, actorVariables }) => { const [detailId, setDetailId] = useState(''); const [executionDetailsRawSnippet, setExecutionDetailsRawSnippet] = useState(''); const { executionDetails } = step || {}; @@ -61,7 +61,12 @@ export const ExecutionDetailsStepContent = ({ identifier, step, subscriberVariab - + 0 && executionDetailsRawSnippet}> diff --git a/apps/web/src/pages/templates/components/TestWorkflow.tsx b/apps/web/src/pages/templates/components/TestWorkflow.tsx index 61fb84b470e..4aa11395234 100644 --- a/apps/web/src/pages/templates/components/TestWorkflow.tsx +++ b/apps/web/src/pages/templates/components/TestWorkflow.tsx @@ -25,6 +25,16 @@ const makeToValue = (subscriberVariables: INotificationTriggerVariable[], curren return JSON.stringify(subsVars, null, 2); }; +const makeActorValue = () => { + return JSON.stringify( + { + subscriberId: '', + }, + null, + 2 + ); +}; + const makePayloadValue = (variables: INotificationTriggerVariable[]) => { return JSON.stringify(getPayloadValue(variables), null, 2); }; @@ -61,11 +71,13 @@ export function TestWorkflow({ trigger }) { const form = useForm({ initialValues: { toValue: makeToValue(subscriberVariables, currentUser), + actorValue: makeActorValue(), payloadValue: makePayloadValue(variables) === '{}' ? '{\n\n}' : makePayloadValue(variables), overridesValue: overridesTrigger, }, validate: { toValue: jsonValidator, + actorValue: jsonValidator, payloadValue: jsonValidator, overridesValue: jsonValidator, }, @@ -75,8 +87,9 @@ export function TestWorkflow({ trigger }) { form.setValues({ toValue: makeToValue(subscriberVariables, currentUser) }); }, [subscriberVariables, currentUser]); - const onTrigger = async ({ toValue, payloadValue, overridesValue }) => { + const onTrigger = async ({ toValue, actorValue, payloadValue, overridesValue }) => { const to = JSON.parse(toValue); + const actor = JSON.parse(actorValue); const payload = JSON.parse(payloadValue); const overrides = JSON.parse(overridesValue); @@ -84,6 +97,7 @@ export function TestWorkflow({ trigger }) { const response = await triggerTestEvent({ name: trigger?.identifier, to, + actor, payload: { ...payload, __source: 'test-workflow', @@ -131,6 +145,17 @@ export function TestWorkflow({ trigger }) { validationError="Invalid JSON" mb={15} /> + variable.value || ''); + const actorValue = getSubscriberValue(actorVariables, (variable) => variable.value || ''); const payloadValue = getPayloadValue(trigger.variables); const prismTabs = [ { value: NODE_JS, - content: getNodeTriggerSnippet(trigger.identifier, toValue, payloadValue), + content: getNodeTriggerSnippet(trigger.identifier, toValue, actorValue, payloadValue), }, { value: CURL, - content: getCurlTriggerSnippet(trigger.identifier, toValue, payloadValue), + content: getCurlTriggerSnippet(trigger.identifier, toValue, actorValue, payloadValue), }, ]; @@ -36,6 +38,7 @@ export function TriggerSnippetTabs({ trigger }: { trigger: INotificationTrigger export const getNodeTriggerSnippet = ( identifier: string, to: Record, + actor: Record, payload: Record, overrides?: Record ) => { @@ -46,6 +49,7 @@ const novu = new Novu(''); novu.trigger('${identifier}', ${JSON.stringify( { to, + actor, payload, overrides, }, @@ -67,6 +71,7 @@ novu.trigger('${identifier}', ${JSON.stringify( export const getCurlTriggerSnippet = ( identifier: string, to: Record, + actor: Record, payload: Record, overrides?: Record ) => { @@ -77,6 +82,7 @@ export const getCurlTriggerSnippet = ( { name: identifier, to, + actor, payload, overrides, }, 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 fadd7c98ed6..150320e16ea 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 @@ -14,6 +14,7 @@ import { ChatProviderIdEnum, ExecutionDetailsSourceEnum, ExecutionDetailsStatusEnum, + ActorTypeEnum, } from '@novu/shared'; import { InstrumentUsecase, @@ -50,10 +51,18 @@ export class SendMessageChat extends SendMessageBase { @InstrumentUsecase() public async execute(command: SendMessageCommand) { - const subscriber = await this.getSubscriberBySubscriberId({ - subscriberId: command.subscriberId, - _environmentId: command.environmentId, - }); + const [subscriber, actorSubscriber] = await Promise.all([ + this.getSubscriberBySubscriberId({ + subscriberId: command.subscriberId, + _environmentId: command.environmentId, + }), + command.job._actorId + ? this.getSubscriberById({ + _id: command.job._actorId, + _environmentId: command.environmentId, + }) + : Promise.resolve(null), + ]); if (!subscriber) throw new PlatformException('Subscriber not found'); Sentry.addBreadcrumb({ @@ -70,6 +79,7 @@ export class SendMessageChat extends SendMessageBase { events: command.events, total_count: command.events?.length, }, + actor: actorSubscriber, ...command.payload, }; @@ -170,6 +180,7 @@ export class SendMessageChat extends SendMessageBase { _environmentId: command.environmentId, _organizationId: command.organizationId, _subscriberId: command._subscriberId, + _actorId: command.job._actorId, _templateId: command._templateId, _messageTemplateId: chatChannel.template?._id, channel: ChannelTypeEnum.CHAT, @@ -177,7 +188,6 @@ export class SendMessageChat extends SendMessageBase { chatWebhookUrl: chatWebhookUrl, content: this.storeContent() ? content : null, providerId: subscriberChannel.providerId, - _jobId: command.jobId, }); if (!integration) { 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 448ffe65db4..069eda78dd7 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 @@ -15,6 +15,7 @@ import { IAttachmentOptions, IEmailOptions, LogCodeEnum, + ActorTypeEnum, } from '@novu/shared'; import * as Sentry from '@sentry/node'; import { @@ -52,10 +53,18 @@ export class SendMessageEmail extends SendMessageBase { @InstrumentUsecase() public async execute(command: SendMessageCommand) { - const subscriber = await this.getSubscriberBySubscriberId({ - subscriberId: command.subscriberId, - _environmentId: command.environmentId, - }); + const [subscriber, actorSubscriber] = await Promise.all([ + this.getSubscriberBySubscriberId({ + subscriberId: command.subscriberId, + _environmentId: command.environmentId, + }), + command.job._actorId + ? this.getSubscriberById({ + _id: command.job._actorId, + _environmentId: command.environmentId, + }) + : Promise.resolve(null), + ]); if (!subscriber) throw new PlatformException(`Subscriber ${command.subscriberId} not found`); let integration: IntegrationEntity | undefined = undefined; @@ -90,6 +99,7 @@ export class SendMessageEmail extends SendMessageBase { if (!emailChannel.template) throw new PlatformException('Email channel template not found'); const email = command.payload.email || subscriber.email; + const { actor } = emailChannel.template; Sentry.addBreadcrumb({ message: 'Sending Email', @@ -143,6 +153,7 @@ export class SendMessageEmail extends SendMessageBase { total_count: command.events?.length, }, subscriber, + actor: actorSubscriber, }, }; @@ -165,6 +176,11 @@ export class SendMessageEmail extends SendMessageBase { overrides, templateIdentifier: command.identifier, _jobId: command.jobId, + ...(actor && + actor.type !== ActorTypeEnum.NONE && { + actor, + _actorId: command.job?._actorId, + }), }); let replyToAddress: string | undefined; diff --git a/apps/worker/src/app/workflow/usecases/send-message/send-message-in-app.usecase.ts b/apps/worker/src/app/workflow/usecases/send-message/send-message-in-app.usecase.ts index 95b749f1b62..07a1f516ac1 100644 --- a/apps/worker/src/app/workflow/usecases/send-message/send-message-in-app.usecase.ts +++ b/apps/worker/src/app/workflow/usecases/send-message/send-message-in-app.usecase.ts @@ -56,10 +56,18 @@ export class SendMessageInApp extends SendMessageBase { @InstrumentUsecase() public async execute(command: SendMessageCommand) { - const subscriber = await this.getSubscriberBySubscriberId({ - subscriberId: command.subscriberId, - _environmentId: command.environmentId, - }); + const [subscriber, actorSubscriber] = await Promise.all([ + this.getSubscriberBySubscriberId({ + subscriberId: command.subscriberId, + _environmentId: command.environmentId, + }), + command.job._actorId + ? this.getSubscriberById({ + _id: command.job._actorId, + _environmentId: command.environmentId, + }) + : Promise.resolve(null), + ]); if (!subscriber) throw new PlatformException('Subscriber not found'); if (!command.step.template) throw new PlatformException('Template not found'); @@ -103,6 +111,7 @@ export class SendMessageInApp extends SendMessageBase { inAppChannel.template.content, command.payload, subscriber, + actorSubscriber, command, organization ); @@ -112,6 +121,7 @@ export class SendMessageInApp extends SendMessageBase { inAppChannel.template.cta?.data?.url, command.payload, subscriber, + actorSubscriber, command, organization ); @@ -125,6 +135,7 @@ export class SendMessageInApp extends SendMessageBase { action.content, command.payload, subscriber, + actorSubscriber, command, organization ); @@ -146,6 +157,7 @@ export class SendMessageInApp extends SendMessageBase { _notificationId: command.notificationId, _environmentId: command.environmentId, _subscriberId: command._subscriberId, + _actorId: command.job._actorId, _templateId: command._templateId, _messageTemplateId: inAppChannel.template._id, channel: ChannelTypeEnum.IN_APP, @@ -299,6 +311,7 @@ export class SendMessageInApp extends SendMessageBase { content: string | IEmailBlock[], payload: any, subscriber: SubscriberEntity, + actor: SubscriberEntity | null, command: SendMessageCommand, organization: OrganizationEntity | null ): Promise { @@ -316,6 +329,7 @@ export class SendMessageInApp extends SendMessageBase { logo: organization?.branding?.logo, color: organization?.branding?.color || '#f47373', }, + actor, ...payload, }, }) 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 90238b3ec85..e5e5558ed2d 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 @@ -48,10 +48,18 @@ export class SendMessagePush extends SendMessageBase { @InstrumentUsecase() public async execute(command: SendMessageCommand) { - const subscriber = await this.getSubscriberBySubscriberId({ - subscriberId: command.subscriberId, - _environmentId: command.environmentId, - }); + const [subscriber, actorSubscriber] = await Promise.all([ + this.getSubscriberBySubscriberId({ + subscriberId: command.subscriberId, + _environmentId: command.environmentId, + }), + command.job._actorId + ? this.getSubscriberById({ + _id: command.job._actorId, + _environmentId: command.environmentId, + }) + : Promise.resolve(null), + ]); if (!subscriber) throw new PlatformException(`Subscriber not found`); Sentry.addBreadcrumb({ @@ -67,6 +75,7 @@ export class SendMessagePush extends SendMessageBase { }; const data = { subscriber: subscriber, + actor: actorSubscriber, step: stepData, ...command.payload, }; @@ -194,6 +203,7 @@ export class SendMessagePush extends SendMessageBase { _environmentId: command.environmentId, _organizationId: command.organizationId, _subscriberId: command._subscriberId, + _actorId: command.job._actorId, _templateId: command._templateId, _messageTemplateId: command.step?.template?._id, channel: ChannelTypeEnum.PUSH, 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 4829c5c03e6..423161652aa 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 @@ -7,7 +7,13 @@ import { MessageEntity, IntegrationEntity, } from '@novu/dal'; -import { ChannelTypeEnum, LogCodeEnum, ExecutionDetailsSourceEnum, ExecutionDetailsStatusEnum } from '@novu/shared'; +import { + ChannelTypeEnum, + LogCodeEnum, + ExecutionDetailsSourceEnum, + ExecutionDetailsStatusEnum, + ActorTypeEnum, +} from '@novu/shared'; import { InstrumentUsecase, DetailEnum, @@ -42,10 +48,18 @@ export class SendMessageSms extends SendMessageBase { @InstrumentUsecase() public async execute(command: SendMessageCommand) { - const subscriber = await this.getSubscriberBySubscriberId({ - subscriberId: command.subscriberId, - _environmentId: command.environmentId, - }); + const [subscriber, actorSubscriber] = await Promise.all([ + this.getSubscriberBySubscriberId({ + subscriberId: command.subscriberId, + _environmentId: command.environmentId, + }), + command.job._actorId + ? this.getSubscriberById({ + _id: command.job._actorId, + _environmentId: command.environmentId, + }) + : Promise.resolve(null), + ]); if (!subscriber) throw new PlatformException('Subscriber not found'); const overrideSelectedIntegration = command.overrides?.sms?.integrationIdentifier; @@ -65,8 +79,11 @@ export class SendMessageSms extends SendMessageBase { const smsChannel: NotificationStepEntity = command.step; if (!smsChannel.template) throw new PlatformException(`Unexpected error: SMS template is missing`); + const { actor } = smsChannel.template; + const payload = { subscriber: subscriber, + actor: actorSubscriber, step: { digest: !!command.events?.length, events: command.events, @@ -141,6 +158,11 @@ export class SendMessageSms extends SendMessageBase { overrides, templateIdentifier: command.identifier, _jobId: command.jobId, + ...(actor && + actor.type !== ActorTypeEnum.NONE && { + actor, + _actorId: command.job?._actorId, + }), }); await this.createExecutionDetails.execute( diff --git a/apps/worker/src/app/workflow/usecases/send-message/send-message.base.ts b/apps/worker/src/app/workflow/usecases/send-message/send-message.base.ts index d36b46f95bd..17fb539e37a 100644 --- a/apps/worker/src/app/workflow/usecases/send-message/send-message.base.ts +++ b/apps/worker/src/app/workflow/usecases/send-message/send-message.base.ts @@ -2,6 +2,7 @@ import { IntegrationEntity, JobEntity, MessageRepository, SubscriberRepository } import { ChannelTypeEnum, ExecutionDetailsSourceEnum, ExecutionDetailsStatusEnum } from '@novu/shared'; import { buildSubscriberKey, + buildSubscriberIdentifierKey, CachedEntity, DetailEnum, CreateExecutionDetails, @@ -45,6 +46,20 @@ export abstract class SendMessageBase extends SendMessageType { }); } + @CachedEntity({ + builder: (command: { _id: string; _environmentId: string }) => + buildSubscriberIdentifierKey({ + _environmentId: command._environmentId, + _id: command._id, + }), + }) + protected async getSubscriberById({ _id, _environmentId }: { _id: string; _environmentId: string }) { + return await this.subscriberRepository.findOne({ + _environmentId, + _id, + }); + } + protected async getIntegration( selectIntegrationCommand: SelectIntegrationCommand ): Promise { diff --git a/libs/dal/src/repositories/notification/notification.entity.ts b/libs/dal/src/repositories/notification/notification.entity.ts index a508f9ec293..414fb4a98cf 100644 --- a/libs/dal/src/repositories/notification/notification.entity.ts +++ b/libs/dal/src/repositories/notification/notification.entity.ts @@ -16,6 +16,8 @@ export class NotificationEntity { _subscriberId: string; + _actorId?: string; + transactionId: string; template?: NotificationTemplateEntity; @@ -27,6 +29,9 @@ export class NotificationEntity { // eslint-disable-next-line @typescript-eslint/no-explicit-any to?: any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + actor?: any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any payload?: any; @@ -37,5 +42,5 @@ export class NotificationEntity { export type NotificationDBModel = ChangePropsValueType< NotificationEntity, - '_environmentId' | '_organizationId' | '_templateId' | '_subscriberId' + '_environmentId' | '_organizationId' | '_templateId' | '_subscriberId' | '_actorId' >; diff --git a/libs/dal/src/repositories/notification/notification.repository.ts b/libs/dal/src/repositories/notification/notification.repository.ts index f0bb504403a..918c4ed566d 100644 --- a/libs/dal/src/repositories/notification/notification.repository.ts +++ b/libs/dal/src/repositories/notification/notification.repository.ts @@ -93,6 +93,13 @@ export class NotificationRepository extends BaseRepository< path: 'subscriber', select: 'firstName _id lastName email phone subscriberId', }) + .populate({ + options: { + readPreference: 'secondaryPreferred', + }, + path: 'actorSubscriber', + select: 'firstName _id lastName avatar subscriberId', + }) .populate({ options: { readPreference: 'secondaryPreferred', diff --git a/libs/dal/src/repositories/notification/notification.schema.ts b/libs/dal/src/repositories/notification/notification.schema.ts index a9c50e2c4d9..b15674a07b7 100644 --- a/libs/dal/src/repositories/notification/notification.schema.ts +++ b/libs/dal/src/repositories/notification/notification.schema.ts @@ -39,9 +39,16 @@ const notificationSchema = new Schema( _digestedNotificationId: { type: Schema.Types.String, }, + _actorId: { + type: Schema.Types.ObjectId, + ref: 'Subscriber', + }, to: { type: Schema.Types.Mixed, }, + actor: { + type: Schema.Types.Mixed, + }, payload: { type: Schema.Types.Mixed, }, @@ -80,6 +87,13 @@ notificationSchema.virtual('subscriber', { justOne: true, }); +notificationSchema.virtual('actorSubscriber', { + ref: 'Subscriber', + localField: '_actorId', + foreignField: '_id', + justOne: true, +}); + notificationSchema.virtual('jobs', { ref: 'Job', localField: '_id', diff --git a/libs/shared/src/entities/message-template/message-template.interface.ts b/libs/shared/src/entities/message-template/message-template.interface.ts index 9f36a11a65b..a277181b83e 100644 --- a/libs/shared/src/entities/message-template/message-template.interface.ts +++ b/libs/shared/src/entities/message-template/message-template.interface.ts @@ -37,7 +37,7 @@ export interface IMessageTemplate { } // eslint-disable-next-line @typescript-eslint/naming-convention -export const TemplateSystemVariables = ['subscriber', 'step', 'branding', 'preheader']; +export const TemplateSystemVariables = ['subscriber', 'actor', 'step', 'branding', 'preheader']; // eslint-disable-next-line @typescript-eslint/naming-convention export const SystemVariablesWithTypes = { @@ -50,6 +50,12 @@ export const SystemVariablesWithTypes = { locale: 'string', subscriberId: 'string', }, + actor: { + firstName: 'string', + lastName: 'string', + avatar: 'string', + subscriberId: 'string', + }, step: { digest: 'boolean', events: 'array', diff --git a/packages/application-generic/src/services/cache/key-builders/entities.ts b/packages/application-generic/src/services/cache/key-builders/entities.ts index cf929003988..43c1d635a7c 100644 --- a/packages/application-generic/src/services/cache/key-builders/entities.ts +++ b/packages/application-generic/src/services/cache/key-builders/entities.ts @@ -23,6 +23,21 @@ const buildSubscriberKey = ({ identifier: subscriberId, }); +const buildSubscriberIdentifierKey = ({ + _id, + _environmentId, +}: { + _id: string; + _environmentId: string; +}): string => + buildCommonKey({ + type: CacheKeyTypeEnum.ENTITY, + keyEntity: CacheKeyPrefixEnum.SUBSCRIBER, + environmentId: _environmentId, + identifierPrefix: IdentifierPrefixEnum.ID, + identifier: _id, + }); + const buildUserKey = ({ _id }: { _id: string }): string => buildKeyById({ type: CacheKeyTypeEnum.ENTITY, @@ -94,6 +109,7 @@ const buildGroupedBlueprintsKey = (): string => export { buildUserKey, buildSubscriberKey, + buildSubscriberIdentifierKey, buildNotificationTemplateKey, buildNotificationTemplateIdentifierKey, buildEnvironmentByApiKey, diff --git a/packages/application-generic/src/usecases/create-notification-jobs/create-notification-jobs.command.ts b/packages/application-generic/src/usecases/create-notification-jobs/create-notification-jobs.command.ts index fdb3621d3b1..358c56e423b 100644 --- a/packages/application-generic/src/usecases/create-notification-jobs/create-notification-jobs.command.ts +++ b/packages/application-generic/src/usecases/create-notification-jobs/create-notification-jobs.command.ts @@ -32,10 +32,13 @@ export class CreateNotificationJobsCommand extends EnvironmentWithUserCommand { @IsDefined() to: ISubscribersDefine; + @IsOptional() + actor?: ISubscribersDefine; + @IsString() @IsDefined() transactionId: string; @IsOptional() - actor?: SubscriberEntity; + actorSubscriber?: SubscriberEntity; } diff --git a/packages/application-generic/src/usecases/create-notification-jobs/create-notification-jobs.usecase.ts b/packages/application-generic/src/usecases/create-notification-jobs/create-notification-jobs.usecase.ts index bcf2f9d1f35..7706aad7707 100644 --- a/packages/application-generic/src/usecases/create-notification-jobs/create-notification-jobs.usecase.ts +++ b/packages/application-generic/src/usecases/create-notification-jobs/create-notification-jobs.usecase.ts @@ -71,6 +71,8 @@ export class CreateNotificationJobs { payload: command.payload, expireAt: this.calculateExpireAt(command), channels, + ...(command.actorSubscriber && { _actorId: command.actorSubscriber._id }), + ...(command.actor && { actor: command.actor }), }); if (!notification) { @@ -109,7 +111,9 @@ export class CreateNotificationJobs { type: step.template.type, providerId: providerId, expireAt: notification.expireAt, - ...(command.actor && { _actorId: command.actor?._id }), + ...(command.actorSubscriber && { + _actorId: command.actorSubscriber._id, + }), }; jobs.push(job); diff --git a/packages/application-generic/src/usecases/send-test-email/send-test-email.usecase.ts b/packages/application-generic/src/usecases/send-test-email/send-test-email.usecase.ts index 2e6f2dc4458..c8fecf9db50 100644 --- a/packages/application-generic/src/usecases/send-test-email/send-test-email.usecase.ts +++ b/packages/application-generic/src/usecases/send-test-email/send-test-email.usecase.ts @@ -67,6 +67,7 @@ export class SendTestEmail { ...this.getSystemVariables('step', command), }, subscriber: this.getSystemVariables('subscriber', command), + actor: this.getSystemVariables('actor', command), }, }) ); @@ -124,7 +125,7 @@ export class SendTestEmail { } private getSystemVariables( - variableType: 'subscriber' | 'step' | 'branding', + variableType: 'subscriber' | 'actor' | 'step' | 'branding', command: SendTestEmailCommand ) { const variables = {}; diff --git a/packages/application-generic/src/usecases/trigger-event/trigger-event.usecase.ts b/packages/application-generic/src/usecases/trigger-event/trigger-event.usecase.ts index ac89a27101e..b151836309d 100644 --- a/packages/application-generic/src/usecases/trigger-event/trigger-event.usecase.ts +++ b/packages/application-generic/src/usecases/trigger-event/trigger-event.usecase.ts @@ -161,7 +161,8 @@ export class TriggerEvent { to: subscriber, transactionId: command.transactionId, userId, - ...(actor && actorProcessed && { actor: actorProcessed }), + ...(actor && + actorProcessed && { actor, actorSubscriber: actorProcessed }), }); const notificationJobs = await this.createNotificationJobs.execute(