diff --git a/apps/api/src/app.module.ts b/apps/api/src/app.module.ts index 5dd2a03ec44..d9c31a884f6 100644 --- a/apps/api/src/app.module.ts +++ b/apps/api/src/app.module.ts @@ -38,6 +38,7 @@ import { ApiRateLimitInterceptor } from './app/rate-limiting/guards'; import { RateLimitingModule } from './app/rate-limiting/rate-limiting.module'; import { ProductFeatureInterceptor } from './app/shared/interceptors/product-feature.interceptor'; import { ResourceThrottlerInterceptor } from './app/resource-limiting/guards'; +import { AnalyticsModule } from './app/analytics/analytics.module'; const enterpriseImports = (): Array | ForwardReference> => { const modules: Array | ForwardReference> = []; @@ -132,6 +133,10 @@ if (process.env.SENTRY_DSN) { }); } +if (process.env.SEGMENT_TOKEN) { + modules.push(AnalyticsModule); +} + if (process.env.NODE_ENV === 'test') { modules.push(TestingModule); } diff --git a/apps/api/src/app/analytics/analytics.controller.ts b/apps/api/src/app/analytics/analytics.controller.ts new file mode 100644 index 00000000000..0e1560818e0 --- /dev/null +++ b/apps/api/src/app/analytics/analytics.controller.ts @@ -0,0 +1,22 @@ +import { Body, Controller, Logger, Post, UseGuards } from '@nestjs/common'; +import { SkipThrottle } from '@nestjs/throttler'; +import { AnalyticsService, UserAuthGuard, UserSession } from '@novu/application-generic'; +import { IJwtPayload } from '@novu/shared'; + +@Controller({ + path: 'telemetry', +}) +@SkipThrottle() +export class AnalyticsController { + constructor(private analyticsService: AnalyticsService) {} + + @Post('/measure') + @UseGuards(UserAuthGuard) + async trackEvent(@Body('event') event, @Body('data') data, @UserSession() user: IJwtPayload): Promise { + await this.analyticsService.track(event, user._id, data); + + return { + success: true, + }; + } +} diff --git a/apps/api/src/app/analytics/analytics.module.ts b/apps/api/src/app/analytics/analytics.module.ts new file mode 100644 index 00000000000..c14b17e1c8d --- /dev/null +++ b/apps/api/src/app/analytics/analytics.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { AnalyticsController } from './analytics.controller'; +import { SharedModule } from '../shared/shared.module'; +import { AnalyticsService } from '@novu/application-generic'; +import { AuthModule } from '../auth/auth.module'; + +@Module({ + imports: [SharedModule, AuthModule], + controllers: [AnalyticsController], + providers: [AnalyticsService], +}) +export class AnalyticsModule {} diff --git a/libs/shared-web/src/utils/segment.ts b/libs/shared-web/src/utils/segment.ts index c5036fc9ec6..a48f965e150 100644 --- a/libs/shared-web/src/utils/segment.ts +++ b/libs/shared-web/src/utils/segment.ts @@ -1,5 +1,6 @@ import { AnalyticsBrowser } from '@segment/analytics-next'; import { IUserEntity } from '@novu/shared'; +import { api } from '../api'; export class SegmentService { private _segment: AnalyticsBrowser | null = null; @@ -21,12 +22,15 @@ export class SegmentService { this._segment?.identify(user?._id); } - track(event: string, data?: Record) { + async track(event: string, data?: Record) { if (!this.isSegmentEnabled()) { return; } - this._segment?.track(event + ' - [WEB]', data); + await api.post('/v1/telemetry/measure', { + event: event + ' - [WEB]', + data, + }); } pageView(url: string) {