import { Injectable, Logger, OnModuleInit } from "@nestjs/common"; import { BlameRequestType } from "src/Types&Enums/blame-request-management/blameRequestType.enum"; import { SmsTextDbService } from "./entities/db-service/sms-text.db.service"; import { SmsGatewayService } from "./provider/sms-gateway.service"; import { describeSmsError } from "./provider/sms-provider.exception"; type TemplateArgs = { template: string; receptor: string; token: string; token2?: string; token3?: string; token10?: string; }; @Injectable() export class SmsOrchestrationService implements OnModuleInit { private readonly logger = new Logger(SmsOrchestrationService.name); constructor( private readonly smsGatewayService: SmsGatewayService, private readonly smsTextDbService: SmsTextDbService, ) {} async onModuleInit(): Promise { await this.smsTextDbService.upsert( "parties_disagree_notify", "متاسفانه طرف مقابل با نظر کارشناس مخالفت کرد. فرآیند آنلاین این پرونده بسته شده است و جهت پیگیری حضوری اقدام نمایید.", ); await this.smsTextDbService.upsert( "one_party_signed_wait_signature", "طرف مقابل توافق را امضا کرده است. لطفا جهت نهایی کردن پرونده، امضای خود را ثبت نمایید.", ); await this.smsTextDbService.upsert( "one_party_accepted_wait_24h", "طرف مقابل نظر کارشناس را قبول و امضا کرده است. در طی 24 ساعت آینده فرصت دارید تا پرونده را تکمیل کرده یا پرونده بسته خواهد شد.", ); } buildInviteLink(frontendRoute: string, requestId: string): string { return `${process.env.URL}/${frontendRoute}?token=${requestId}`; } buildBlamePartyLink(requestId: string, partyRole: "FIRST" | "SECOND"): string { const route = partyRole === "SECOND" ? "user2" : "user"; return `${process.env.URL}/${route}?token=${requestId}`; } buildClaimLink(claimRequestId: string): string { return `${process.env.URL}/claim?token=${claimRequestId}`; } async sendInviteLink(phoneNumber: string, link: string): Promise { return this.sendTemplate({ template: "yara724-invite-link", receptor: phoneNumber, token: link, }); } async sendAuthOtp( mobile: string, otp: string, template?: string, ): Promise { return this.sendTemplate({ template: template || process.env.AUTH_SMS_TEMPLATE || "", receptor: mobile, token: otp, }); } async sendFieldExpertLink(params: { receptor: string; type: BlameRequestType; expertLastName: string; link: string; }): Promise { return this.sendTemplate({ template: "yara-field-expert-link", receptor: params.receptor, token: params.type === BlameRequestType.CAR_BODY ? "بدنه" : "ثالث", token2: params.expertLastName || "کارشناس", token3: params.link, }); } async sendTextByKey( receptor: string, key: string, fallbackText: string, ): Promise { const row = await this.smsTextDbService.findOne({ key, active: true }); const message = row?.text?.trim() || fallbackText; try { await this.smsGatewayService.sendMessage({ receptor, message }); this.logger.log(`[SMS] text sent key=${key} receptor=${receptor}`); return true; } catch (err) { this.logger.error( `[SMS] text send failed key=${key} receptor=${receptor}: ${describeSmsError(err)}`, ); return false; } } async sendThirdPartyAgreementSignNotice(params: { receptor: string; publicId: string; link: string; }): Promise { return this.sendTemplate({ template: "yara-blame-agreement", receptor: params.receptor, token: params.publicId, token2: params.link, }); } async sendThirdPartyExpertStartedReviewNotice( params: { receptor: string; publicId: string; expertLastName: string; }, ): Promise { return this.sendTemplate({ template: process.env.SMS_TEMPLATE_THIRD_PARTY_EXPERT_LOCK || "yara-blame-expert-lock", receptor: params.receptor, token: params.publicId, token2: params.expertLastName || "کارشناس", }); } async sendResendDocumentsNotice(params: { receptor: string; fileKind: "blame" | "claim"; publicId: string; link: string; }): Promise { return this.sendTemplate({ template: "yara-resend-documents", receptor: params.receptor, token: params.fileKind === "blame" ? "تصادف" : "خسارت", token2: params.publicId, token3: params.link, }); } async sendSignatureReviewNotice(params: { receptor: string; fileKind: "blame" | "claim"; publicId: string; expertLastName: string; link: string; }): Promise { return this.sendTemplate({ template: "yara-signature", receptor: params.receptor, token: params.fileKind === "blame" ? "تصادف" : "خسارت", token2: params.publicId, token3: params.expertLastName || "کارشناس", token10: params.link, }); } private async sendTemplate(args: TemplateArgs): Promise { try { await this.smsGatewayService.verifyLookUp(args); this.logger.log( `[SMS] template sent template=${args.template} receptor=${args.receptor}`, ); return true; } catch (err) { this.logger.error( `[SMS] template send failed template=${args.template} receptor=${args.receptor}: ${describeSmsError(err)}`, ); return false; } } }