Skip to content

Commit

Permalink
feat(providers): improve expo response management and multi device token
Browse files Browse the repository at this point in the history
  • Loading branch information
p-fernandez committed Oct 12, 2023
1 parent f3de39a commit 612e10d
Show file tree
Hide file tree
Showing 5 changed files with 280 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
SelectIntegration,
CompileTemplate,
CompileTemplateCommand,
IPushHandler,
PushFactory,
GetNovuProviderCredentials,
} from '@novu/application-generic';
Expand All @@ -43,6 +44,8 @@ const LOG_CONTEXT = 'SendMessagePush';
export class SendMessagePush extends SendMessageBase {
channelType = ChannelTypeEnum.PUSH;

private pushFactory;

constructor(
protected subscriberRepository: SubscriberRepository,
protected messageRepository: MessageRepository,
Expand All @@ -62,6 +65,8 @@ export class SendMessagePush extends SendMessageBase {
selectIntegration,
getNovuProviderCredentials
);

this.pushFactory = new PushFactory();
}

@InstrumentUsecase()
Expand Down Expand Up @@ -148,21 +153,26 @@ export class SendMessagePush extends SendMessageBase {
await this.sendSelectedIntegrationExecution(command.job, integration);

const overrides = command.overrides[integration.providerId] || {};

const result = await this.sendMessage(
subscriber,
integration,
deviceTokens,
title,
content,
command,
command.payload,
overrides,
stepData
);

if (!result) {
integrationsWithErrors++;
const target = (overrides as { deviceTokens?: string[] }).deviceTokens || deviceTokens;

const message = await this.createMessage(command, integration, title, content, target, overrides);

for (const deviceToken of target) {
const result = await this.sendMessage(
command,
message,
subscriber,
integration,
deviceToken,
title,
content,
overrides,
stepData
);

if (!result) {
integrationsWithErrors++;
}
}
}

Expand Down Expand Up @@ -273,59 +283,24 @@ export class SendMessagePush extends SendMessageBase {
}

private async sendMessage(
command: SendMessageCommand,
message: MessageEntity,
subscriber: IPushOptions['subscriber'],
integration: IntegrationEntity,
target: string[],
deviceToken: string,
title: string,
content: string,
command: SendMessageCommand,
payload: object,
overrides: object,
step: IPushOptions['step']
): Promise<boolean> {
const message: MessageEntity = await this.messageRepository.create({
_notificationId: command.notificationId,
_environmentId: command.environmentId,
_organizationId: command.organizationId,
_subscriberId: command._subscriberId,
_templateId: command._templateId,
_messageTemplateId: command.step?.template?._id,
channel: ChannelTypeEnum.PUSH,
transactionId: command.transactionId,
deviceTokens: target,
content: this.storeContent() ? content : null,
title,
payload: payload as never,
overrides: overrides as never,
providerId: integration.providerId,
_jobId: command.jobId,
});

await this.createExecutionDetails.execute(
CreateExecutionDetailsCommand.create({
...CreateExecutionDetailsCommand.getDetailsFromJob(command.job),
detail: `${DetailEnum.MESSAGE_CREATED}: ${integration.providerId}`,
source: ExecutionDetailsSourceEnum.INTERNAL,
status: ExecutionDetailsStatusEnum.PENDING,
messageId: message._id,
isTest: false,
isRetry: false,
raw: this.storeContent() ? JSON.stringify(content) : null,
})
);

try {
const pushFactory = new PushFactory();
const pushHandler = pushFactory.getHandler(integration);
if (!pushHandler) {
throw new PlatformException(`Push handler for provider ${integration.providerId} is not found`);
}
const pushHandler = this.getIntegrationHandler(integration);

const result = await pushHandler.send({
target: (overrides as { deviceTokens?: string[] }).deviceTokens || target,
target: [deviceToken],
title,
content,
payload,
payload: command.payload,
overrides,
subscriber,
step,
Expand All @@ -340,7 +315,7 @@ export class SendMessagePush extends SendMessageBase {
status: ExecutionDetailsStatusEnum.SUCCESS,
isTest: false,
isRetry: false,
raw: JSON.stringify(result),
raw: JSON.stringify({ result, deviceToken }),
})
);

Expand All @@ -363,4 +338,57 @@ export class SendMessagePush extends SendMessageBase {
return false;
}
}

private async createMessage(
command: SendMessageCommand,
integration: IntegrationEntity,
title: string,
content: string,
deviceTokens: string[],
overrides: object
): Promise<MessageEntity> {
const message = await this.messageRepository.create({
_notificationId: command.notificationId,
_environmentId: command.environmentId,
_organizationId: command.organizationId,
_subscriberId: command._subscriberId,
_templateId: command._templateId,
_messageTemplateId: command.step?.template?._id,
channel: ChannelTypeEnum.PUSH,
transactionId: command.transactionId,
deviceTokens,
content: this.storeContent() ? content : null,
title,
payload: command.payload as never,
overrides: overrides as never,
providerId: integration.providerId,
_jobId: command.jobId,
});

await this.createExecutionDetails.execute(
CreateExecutionDetailsCommand.create({
...CreateExecutionDetailsCommand.getDetailsFromJob(command.job),
detail: `${DetailEnum.MESSAGE_CREATED}: ${integration.providerId}`,
source: ExecutionDetailsSourceEnum.INTERNAL,
status: ExecutionDetailsStatusEnum.PENDING,
messageId: message._id,
isTest: false,
isRetry: false,
raw: this.storeContent() ? JSON.stringify(content) : null,
})
);

return message;
}

private getIntegrationHandler(integration): IPushHandler {
const pushHandler = this.pushFactory.getHandler(integration);

if (!pushHandler) {
const message = `Push handler for provider ${integration.providerId} is not found`;
throw new PlatformException(message);
}

return pushHandler;
}
}
1 change: 1 addition & 0 deletions packages/application-generic/src/factories/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export * from './chat/chat.factory';
export * from './sms/sms.factory';
export * from './mail/mail.factory';
export * from './push/push.factory';
export * from './push/interfaces/push.handler.interface';
export * from './sms/interfaces';
export * from './mail/interfaces/send.handler.interface';
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class PushFactory implements IPushFactory {
new PushWebhookHandler(),
];

getHandler(integration: IntegrationEntity) {
getHandler(integration: IntegrationEntity): IPushHandler {
const handler =
this.handlers.find((handlerItem) =>
handlerItem.canHandle(integration.providerId, integration.channel)
Expand Down
Loading

0 comments on commit 612e10d

Please sign in to comment.