diff --git a/apps/web/src/pages/integrations/components/multi-provider/sort-providers.ts b/apps/web/src/pages/integrations/components/multi-provider/sort-providers.ts index 2af0347d0b4..6873cccf5df 100644 --- a/apps/web/src/pages/integrations/components/multi-provider/sort-providers.ts +++ b/apps/web/src/pages/integrations/components/multi-provider/sort-providers.ts @@ -49,6 +49,8 @@ const providers: Record = { PushProviderIdEnum.OneSignal, PushProviderIdEnum.Pushpad, PushProviderIdEnum.PusherBeams, + PushProviderIdEnum.AppIO, + PushProviderIdEnum.Pushwoosh, ], [ChannelTypeEnum.SMS]: [ SmsProviderIdEnum.Twilio, diff --git a/libs/application-generic/src/factories/push/handlers/index.ts b/libs/application-generic/src/factories/push/handlers/index.ts index a92b1ebc850..dd8cff0c738 100644 --- a/libs/application-generic/src/factories/push/handlers/index.ts +++ b/libs/application-generic/src/factories/push/handlers/index.ts @@ -5,4 +5,5 @@ export * from './one-signal.handler'; export * from './push-webhook.handler'; export * from './pusher-beams.handler'; export * from './pushpad.handler'; -export * from './appio.handler'; \ No newline at end of file +export * from './appio.handler'; +export * from './pushwoosh.handler'; \ No newline at end of file diff --git a/libs/application-generic/src/factories/push/handlers/pushwoosh.handler.ts b/libs/application-generic/src/factories/push/handlers/pushwoosh.handler.ts new file mode 100644 index 00000000000..0e55591fc3c --- /dev/null +++ b/libs/application-generic/src/factories/push/handlers/pushwoosh.handler.ts @@ -0,0 +1,20 @@ +import { PushwooshPushProvider } from '@novu/providers'; +import { ChannelTypeEnum, ICredentials, PushProviderIdEnum } from '@novu/shared'; +import { BasePushHandler } from './base.handler'; + +export class PushwooshHandler extends BasePushHandler { + constructor() { + super(PushProviderIdEnum.Pushwoosh, ChannelTypeEnum.PUSH); + } + + buildProvider(credentials: ICredentials) { + if (!credentials.apiKey || !credentials.applicationId) { + throw Error('Config is not valid for Pushwoosh'); + } + + this.provider = new PushwooshPushProvider({ + applicationId: credentials.applicationId, + apiKey: credentials.apiKey, + }); + } +} diff --git a/libs/application-generic/src/factories/push/push.factory.ts b/libs/application-generic/src/factories/push/push.factory.ts index 9ac4e6d47b4..db8748bb6fd 100644 --- a/libs/application-generic/src/factories/push/push.factory.ts +++ b/libs/application-generic/src/factories/push/push.factory.ts @@ -8,6 +8,7 @@ import { PushpadHandler, PushWebhookHandler, AppIOHandler, + PushwooshHandler, } from './handlers'; import { IPushFactory, IPushHandler } from './interfaces'; @@ -21,6 +22,7 @@ export class PushFactory implements IPushFactory { new PushWebhookHandler(), new PusherBeamsHandler(), new AppIOHandler(), + new PushwooshHandler(), ]; getHandler( diff --git a/packages/framework/src/shared.ts b/packages/framework/src/shared.ts index 0d0294fd149..91946148812 100644 --- a/packages/framework/src/shared.ts +++ b/packages/framework/src/shared.ts @@ -47,14 +47,14 @@ export interface IAttachmentOptions { export interface ITriggerPayload { attachments?: IAttachmentOptions[]; [key: string]: - | string - | string[] - | boolean - | number - | undefined - | IAttachmentOptions - | IAttachmentOptions[] - | Record; + | string + | string[] + | boolean + | number + | undefined + | IAttachmentOptions + | IAttachmentOptions[] + | Record; } export interface ISubscriberPayload { @@ -186,6 +186,7 @@ export enum PushProviderIdEnum { PushWebhook = 'push-webhook', PusherBeams = 'pusher-beams', AppIO = 'appio', + Pushwoosh = 'pushwoosh', } export enum InAppProviderIdEnum { @@ -251,8 +252,8 @@ export type WorkflowPreferences = { // TODO: This utility also exists in src/types/util.types.ts. They should be consolidated. export type DeepPartial = T extends object ? { - [P in keyof T]?: DeepPartial; - } + [P in keyof T]?: DeepPartial; + } : T; /** A partial set of workflow preferences. */ diff --git a/packages/providers/src/lib/push/index.ts b/packages/providers/src/lib/push/index.ts index 7e5bc3a73d8..3ee44ef2f05 100644 --- a/packages/providers/src/lib/push/index.ts +++ b/packages/providers/src/lib/push/index.ts @@ -5,4 +5,5 @@ export * from './one-signal/one-signal.provider'; export * from './push-webhook/push-webhook.provider'; export * from './pusher-beams/pusher-beams.provider'; export * from './pushpad/pushpad.provider'; +export * from './pushwoosh/pushwoosh.provider'; export * from './appio/appio.provider'; diff --git a/packages/providers/src/lib/push/pushwoosh/pushwoosh.provider.spec.ts b/packages/providers/src/lib/push/pushwoosh/pushwoosh.provider.spec.ts new file mode 100644 index 00000000000..e53bd6f71bf --- /dev/null +++ b/packages/providers/src/lib/push/pushwoosh/pushwoosh.provider.spec.ts @@ -0,0 +1,33 @@ +import { ChannelTypeEnum, PushProviderIdEnum } from '@novu/shared'; +import { PushwooshPushProvider } from './pushwoosh.provider'; + +describe('PushwooshPushProvider', () => { + const config = { + applicationId: 'TEST-APP-CODE', + apiKey: 'test-api-key', + }; + + test('should create provider instance', () => { + const provider = new PushwooshPushProvider(config); + expect(provider.id).toBe(PushProviderIdEnum.Pushwoosh); + expect(provider.channelType).toBe(ChannelTypeEnum.PUSH); + }); + + test('should throw not implemented error', async () => { + const provider = new PushwooshPushProvider(config); + + const options = { + title: 'Test Notification', + content: 'This is a test message', + target: ['device-token-1', 'device-token-2'], + payload: { + customData: 'test', + }, + }; + + await expect(provider.sendMessage(options)).rejects.toThrow( + 'PushwooshPushProvider.sendMessage is not implemented yet' + ); + }); +}); + diff --git a/packages/providers/src/lib/push/pushwoosh/pushwoosh.provider.ts b/packages/providers/src/lib/push/pushwoosh/pushwoosh.provider.ts new file mode 100644 index 00000000000..ea687194682 --- /dev/null +++ b/packages/providers/src/lib/push/pushwoosh/pushwoosh.provider.ts @@ -0,0 +1,31 @@ +import { + ChannelTypeEnum, + IPushOptions, + IPushProvider, + ISendMessageSuccessResponse, +} from '@novu/stateless'; +import { PushProviderIdEnum } from '@novu/shared'; +import { BaseProvider, CasingEnum } from '../../../base.provider'; + +export class PushwooshPushProvider extends BaseProvider implements IPushProvider { + id = PushProviderIdEnum.Pushwoosh; + channelType = ChannelTypeEnum.PUSH as ChannelTypeEnum.PUSH; + protected casing: CasingEnum = CasingEnum.CAMEL_CASE; + + constructor( + private config: { + applicationId: string; + apiKey: string; + } + ) { + super(); + } + + async sendMessage( + options: IPushOptions + ): Promise { + void options; + + throw new Error('PushwooshPushProvider.sendMessage is not implemented yet'); + } +} diff --git a/packages/shared/src/consts/providers/channels/push.ts b/packages/shared/src/consts/providers/channels/push.ts index 3f4ea64ad4c..60a89a67f60 100644 --- a/packages/shared/src/consts/providers/channels/push.ts +++ b/packages/shared/src/consts/providers/channels/push.ts @@ -15,6 +15,7 @@ import { oneSignalConfig, pusherBeamsConfig, pushpadConfig, + pushwooshConfig, pushWebhookConfig, } from '../credentials'; import { IProviderConfig } from '../provider.interface'; @@ -37,6 +38,14 @@ export const pushProviders: IProviderConfig[] = [ docReference: `https://docs.novu.co/platform/integrations/push/pushpad${UTM_CAMPAIGN_QUERY_PARAM}`, logoFileName: { light: 'pushpad.svg', dark: 'pushpad.svg' }, }, + { + id: PushProviderIdEnum.Pushwoosh, + displayName: 'Pushwoosh', + channel: ChannelTypeEnum.PUSH, + credentials: pushwooshConfig, + docReference: `https://docs.novu.co/platform/integrations/push/pushwoosh${UTM_CAMPAIGN_QUERY_PARAM}`, + logoFileName: { light: 'pushwoosh.svg', dark: 'pushwoosh.svg' }, + }, { id: PushProviderIdEnum.FCM, displayName: 'Firebase Cloud Messaging', diff --git a/packages/shared/src/consts/providers/credentials/provider-credentials.ts b/packages/shared/src/consts/providers/credentials/provider-credentials.ts index 2756ecd1e00..28208560c43 100644 --- a/packages/shared/src/consts/providers/credentials/provider-credentials.ts +++ b/packages/shared/src/consts/providers/credentials/provider-credentials.ts @@ -741,6 +741,22 @@ export const pushpadConfig: IConfigCredential[] = [ ...pushConfigBase, ]; +export const pushwooshConfig: IConfigCredential[] = [ + { + key: CredentialsKeyEnum.ApiKey, + displayName: 'API Access Token', + type: 'text', + required: true, + }, + { + key: CredentialsKeyEnum.ApplicationId, + displayName: 'Application Code', + type: 'text', + required: true, + }, + ...pushConfigBase, +]; + export const apnsConfig: IConfigCredential[] = [ { key: CredentialsKeyEnum.SecretKey, diff --git a/packages/shared/src/types/providers.ts b/packages/shared/src/types/providers.ts index 7516c6159d0..895fbd73999 100644 --- a/packages/shared/src/types/providers.ts +++ b/packages/shared/src/types/providers.ts @@ -146,6 +146,7 @@ export enum PushProviderIdEnum { PushWebhook = 'push-webhook', PusherBeams = 'pusher-beams', AppIO = 'appio', + Pushwoosh = 'pushwoosh', } export enum InAppProviderIdEnum {