138 lines
3.7 KiB
TypeScript
138 lines
3.7 KiB
TypeScript
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<SmsScenarioSetting>,
|
|
private readonly smsTemplatesService: SmsTemplatesService,
|
|
private readonly smsService: SmsService,
|
|
) {}
|
|
|
|
getScenarioDefinitions() {
|
|
return SMS_SCENARIOS;
|
|
}
|
|
|
|
async findAllSettings(): Promise<SmsScenarioSetting[]> {
|
|
return this.settingsRepository.find({
|
|
relations: { template: true },
|
|
order: { key: 'ASC' },
|
|
});
|
|
}
|
|
|
|
async findSettingByKey(key: SmsScenarioKey): Promise<SmsScenarioSetting> {
|
|
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<string, string>,
|
|
): Promise<string | null> {
|
|
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<string, string>,
|
|
): Promise<string | null> {
|
|
const template = await this.smsTemplatesService.findOne(templateId);
|
|
if (!template.isActive) {
|
|
return null;
|
|
}
|
|
|
|
return renderSmsTemplate(template.body, variables);
|
|
}
|
|
|
|
async previewMessage(dto: PreviewSmsScenarioDto): Promise<string> {
|
|
const body = await this.resolvePreviewBody(dto);
|
|
const variables = getSampleVariables(dto.key);
|
|
return renderSmsTemplate(body, variables);
|
|
}
|
|
|
|
async sendScenarioSms(
|
|
key: SmsScenarioKey,
|
|
mobile: string,
|
|
variables: Record<string, string>,
|
|
): Promise<boolean> {
|
|
const message = await this.resolveMessage(key, variables);
|
|
if (!message) {
|
|
return false;
|
|
}
|
|
|
|
return this.smsService.sendSms(mobile, message);
|
|
}
|
|
|
|
private async resolveBody(
|
|
setting: SmsScenarioSetting,
|
|
): Promise<string | null> {
|
|
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<string> {
|
|
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;
|
|
}
|
|
}
|