diff --git a/docsfera.json b/docsfera.json index 950e6af..11db613 100644 --- a/docsfera.json +++ b/docsfera.json @@ -3274,6 +3274,17 @@ "Productboard" ] } + }, + "/trackEvent/{id}": { + "post": { + "operationId": "MixpanelController_trackEvent", + "parameters": [], + "responses": { + "201": { + "description": "" + } + } + } } }, "info": { diff --git a/package-lock.json b/package-lock.json index d8036d1..46db5ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "helmet": "^5.1.0", "jsonwebtoken": "^8.5.1", "jwk-to-pem": "^2.0.5", + "mixpanel": "^0.17.0", "passport": "^0.6.0", "passport-facebook": "^3.0.0", "passport-forcedotcom": "^0.1.5", @@ -3543,7 +3544,6 @@ }, "node_modules/agent-base": { "version": "6.0.2", - "dev": true, "license": "MIT", "dependencies": { "debug": "4" @@ -8205,6 +8205,29 @@ "version": "1.2.6", "license": "MIT" }, + "node_modules/mixpanel": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/mixpanel/-/mixpanel-0.17.0.tgz", + "integrity": "sha512-DY5WeOy/hmkPrNiiZugJpWR0iMuOwuj1a3u0bgwB2eUFRV6oIew/pIahhpawdbNjb+Bye4a8ID3gefeNPvL81g==", + "dependencies": { + "https-proxy-agent": "5.0.0" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/mixpanel/node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/mkdirp": { "version": "0.5.6", "license": "MIT", @@ -13556,7 +13579,6 @@ }, "agent-base": { "version": "6.0.2", - "dev": true, "requires": { "debug": "4" } @@ -16720,6 +16742,25 @@ "minimist": { "version": "1.2.6" }, + "mixpanel": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/mixpanel/-/mixpanel-0.17.0.tgz", + "integrity": "sha512-DY5WeOy/hmkPrNiiZugJpWR0iMuOwuj1a3u0bgwB2eUFRV6oIew/pIahhpawdbNjb+Bye4a8ID3gefeNPvL81g==", + "requires": { + "https-proxy-agent": "5.0.0" + }, + "dependencies": { + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + } + } + }, "mkdirp": { "version": "0.5.6", "requires": { diff --git a/package.json b/package.json index c250f21..55c5c06 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "helmet": "^5.1.0", "jsonwebtoken": "^8.5.1", "jwk-to-pem": "^2.0.5", + "mixpanel": "^0.17.0", "passport": "^0.6.0", "passport-facebook": "^3.0.0", "passport-forcedotcom": "^0.1.5", diff --git a/src/app.module.ts b/src/app.module.ts index 31bf962..9905c93 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -24,6 +24,7 @@ import { CatalogModule } from './modules/catalog/catalog.module'; import { ConfigModule } from '@nestjs/config'; import { PipelinesV2Module } from './modules/pipelinesV2/pipelines.module'; import { ProductboardModule } from './modules/productboard/productboard.module'; +import { MixpanelModule } from './modules/mixpanel/mixpanel.module'; @Module({ controllers: [], @@ -56,6 +57,7 @@ import { ProductboardModule } from './modules/productboard/productboard.module'; OauthModule, CatalogModule, ProductboardModule, + MixpanelModule, ], }) export class AppModule {} diff --git a/src/modules/mixpanel/mixpanel.controller.ts b/src/modules/mixpanel/mixpanel.controller.ts new file mode 100644 index 0000000..e7005ee --- /dev/null +++ b/src/modules/mixpanel/mixpanel.controller.ts @@ -0,0 +1,31 @@ +import { Body, Controller, Inject, Param, Post } from '@nestjs/common'; +import { init } from 'mixpanel'; +import { RequestUser, User } from 'src/authentication/user.decorator'; + +@Controller('trackEvent') +export class MixpanelController { + constructor( + @Inject('MIXPANEL_TOKEN') + private readonly mixpanelToken: string, + ) {} + @Post(':id') + async trackEvent(@Param('id') id, @Body() body, @User() user: RequestUser) { + delete body.info; + const mixpanel = init(this.mixpanelToken); + + await mixpanel.people.set(user.username, { + $name: user.username, + $email: user.username, + customer_name: user.customer_name, + }); + + await mixpanel.track(id, { + distinct_id: user.username, + customer: user.customer_name, + env: process.env.ENV, + ...body, + }); + + return { id, body, user: user.username }; + } +} diff --git a/src/modules/mixpanel/mixpanel.module.ts b/src/modules/mixpanel/mixpanel.module.ts new file mode 100644 index 0000000..41b4a68 --- /dev/null +++ b/src/modules/mixpanel/mixpanel.module.ts @@ -0,0 +1,16 @@ +import { Module } from '@nestjs/common'; +import { getSecreteFromSecreteManager } from 'src/utils/SecretManager'; +import { MixpanelController } from './mixpanel.controller'; + +@Module({ + controllers: [MixpanelController], + providers: [ + { + provide: 'MIXPANEL_TOKEN', + useValue: getSecreteFromSecreteManager( + `${process.env.ENV}/root/mixpanel_token`, + ), + }, + ], +}) +export class MixpanelModule {}