import { Injectable, NotFoundException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { renderSmsTemplate } from '../sms-templates/utils/render-sms-template.util'; import { SmsTemplatesService } from '../sms-templates/sms-templates.service'; import { SmsService } from '../sms/sms.service'; import { getSampleVariables, SMS_SCENARIOS, SMS_SCENARIO_MAP, } from './constants/sms-scenarios.constants'; import { PreviewSmsScenarioDto } from './dto/update-sms-scenario-setting.dto'; import { SmsScenarioSetting } from './entities/sms-scenario-setting.entity'; import { SmsScenarioKey } from './enums/sms-scenario-key.enum'; @Injectable() export class SmsDispatchService { constructor( @InjectRepository(SmsScenarioSetting) private readonly settingsRepository: Repository, private readonly smsTemplatesService: SmsTemplatesService, private readonly smsService: SmsService, ) {} getScenarioDefinitions() { return SMS_SCENARIOS; } async findAllSettings(): Promise { return this.settingsRepository.find({ relations: { template: true }, order: { key: 'ASC' }, }); } async findSettingByKey(key: SmsScenarioKey): Promise { const setting = await this.settingsRepository.findOne({ where: { key }, relations: { template: true }, }); if (!setting) { throw new NotFoundException(`SMS scenario setting "${key}" not found`); } return setting; } async resolveMessage( key: SmsScenarioKey, variables: Record, ): Promise { const setting = await this.findSettingByKey(key); if (!setting.isActive) { return null; } const body = await this.resolveBody(setting); if (!body) { return null; } return renderSmsTemplate(body, variables); } async resolveMessageFromTemplateId( templateId: string, variables: Record, ): Promise { const template = await this.smsTemplatesService.findOne(templateId); if (!template.isActive) { return null; } return renderSmsTemplate(template.body, variables); } async previewMessage(dto: PreviewSmsScenarioDto): Promise { const body = await this.resolvePreviewBody(dto); const variables = getSampleVariables(dto.key); return renderSmsTemplate(body, variables); } async sendScenarioSms( key: SmsScenarioKey, mobile: string, variables: Record, ): Promise { const message = await this.resolveMessage(key, variables); if (!message) { return false; } return this.smsService.sendSms(mobile, message); } private async resolveBody( setting: SmsScenarioSetting, ): Promise { if (setting.templateId) { const template = await this.smsTemplatesService.findOne( setting.templateId, ); if (!template.isActive) { return null; } return template.body; } if (setting.body) { return setting.body; } return SMS_SCENARIO_MAP.get(setting.key)?.defaultBody ?? null; } private async resolvePreviewBody( dto: PreviewSmsScenarioDto, ): Promise { if (dto.templateId) { const template = await this.smsTemplatesService.findOne(dto.templateId); return template.body; } if (dto.body) { return dto.body; } const setting = await this.findSettingByKey(dto.key); const resolved = await this.resolveBody(setting); if (!resolved) { throw new NotFoundException('No SMS body configured for this scenario'); } return resolved; } }