chore: sms service with configs

This commit is contained in:
matin jamshidi
2025-01-19 14:46:16 +03:30
parent b899b8df6f
commit a934e5b55e
8 changed files with 132 additions and 4 deletions
+5
View File
@@ -7,3 +7,8 @@ DB_PORT=5432
DB_NAME=danak-dsc DB_NAME=danak-dsc
DB_USER=danak DB_USER=danak
DB_PASS=jkm3q2wux56RHYuTuKN11Too6+4pIpGQj3Q/fkNbahM DB_PASS=jkm3q2wux56RHYuTuKN11Too6+4pIpGQj3Q/fkNbahM
URL=https://RestfulSms.com/api/UltraFastSend/direct
SMS_API_KEY=
SMS_SECRET=
SMS_PATTERN_OTP=
+1
View File
@@ -27,6 +27,7 @@
"@nestjs/platform-fastify": "^10.4.15", "@nestjs/platform-fastify": "^10.4.15",
"@nestjs/swagger": "^8.1.1", "@nestjs/swagger": "^8.1.1",
"@nestjs/typeorm": "^10.0.2", "@nestjs/typeorm": "^10.0.2",
"axios": "^1.7.9",
"pg": "^8.13.1", "pg": "^8.13.1",
"reflect-metadata": "^0.2.2", "reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1", "rxjs": "^7.8.1",
+30
View File
@@ -29,6 +29,9 @@ importers:
'@nestjs/typeorm': '@nestjs/typeorm':
specifier: ^10.0.2 specifier: ^10.0.2
version: 10.0.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(pg@8.13.1)(ts-node@10.9.2(@types/node@20.17.14)(typescript@5.7.3))) version: 10.0.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(pg@8.13.1)(ts-node@10.9.2(@types/node@20.17.14)(typescript@5.7.3)))
axios:
specifier: ^1.7.9
version: 1.7.9
pg: pg:
specifier: ^8.13.1 specifier: ^8.13.1
version: 8.13.1 version: 8.13.1
@@ -1094,6 +1097,9 @@ packages:
avvio@8.4.0: avvio@8.4.0:
resolution: {integrity: sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==} resolution: {integrity: sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==}
axios@1.7.9:
resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==}
babel-jest@29.7.0: babel-jest@29.7.0:
resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -1804,6 +1810,15 @@ packages:
flatted@3.3.2: flatted@3.3.2:
resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==}
follow-redirects@1.15.9:
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
for-each@0.3.3: for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@@ -2957,6 +2972,9 @@ packages:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'} engines: {node: '>= 0.10'}
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
punycode@2.3.1: punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'} engines: {node: '>=6'}
@@ -5005,6 +5023,14 @@ snapshots:
'@fastify/error': 3.4.1 '@fastify/error': 3.4.1
fastq: 1.18.0 fastq: 1.18.0
axios@1.7.9:
dependencies:
follow-redirects: 1.15.9
form-data: 4.0.1
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
babel-jest@29.7.0(@babel/core@7.26.0): babel-jest@29.7.0(@babel/core@7.26.0):
dependencies: dependencies:
'@babel/core': 7.26.0 '@babel/core': 7.26.0
@@ -5844,6 +5870,8 @@ snapshots:
flatted@3.3.2: {} flatted@3.3.2: {}
follow-redirects@1.15.9: {}
for-each@0.3.3: for-each@0.3.3:
dependencies: dependencies:
is-callable: 1.2.7 is-callable: 1.2.7
@@ -7162,6 +7190,8 @@ snapshots:
forwarded: 0.2.0 forwarded: 0.2.0
ipaddr.js: 1.9.1 ipaddr.js: 1.9.1
proxy-from-env@1.1.0: {}
punycode@2.3.1: {} punycode@2.3.1: {}
pure-rand@6.1.0: {} pure-rand@6.1.0: {}
+30
View File
@@ -0,0 +1,30 @@
import { ConfigService } from "@nestjs/config";
export function SmsConfigs() {
return {
inject: [ConfigService],
useFactory(configService: ConfigService) {
return {
URL: configService.getOrThrow<string>("URL"),
API_KEY: configService.getOrThrow<string>("API_KEY"),
SECRET_KEY: configService.getOrThrow<string>("SECRET_KEY"),
SMS_PATTERN_OTP: configService.getOrThrow<string>("SMS_PATTERN_OTP"),
SMS_SECRET_BODY: {
UserApiKey: configService.getOrThrow<string>("API_KEY"),
SecretKey: configService.getOrThrow<string>("SECRET_KEY"),
},
};
},
};
}
export interface ISmsConfigs {
URL: string;
API_KEY: string;
SECRET_KEY: string;
SMS_PATTERN_OTP: string;
SMS_SECRET_BODY: {
UserApiKey: string;
SecretKey: string;
};
}
+1
View File
@@ -0,0 +1 @@
export const SMS_CONFIG = "SMS_CONFIG";
+18
View File
@@ -0,0 +1,18 @@
export interface ISmsBody {
ParameterArray: IParameterArray[];
Mobile: string;
TemplateId: string;
UserApiKey: string;
SecretKey: string;
}
export interface IParameterArray {
Parameter: string;
ParameterValue: string;
}
export interface ISmsResponse {
VerificationCodeId: number;
isSuccessful: boolean;
Message: string;
}
@@ -0,0 +1,35 @@
import { Inject, Injectable, Logger } from "@nestjs/common";
import axios from "axios";
import { ISmsConfigs } from "../../../configs/sms.config";
import { SMS_CONFIG } from "../constants";
import { ISmsBody } from "../interfaces/ISms";
@Injectable()
export class SmsService {
private logger = new Logger(SmsService.name);
constructor(@Inject(SMS_CONFIG) private smsConfigs: ISmsConfigs) {}
async sendSmsVerifyCode(mobile: string, otpCode: string) {
const smsData: ISmsBody = {
ParameterArray: [{ Parameter: "otp", ParameterValue: otpCode }],
Mobile: mobile,
TemplateId: this.smsConfigs.SMS_PATTERN_OTP,
...this.smsConfigs.SMS_SECRET_BODY,
};
return this.sendSms(smsData);
}
private async sendSms(body: ISmsBody) {
try {
const { data } = await axios.post(this.smsConfigs.URL, body, {
headers: {
"Content-Type": "application/json",
},
});
return data;
} catch (error) {
this.logger.error(error);
}
}
}
+10 -2
View File
@@ -1,7 +1,15 @@
import { Module } from "@nestjs/common"; import { Module } from "@nestjs/common";
import { SMS_CONFIG } from "./constants";
import { SmsConfigs } from "../../configs/sms.config";
@Module({ @Module({
providers: [], providers: [
exports: [], {
provide: SMS_CONFIG,
useFactory: SmsConfigs().useFactory,
inject: SmsConfigs().inject
},
],
exports: [SMS_CONFIG]
}) })
export class UtilsModule { } export class UtilsModule { }