diff --git a/src/api/api.controller.ts b/src/api/api.controller.ts index 95b5354..a5ca575 100644 --- a/src/api/api.controller.ts +++ b/src/api/api.controller.ts @@ -40,6 +40,7 @@ import { v4 as uuidv4 } from 'uuid'; import { VerifyJWTDto } from './dto/verify-jwt.dto'; import { Request } from 'express'; import { GupshupWhatsappService } from './sms/gupshupWhatsapp/gupshupWhatsapp.service'; +import { TelemetryService } from 'src/telemetry/telemetry.service'; // eslint-disable-next-line @typescript-eslint/no-var-requires const CryptoJS = require('crypto-js'); @@ -54,7 +55,8 @@ export class ApiController { private readonly otpService: OtpService, private readonly apiService: ApiService, private readonly configResolverService: ConfigResolverService, - private readonly gupshupWhatsappService: GupshupWhatsappService + private readonly gupshupWhatsappService: GupshupWhatsappService, + private readonly telemetryService: TelemetryService ) {} @Get() @@ -72,6 +74,7 @@ export class ApiController { @Query() params: SendOtpDto, @Headers('x-application-id') applicationId?, ): Promise { + let startTime = Date.now(); if (applicationId) { const { total }: { total: number; users: Array } = await this.fusionAuthService.getUsersByString( @@ -93,21 +96,39 @@ export class ApiController { ); } } + + let status: any, isWhatsApp = false; // Check if phone number contains country code (e.g. 91-1234567890) if (params.phone.includes('-')) { + isWhatsApp = true; const [countryCode, number] = params.phone.split('-'); params.phone = number; - const status: any = await this.gupshupWhatsappService.sendWhatsappOTP({ + status = await this.gupshupWhatsappService.sendWhatsappOTP({ phone: number, template: null, type: null, params: null }); - return { status }; } else { - const status: any = await this.otpService.sendOTP(params.phone); - return { status }; + status = await this.otpService.sendOTP(params.phone); + } + + if(this.configService.get('TELEMETRY_INTERNAL_BASE_URL')) { + this.telemetryService.sendEvent( + { + botId: params.botId, + orgId: params.orgId, + timeTaken: Date.now() - startTime, + createdAt: Math.floor(new Date().getTime() / 1000), + phoneNumber: params.phone + }, + 'E117', + 'Send OTP', + 'sendOTP', + isWhatsApp ? 'Whatsapp' : 'PWA' + ) } + return { status }; } @Get('verifyOTP') diff --git a/src/api/api.module.ts b/src/api/api.module.ts index 9b92e28..b43394c 100644 --- a/src/api/api.module.ts +++ b/src/api/api.module.ts @@ -13,6 +13,7 @@ import got from 'got/dist/source'; import { CdacService } from './sms/cdac/cdac.service'; import { RajaiOtpService } from '../user/sms/rajaiOtpService/rajaiOtpService.service'; import { GupshupWhatsappService } from './sms/gupshupWhatsapp/gupshupWhatsapp.service'; +import { TelemetryService } from 'src/telemetry/telemetry.service'; const otpServiceFactory = { provide: OtpService, @@ -69,7 +70,8 @@ const otpServiceFactory = { otpServiceFactory, QueryGeneratorService, ConfigResolverService, - GupshupWhatsappService + GupshupWhatsappService, + TelemetryService ], }) export class ApiModule { diff --git a/src/api/dto/send-otp.dto.ts b/src/api/dto/send-otp.dto.ts index a632c9f..e3dc1a0 100644 --- a/src/api/dto/send-otp.dto.ts +++ b/src/api/dto/send-otp.dto.ts @@ -11,4 +11,12 @@ export class SendOtpDto { @IsString() @IsOptional() errorMessage?: string; + + @IsString() + @IsOptional() + botId?: string; + + @IsString() + @IsOptional() + orgId?: string; } diff --git a/src/telemetry/telemetry.service.ts b/src/telemetry/telemetry.service.ts new file mode 100644 index 0000000..ee6ea0f --- /dev/null +++ b/src/telemetry/telemetry.service.ts @@ -0,0 +1,72 @@ +import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; + +@Injectable() +export class TelemetryService { + private readonly logger = new Logger(TelemetryService.name); + constructor( + private readonly configService: ConfigService + ) {} + + async sendEvent( + eventData: any, + eventId: string, + event: string, + subEvent: string, + generator?: string, + userId?: string, + ): Promise { + const myHeaders = new Headers(); + myHeaders.append('Content-Type', 'application/json'); + + console.log([ + { + generator, + version: '0.0.1', + timestamp: Math.floor(new Date().getTime() / 1000), + actorId: userId, + actorType: 'User', + env: this.configService.get('ENVIRONMENT'), + eventId, + event, + subEvent, + eventData, + }, + ]); + + const raw = JSON.stringify([ + { + generator, + version: '0.0.1', + timestamp: Math.floor(new Date().getTime() / 1000), + actorId: userId, + actorType: 'User', + env: this.configService.get('ENVIRONMENT'), + eventId, + event, + subEvent, + eventData, + }, + ]); + + const requestOptions: any = { + method: 'POST', + headers: myHeaders, + body: raw, + redirect: 'follow', + retry: 1, + }; + + try { + const response = await fetch( + `${this.configService.get('TELEMETRY_INTERNAL_BASE_URL')}/metrics/v1/save`, + requestOptions, + ); + this.logger.verbose(`Sucessfully sent ${subEvent} event`); + return response.body; + } catch (error) { + this.logger.error(`Failed to send ${subEvent} event.`); + throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR); + } + } +}