forked from Yara724/api
Tidied up the project
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { KavenegarService } from "@fraybabak/kavenegar_nest";
|
||||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import { KavenegarService } from "./kavenegar.service";
|
||||
import {
|
||||
isKavenegarSuccess,
|
||||
KavenegarNormalized,
|
||||
@@ -21,29 +21,27 @@ export class KavenegarSmsGateway {
|
||||
|
||||
async sendMessage(data: SendMessage) {
|
||||
try {
|
||||
const body = await this.sender.Send({
|
||||
const body = await this.sender.send({
|
||||
sender: "10008663",
|
||||
...data,
|
||||
});
|
||||
|
||||
if (!isKavenegarSuccess(body)) {
|
||||
const normalized = normalizeKavenegarBody(body);
|
||||
|
||||
this.logProviderRejection("send", data.receptor, undefined, normalized);
|
||||
|
||||
throw new SmsProviderException("send", {
|
||||
receptor: data.receptor,
|
||||
providerBody: body,
|
||||
normalized,
|
||||
});
|
||||
}
|
||||
this.logger.log(
|
||||
`Kavenegar Send ok receptor=${data.receptor} status=200`,
|
||||
);
|
||||
|
||||
return body;
|
||||
} catch (e) {
|
||||
if (e instanceof SmsProviderException) throw e;
|
||||
const detail = safeJsonStringify(unwrapKavenegarTransportError(e));
|
||||
this.logger.error(
|
||||
`Kavenegar Send transport error receptor=${data.receptor} detail=${detail}`,
|
||||
);
|
||||
|
||||
throw new SmsTransportException("send", { receptor: data.receptor }, e);
|
||||
}
|
||||
}
|
||||
@@ -51,14 +49,17 @@ export class KavenegarSmsGateway {
|
||||
async verifyLookUp(data: VerifyLookUpMessage) {
|
||||
try {
|
||||
const body = await this.sender.verifyLookup(data);
|
||||
|
||||
if (!isKavenegarSuccess(body)) {
|
||||
const normalized = normalizeKavenegarBody(body);
|
||||
|
||||
this.logProviderRejection(
|
||||
"verifyLookUp",
|
||||
data.receptor,
|
||||
data.template,
|
||||
normalized,
|
||||
);
|
||||
|
||||
throw new SmsProviderException("verifyLookup", {
|
||||
receptor: data.receptor,
|
||||
template: data.template,
|
||||
@@ -66,19 +67,21 @@ export class KavenegarSmsGateway {
|
||||
normalized,
|
||||
});
|
||||
}
|
||||
this.logger.log(
|
||||
`Kavenegar verifyLookUp ok receptor=${data.receptor} template=${data.template} status=200`,
|
||||
);
|
||||
|
||||
return body;
|
||||
} catch (e) {
|
||||
if (e instanceof SmsProviderException) throw e;
|
||||
|
||||
const detail = safeJsonStringify(unwrapKavenegarTransportError(e));
|
||||
this.logger.error(
|
||||
`Kavenegar verifyLookUp transport error receptor=${data.receptor} template=${data.template} detail=${detail}`,
|
||||
);
|
||||
|
||||
this.logger.error(`Kavenegar transport error ${detail}`);
|
||||
|
||||
throw new SmsTransportException(
|
||||
"verifyLookup",
|
||||
{ receptor: data.receptor, template: data.template },
|
||||
{
|
||||
receptor: data.receptor,
|
||||
template: data.template,
|
||||
},
|
||||
e,
|
||||
);
|
||||
}
|
||||
@@ -90,9 +93,10 @@ export class KavenegarSmsGateway {
|
||||
template: string | undefined,
|
||||
normalized: KavenegarNormalized,
|
||||
) {
|
||||
const t = template != null && template !== "" ? ` template=${template}` : "";
|
||||
const t = template != null ? ` template=${template}` : "";
|
||||
|
||||
this.logger.warn(
|
||||
`Kavenegar ${op} rejected receptor=${receptor}${t} providerStatus=${normalized.httpLikeStatus ?? "unknown"} providerMessage=${normalized.message ?? "n/a"} body=${normalized.raw}`,
|
||||
`Kavenegar ${op} rejected receptor=${receptor}${t} providerStatus=${normalized.httpLikeStatus}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
45
src/sms-orchestration/provider/kavenegar.service.ts
Normal file
45
src/sms-orchestration/provider/kavenegar.service.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { HttpService } from "@nestjs/axios";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
@Injectable()
|
||||
export class KavenegarService {
|
||||
private readonly apiKey: string;
|
||||
private readonly baseUrl: string;
|
||||
|
||||
constructor(
|
||||
private readonly http: HttpService,
|
||||
private readonly configService: ConfigService,
|
||||
) {
|
||||
this.apiKey = this.configService.get<string>("SMS_API_KEY", "");
|
||||
|
||||
this.baseUrl = `https://api.kavenegar.com/v1/${this.apiKey}`;
|
||||
}
|
||||
|
||||
async send(data: { receptor: string; message: string; sender?: string }) {
|
||||
const response = await firstValueFrom(
|
||||
this.http.post(`${this.baseUrl}/sms/send.json`, null, {
|
||||
params: data,
|
||||
}),
|
||||
);
|
||||
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async verifyLookup(data: {
|
||||
receptor: string;
|
||||
token: string;
|
||||
template: string;
|
||||
token2?: string;
|
||||
token3?: string;
|
||||
}) {
|
||||
const response = await firstValueFrom(
|
||||
this.http.get(`${this.baseUrl}/verify/lookup.json`, {
|
||||
params: data,
|
||||
}),
|
||||
);
|
||||
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,20 @@
|
||||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import axios, { isAxiosError } from "axios";
|
||||
import { isAxiosError } from "axios";
|
||||
import { buildParsianTemplateMessage } from "./parsian-template-messages";
|
||||
import {
|
||||
SmsProviderException,
|
||||
SmsTransportException,
|
||||
} from "./sms-provider.exception";
|
||||
import { SendMessage, VerifyLookUpMessage } from "./sms-gateway.types";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { HttpService } from "@nestjs/axios";
|
||||
|
||||
@Injectable()
|
||||
export class ParsianSmsGateway {
|
||||
private readonly logger = new Logger(ParsianSmsGateway.name);
|
||||
|
||||
constructor(private readonly httpService: HttpService) {}
|
||||
|
||||
async sendMessage(data: SendMessage) {
|
||||
try {
|
||||
const body = await this.requestSend(data.receptor, data.message);
|
||||
@@ -19,7 +23,11 @@ export class ParsianSmsGateway {
|
||||
} catch (e) {
|
||||
if (e instanceof SmsProviderException) throw e;
|
||||
const detail = isAxiosError(e)
|
||||
? { status: e.response?.status, data: e.response?.data, message: e.message }
|
||||
? {
|
||||
status: e.response?.status,
|
||||
data: e.response?.data,
|
||||
message: e.message,
|
||||
}
|
||||
: e;
|
||||
this.logger.error(
|
||||
`Parsian Send transport error receptor=${data.receptor} detail=${JSON.stringify(detail)}`,
|
||||
@@ -39,7 +47,11 @@ export class ParsianSmsGateway {
|
||||
} catch (e) {
|
||||
if (e instanceof SmsProviderException) throw e;
|
||||
const detail = isAxiosError(e)
|
||||
? { status: e.response?.status, data: e.response?.data, message: e.message }
|
||||
? {
|
||||
status: e.response?.status,
|
||||
data: e.response?.data,
|
||||
message: e.message,
|
||||
}
|
||||
: e;
|
||||
this.logger.error(
|
||||
`Parsian verifyLookUp transport error receptor=${data.receptor} template=${data.template} detail=${JSON.stringify(detail)}`,
|
||||
@@ -60,7 +72,10 @@ export class ParsianSmsGateway {
|
||||
};
|
||||
}
|
||||
|
||||
private async requestSend(receptor: string, message: string): Promise<unknown> {
|
||||
private async requestSend(
|
||||
receptor: string,
|
||||
message: string,
|
||||
): Promise<unknown> {
|
||||
const baseUrl = process.env.PARSIAN_SMS_URL;
|
||||
if (!baseUrl?.trim()) {
|
||||
throw new SmsTransportException(
|
||||
@@ -71,7 +86,9 @@ export class ParsianSmsGateway {
|
||||
}
|
||||
|
||||
const url = `${baseUrl}=${receptor}&Message=${encodeURIComponent(message)}`;
|
||||
const response = await axios.get(url, { headers: this.parsianHeaders() });
|
||||
const response = await firstValueFrom(
|
||||
this.httpService.get(url, { headers: this.parsianHeaders() }),
|
||||
);
|
||||
|
||||
if (response.status < 200 || response.status >= 300) {
|
||||
throw new SmsProviderException("send", {
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
import { KavenegarModule } from "@fraybabak/kavenegar_nest";
|
||||
import { HttpModule } from "@nestjs/axios";
|
||||
import { Module } from "@nestjs/common";
|
||||
import * as dotenv from "dotenv";
|
||||
import { ConfigModule } from "@nestjs/config";
|
||||
|
||||
import { KavenegarService } from "./kavenegar.service";
|
||||
import { KavenegarSmsGateway } from "./kavenegar-sms.gateway";
|
||||
import { ParsianSmsGateway } from "./parsian-sms.gateway";
|
||||
import { SmsGatewayService } from "./sms-gateway.service";
|
||||
|
||||
dotenv.config();
|
||||
dotenv.config({ path: `.${process.env.NODE_ENV}.env` });
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
KavenegarModule.forRoot({
|
||||
apikey: process.env.SMS_API_KEY || "",
|
||||
}),
|
||||
],
|
||||
imports: [HttpModule, ConfigModule],
|
||||
providers: [
|
||||
KavenegarService,
|
||||
KavenegarSmsGateway,
|
||||
ParsianSmsGateway,
|
||||
SmsGatewayService,
|
||||
|
||||
Reference in New Issue
Block a user