Skip to content

Commit

Permalink
Merge pull request #97 from Amruth-Vamshi/feature/rajai-otp-service
Browse files Browse the repository at this point in the history
  • Loading branch information
ChakshuGautam authored Aug 28, 2024
2 parents 1e37cdd + 4edcf17 commit eeaf61e
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 2 deletions.
7 changes: 6 additions & 1 deletion .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ CDAC_OTP_TEMPLATE_ID="123456"
CDAC_OTP_TEMPLATE="Respected User, The OTP to reset password for %phone% is %code%."

# SMS Adapter
SMS_ADAPTER_TYPE= # CDAC or GUPSHUP
SMS_ADAPTER_TYPE= # CDAC or GUPSHUP or RAJAI
SMS_TOTP_SECRET= # any random string, needed for CDAC
SMS_TOTP_EXPIRY=600 # in seconds, needed for CDAC

#RAJAI OTP Service
RAJAI_USERNAME=
RAJAI_PASSWORD=
RAJAI_BASEURL=

# Fusionauth
FUSIONAUTH_APPLICATION_ID="f0ddb3f6-091b-45e4-8c0f-889f89d4f5da"
FUSIONAUTH_SAMARTH_HP_APPLICATION_ID=f18c3f6f-45b8-4928-b978-a9906fd03f22
Expand Down
17 changes: 16 additions & 1 deletion src/api/api.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { GupshupService } from './sms/gupshup/gupshup.service';
import { SmsService } from './sms/sms.service';
import got from 'got/dist/source';
import { CdacService } from './sms/cdac/cdac.service';
import { RajaiOtpService } from '../user/sms/rajaiOtpService/rajaiOtpService.service';

const otpServiceFactory = {
provide: OtpService,
Expand All @@ -24,7 +25,21 @@ const otpServiceFactory = {
},
inject: [],
}.useFactory();
} else {
} else if(config.get<string>('SMS_ADAPTER_TYPE') == 'RAJAI'){
factory = {
provide: 'OtpService',
useFactory: (username, password, baseUrl)=>{
return new RajaiOtpService(
username,
password,
baseUrl,
got
);
},
inject: [],
}.useFactory(config.get('RAJAI_USERNAME'), config.get('RAJAI_PASSWORD'), config.get('RAJAI_BASEURL'));
}
else {
factory = {
provide: 'OtpService',
useFactory: (username, password, baseUrl) => {
Expand Down
207 changes: 207 additions & 0 deletions src/user/sms/rajaiOtpService/rajaiOtpService.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import {
OTPResponse,
SMS,
SMSData,
SMSError,
SMSProvider,
SMSResponse,
SMSResponseStatus,
SMSType,
TrackResponse,
} from '../sms.interface';

import { Injectable } from '@nestjs/common';
import { SmsService } from '../sms.service';
import { Got } from 'got/dist/source';
import { json } from 'stream/consumers';

@Injectable()
export class RajaiOtpService extends SmsService implements SMS {

otpApiConstants: any = {
srvnm: "ChatbotAPIs",
srvmethodnm: ""
};

auth: any = {
usrnm: '',
psw: '',
};

httpClient: Got;

baseURL: string;
path = '';
data: SMSData;

constructor(username: string, password: string, baseURL: string, got: Got) {
super();
this.auth.usrnm = username;
this.auth.psw = password;
this.baseURL = baseURL;
this.httpClient = got;
}

send(data: SMSData): Promise<SMSResponse> {
if (!data) {
throw new Error('Data cannot be null');
}
this.data = data;
if (this.data.type === SMSType.otp) return this.doOTPRequest(data);
else return this.doRequest();
}

doRequest(): Promise<SMSResponse> {
throw new Error('Method not implemented.');
}

track(data: SMSData): Promise<SMSResponse> {
if (!data) {
throw new Error('Data cannot be null');
}
this.data = data;
if (this.data.type === SMSType.otp) return this.verifyOTP(data);
else return this.doRequest();
}

private doOTPRequest(data: SMSData): Promise<OTPResponse> {
this.otpApiConstants.srvmethodnm = 'ChatBotGenerateOtpMobile'
const body: any = {
obj: {
...this.otpApiConstants,
...this.auth,
mobileNo: data.phone,
}
}
const options = {
headers: {
'Content-Type': 'application/json'
},
json: body
};
console.log(options)
const url = this.baseURL + '' + this.path;
console.log(url)
const status: OTPResponse = {} as OTPResponse;
status.provider = SMSProvider.rajai;
status.phone = data.phone;

return this.httpClient
.post(url,options)
.then((response): OTPResponse => {
status.networkResponseCode = 200;
const r = this.parseResponse(response.body);
console.log("otp response", r);
status.messageID = r.messageID;
status.error = r.error;
status.providerResponseCode = r.providerResponseCode;
status.providerSuccessResponse = r.providerSuccessResponse;
status.status = r.status;
return status;
})
.catch((e: Error): OTPResponse => {
console.log("otp response error", e);
const error: SMSError = {
errorText: `Uncaught Exception :: ${e.message}`,
errorCode: 'CUSTOM ERROR',
};
status.networkResponseCode = 200;
status.messageID = null;
status.error = error;
status.providerResponseCode = null;
status.providerSuccessResponse = null;
status.status = SMSResponseStatus.failure;
return status;
});
}

verifyOTP(data: SMSData): Promise<TrackResponse> {
this.otpApiConstants.srvmethodnm = 'ChatBotVerifyOtpMobile'
console.log({ data });
const body: any = {
obj: {
...this.otpApiConstants,
...this.auth,
mobileNo: data.phone,
otp: data.params.otp
}
}
const options = {
headers: {
'Content-Type': 'application/json'
},
json: body
};
const url = this.baseURL + '' + this.path;
const status: TrackResponse = {} as TrackResponse;
status.provider = SMSProvider.rajai;
status.phone = data.phone;

return this.httpClient
.post(url, options)
.then((response): OTPResponse => {
console.log(response.body);
status.networkResponseCode = 200;
const r = this.parseResponse(response.body);
status.messageID = r.messageID;
status.error = r.error;
status.providerResponseCode = r.providerResponseCode;
status.providerSuccessResponse = r.providerSuccessResponse;
status.status = r.status;
return status;
})
.catch((e: Error): OTPResponse => {
const error: SMSError = {
errorText: `Uncaught Exception :: ${e.message}`,
errorCode: 'CUSTOM ERROR',
};
status.networkResponseCode = 200;
status.messageID = null;
status.error = error;
status.providerResponseCode = null;
status.providerSuccessResponse = null;
status.status = SMSResponseStatus.failure;
return status;
});
}

parseResponse(response: string): any{
try {
const responseData = JSON.parse(response);
if (responseData[0]["status"] === '0' || responseData[0]["message"] === 'OTP Verify Successfully' ) {
return {
providerResponseCode: null,
status: SMSResponseStatus.success,
messageID: responseData[0]["data"],
error: null,
providerSuccessResponse: responseData[0]["message"],
};
} else {
const error: SMSError = {
errorText: responseData[0]["message"],
errorCode: responseData[0]["status"],
};
return {
providerResponseCode: responseData[0]["message"],
status: SMSResponseStatus.failure,
messageID: null,
error,
providerSuccessResponse: null,
};
}
} catch (e) {
const error: SMSError = {
errorText: `Gupshup response could not be parsed :: ${e.message}; Provider Response - ${response}`,
errorCode: 'CUSTOM ERROR',
};
return {
providerResponseCode: null,
status: SMSResponseStatus.failure,
messageID: null,
error,
providerSuccessResponse: null,
};
}
}
}

1 change: 1 addition & 0 deletions src/user/sms/sms.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export enum SMSResponseStatus {
export enum SMSProvider {
gupshup = 'Gupshup',
cdac = 'CDAC',
rajai = 'Rajai'
}

export type SMSError = {
Expand Down

0 comments on commit eeaf61e

Please sign in to comment.