This commit is contained in:
SepehrYahyaee
2026-05-23 14:05:11 +03:30
parent 39c4855b95
commit 94bde88cb6
11 changed files with 338 additions and 126 deletions

View File

@@ -0,0 +1,90 @@
import { Injectable, Logger } from "@nestjs/common";
import axios, { isAxiosError } from "axios";
import { buildParsianTemplateMessage } from "./parsian-template-messages";
import {
SmsProviderException,
SmsTransportException,
} from "./sms-provider.exception";
import { SendMessage, VerifyLookUpMessage } from "./sms-gateway.types";
@Injectable()
export class ParsianSmsGateway {
private readonly logger = new Logger(ParsianSmsGateway.name);
async sendMessage(data: SendMessage) {
try {
const body = await this.requestSend(data.receptor, data.message);
this.logger.log(`Parsian Send ok receptor=${data.receptor}`);
return body;
} catch (e) {
if (e instanceof SmsProviderException) throw e;
const detail = isAxiosError(e)
? { 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)}`,
);
throw new SmsTransportException("send", { receptor: data.receptor }, e);
}
}
async verifyLookUp(data: VerifyLookUpMessage) {
const message = buildParsianTemplateMessage(data);
try {
const body = await this.requestSend(data.receptor, message);
this.logger.log(
`Parsian verifyLookUp ok receptor=${data.receptor} template=${data.template}`,
);
return body;
} catch (e) {
if (e instanceof SmsProviderException) throw e;
const detail = isAxiosError(e)
? { 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)}`,
);
throw new SmsTransportException(
"verifyLookup",
{ receptor: data.receptor, template: data.template },
e,
);
}
}
private parsianHeaders() {
return {
"Content-Type": "application/json",
"X-PACKAGE-API-KEY": process.env.PARSIAN_API_KEY ?? "",
Authorization: `Basic ${process.env.PARSIAN_BASIC_TOKEN ?? ""}`,
};
}
private async requestSend(receptor: string, message: string): Promise<unknown> {
const baseUrl = process.env.PARSIAN_SMS_URL;
if (!baseUrl?.trim()) {
throw new SmsTransportException(
"send",
{ receptor },
new Error("PARSIAN_SMS_URL is not configured"),
);
}
const url = `${baseUrl}=${receptor}&Message=${encodeURIComponent(message)}`;
const response = await axios.get(url, { headers: this.parsianHeaders() });
if (response.status < 200 || response.status >= 300) {
throw new SmsProviderException("send", {
receptor,
providerBody: response.data,
normalized: {
httpLikeStatus: response.status,
message: String(response.statusText ?? ""),
raw: JSON.stringify(response.data),
},
});
}
return response.data;
}
}