multiple notification strategies

This commit is contained in:
Tria
2026-06-03 16:17:36 +03:00
parent 36a8002163
commit da10d067f8
7 changed files with 81 additions and 8 deletions

View File

@@ -15,6 +15,7 @@
"dependencies": {
"@edr/api-common": "workspace:*",
"@edr/types": "workspace:*",
"@nestjs/axios": "^4.0.1",
"@nestjs/common": "^11.0.0",
"@nestjs/config": "^4.0.0",
"@nestjs/core": "^11.0.0",
@@ -27,7 +28,7 @@
"@tria-plc/iamapi-common": "^0.1.6",
"amqp-connection-manager": "^5.0.0",
"amqplib": "^2.0.1",
"axios": "^1.7.7",
"axios": "^1.16.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"dotenv": "^17.4.2",
@@ -76,4 +77,4 @@
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
}

View File

@@ -1,9 +1,14 @@
import { Module } from "@nestjs/common";
import { NotificationsService } from "./notifications.service";
import { EmailNotificationStrategy } from "./strategies/notification.email.strategy";
import { SmsNotificationStrategy } from "./strategies/notification.sms.strategy";
import { HttpModule } from "@nestjs/axios";
@Module({
providers: [NotificationsService],
imports: [HttpModule],
controllers: [],
providers: [EmailNotificationStrategy, SmsNotificationStrategy, NotificationsService],
exports: [NotificationsService],
})
export class NotificationsModule {}
export class NotificationsModule { }

View File

@@ -1,14 +1,35 @@
import { Injectable, Logger } from "@nestjs/common";
import { Injectable, Logger, NotFoundException } from "@nestjs/common";
import { EmailNotificationStrategy } from "./strategies/notification.email.strategy";
import { NotificationStrategy } from "./strategies/notification.strategy";
import { SmsNotificationStrategy } from "./strategies/notification.sms.strategy";
type StrategyMethod = "sms" | "email"
@Injectable()
export class NotificationsService {
private readonly logger = new Logger(NotificationsService.name);
private readonly strategies: Map<StrategyMethod, NotificationStrategy>
constructor(private readonly email: EmailNotificationStrategy, private readonly sms: SmsNotificationStrategy) {
this.strategies = new Map([
["sms", this.sms as NotificationStrategy],
["email", this.email as NotificationStrategy]
])
}
/**
* Dispatch a notification to an operator or customer.
* TODO: wire to email/SMS provider (SendGrid, SMS API, etc.) via a mailer service.
*/
async send(recipient: string, subject: string, body: string): Promise<void> {
this.logger.log(`[notify] ${recipient} :: ${subject} :: ${body}`);
async directSend(method: StrategyMethod, recipient: string, message: string) {
const strategy = this.strategies.get(method);
if (!strategy) {
throw new NotFoundException();
}
const sent = await strategy.send(recipient, message)
this.logger.log(`is sent - ${sent}`)
}
}

View File

@@ -0,0 +1,12 @@
import { Injectable, Logger } from "@nestjs/common";
import { NotificationStrategy } from "./notification.strategy";
@Injectable()
export class EmailNotificationStrategy implements NotificationStrategy {
private readonly logger = new Logger(EmailNotificationStrategy.name);
constructor() { }
async send(recipient: string, message: string): Promise<boolean> {
this.logger.log(`${recipient}, ${message}`)
return false;
}
}

View File

@@ -0,0 +1,25 @@
import { Injectable} from "@nestjs/common";
import { NotificationStrategy } from "./notification.strategy";
import { HttpService } from '@nestjs/axios';
import { ConfigService } from "@nestjs/config";
import { firstValueFrom } from 'rxjs';
@Injectable()
export class SmsNotificationStrategy implements NotificationStrategy {
constructor(private readonly httpService: HttpService, private readonly configService: ConfigService) { }
async send(recipient: string, message: string) {
const url = this.configService.get("OZIKING_SMS_URL")
const body = {
to: recipient,
text: message
}
const response = await firstValueFrom(
this.httpService.post(
url,
body,
),
);
return response.status === 201;
}
}

View File

@@ -0,0 +1,6 @@
import { Injectable } from "@nestjs/common";
@Injectable()
export abstract class NotificationStrategy {
abstract send(recipient: string, message: string): Promise<boolean>
}

5
pnpm-lock.yaml generated
View File

@@ -44,6 +44,9 @@ importers:
'@edr/types':
specifier: workspace:*
version: link:../../packages/types
'@nestjs/axios':
specifier: ^4.0.1
version: 4.0.1(@nestjs/common@11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.16.1)(rxjs@7.8.2)
'@nestjs/common':
specifier: ^11.0.0
version: 11.1.23(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)
@@ -81,7 +84,7 @@ importers:
specifier: ^2.0.1
version: 2.0.1
axios:
specifier: ^1.7.7
specifier: ^1.16.1
version: 1.16.1
class-transformer:
specifier: ^0.5.1