Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RAJAI OTP Service module #97

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading