Centralized SMS services YARA-834

This commit is contained in:
SepehrYahyaee
2026-04-22 15:02:08 +03:30
parent f01882dc3a
commit d9b1537ee4
16 changed files with 311 additions and 138 deletions

View File

@@ -39,8 +39,7 @@ import { StepsEnum } from "src/Types&Enums/blame-request-management/steps.enum";
import { ExpertDbService } from "src/users/entities/db-service/expert.db.service";
import { UserDbService } from "src/users/entities/db-service/user.db.service";
import { AutoCloseRequestService } from "src/utils/cron/cron.service";
import { SmsManagerService } from "src/utils/sms-manager/sms-manager.service";
import { describeSmsError } from "src/utils/sms-manager/sms-provider.exception";
import { SmsOrchestrationService } from "src/sms-orchestration/sms-orchestration.service";
import {
DescriptionDto,
LocationDto,
@@ -308,7 +307,7 @@ export class RequestManagementService {
private readonly clientService: ClientService,
private readonly blameVoiceDbService: BlameVoiceDbService,
private readonly userSign: UserSignDbService,
private readonly smsManagerService: SmsManagerService,
private readonly smsOrchestrationService: SmsOrchestrationService,
private readonly expertDbService: ExpertDbService,
private readonly autoCloseRequestService: AutoCloseRequestService,
private readonly claimRequestManagementDbService: ClaimRequestManagementDbService,
@@ -1305,21 +1304,14 @@ export class RequestManagementService {
metadata: { secondPartyPhone, expertInitiatedLink: true },
} as any);
await (req as any).save();
const url = `${process.env.URL}/${frontendRoute}?token=${requestId}`;
try {
await this.smsManagerService.verifyLookUp({
token: url,
template: "yara724-invite-link",
receptor: secondPartyPhone,
});
this.logger.log(
`[SMS] Invitation resent to ${secondPartyPhone} for expert-initiated request ${req.publicId}`,
);
} catch (err) {
this.logger.error(
`[SMS] Failed to send invitation to ${secondPartyPhone}: ${describeSmsError(err)}`,
);
}
const url = this.smsOrchestrationService.buildInviteLink(
frontendRoute,
requestId,
);
await this.smsOrchestrationService.sendInviteLink(
secondPartyPhone,
url,
);
return {
requestId: req._id,
publicId: req.publicId,
@@ -1362,22 +1354,11 @@ export class RequestManagementService {
await (req as any).save();
// Send SMS invitation
const url = `${process.env.URL}/${frontendRoute}?token=${requestId}`;
try {
await this.smsManagerService.verifyLookUp({
token: url,
template: "yara724-invite-link",
receptor: phoneNumber,
});
this.logger.log(
`[SMS] Invitation sent to ${phoneNumber} for request ${req.publicId}`,
);
} catch (err) {
this.logger.error(
`[SMS] Failed to send invitation to ${phoneNumber}: ${describeSmsError(err)}`,
);
// Don't block the request flow if SMS fails
}
const url = this.smsOrchestrationService.buildInviteLink(
frontendRoute,
requestId,
);
await this.smsOrchestrationService.sendInviteLink(phoneNumber, url);
return {
requestId: req._id,
@@ -2295,21 +2276,11 @@ export class RequestManagementService {
}
// Send the SMS after the database update is complete.
const URL = `${process.env.URL}/${frontendRoutes}?token=${requestId}`;
try {
await this.smsManagerService.verifyLookUp({
token: URL,
template: "yara724-invite-link",
receptor: phoneNumber,
});
this.logger.log(
`[SMS] Invite link verifyLookUp ok receptor=${phoneNumber}`,
);
} catch (er) {
this.logger.error(
`[SMS] Invite link failed receptor=${phoneNumber}: ${describeSmsError(er)}`,
);
}
const URL = this.smsOrchestrationService.buildInviteLink(
frontendRoutes,
requestId,
);
await this.smsOrchestrationService.sendInviteLink(phoneNumber, URL);
return { url: URL };
}
@@ -2838,17 +2809,11 @@ export class RequestManagementService {
// TODO SMS Sending
if (phoneNumberToNotify) {
const message = `متاسفانه طرف مقابل با نظر کارشناس مخالفت کرد. فرآیند آنلاین این پرونده بسته شده است و جهت پیگیری حضوری اقدام نمایید.`;
try {
await this.smsManagerService.sendMessage({
receptor: phoneNumberToNotify,
message,
});
} catch (err) {
this.logger.error(
`[SMS] PartiesDisagree notify failed receptor=${phoneNumberToNotify}: ${describeSmsError(err)}`,
);
}
await this.smsOrchestrationService.sendTextByKey(
phoneNumberToNotify,
"parties_disagree_notify",
"متاسفانه طرف مقابل با نظر کارشناس مخالفت کرد. فرآیند آنلاین این پرونده بسته شده است و جهت پیگیری حضوری اقدام نمایید.",
);
}
}
@@ -3028,17 +2993,15 @@ export class RequestManagementService {
: originalReq.firstPartyDetails?.firstPartyPhoneNumber;
if (phoneNumber) {
// TODO FIX SMS SENDING FOR PARTIES
try {
await this.smsManagerService.sendMessage({
receptor: phoneNumber,
message,
});
} catch (err) {
this.logger.error(
`[SMS] One-party-replied notify failed receptor=${phoneNumber}: ${describeSmsError(err)}`,
);
}
const key =
message.includes("24 ساعت")
? "one_party_accepted_wait_24h"
: "one_party_signed_wait_signature";
await this.smsOrchestrationService.sendTextByKey(
phoneNumber,
key,
message,
);
}
await this.autoCloseRequestService.scheduleAutoClose({
@@ -3764,33 +3727,21 @@ export class RequestManagementService {
"URL environment variable is not configured",
);
}
const linkUrl = `${process.env.URL}/${dto.frontendRoute}?token=${requestId}`;
const typeToken =
req.type === BlameRequestType.CAR_BODY ? "بدنه" : "ثالث";
const linkUrl = this.smsOrchestrationService.buildInviteLink(
dto.frontendRoute,
requestId,
);
const expertName =
`${expert?.lastName || ""}`.trim() || "کارشناس";
const sentTo: { role: string; phoneNumber: string; smsSent: boolean }[] = [];
const template = "yara-field-expert-link";
const sendSms = async (phone: string, role: PartyRole): Promise<boolean> => {
try {
await this.smsManagerService.verifyLookUp({
template,
receptor: phone,
token: typeToken,
token2: expertName,
token3: linkUrl,
});
this.logger.log(
`[SMS] Field-expert link sent role=${role} receptor=${phone} template=${template}`,
);
return true;
} catch (er) {
this.logger.error(
`[SMS] Field-expert link failed role=${role} receptor=${phone}: ${describeSmsError(er)}`,
);
return false;
}
return this.smsOrchestrationService.sendFieldExpertLink({
receptor: phone,
type: req.type,
expertLastName: expertName,
link: linkUrl,
});
};
const firstIdx = this.getPartyIndex(req, PartyRole.FIRST);
@@ -3816,7 +3767,12 @@ export class RequestManagementService {
actorName: `${expert.firstName || ""} ${expert.lastName || ""}`.trim(),
actorType: "field_expert",
},
metadata: { linkUrl, sentTo, template, typeToken, frontendRoute: dto.frontendRoute },
metadata: {
linkUrl,
sentTo,
template: "yara-field-expert-link",
frontendRoute: dto.frontendRoute,
},
});
await (req as any).save();