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(