forked from Yara724/api
108 lines
3.2 KiB
TypeScript
108 lines
3.2 KiB
TypeScript
import { Injectable, Logger } from "@nestjs/common";
|
|
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);
|
|
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 firstValueFrom(
|
|
this.httpService.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;
|
|
}
|
|
}
|