import { Inject, Injectable, Logger, OnApplicationBootstrap, } from "@nestjs/common"; import { ClientProxy } from "@nestjs/microservices"; import { BulkMessagesDto, SingleMessageDto } from "./dtos/sms.dto"; import { isBrokerConnected, publishConfirmed } from "./broker.util"; @Injectable() export class SmsClientService implements OnApplicationBootstrap { private readonly logger = new Logger(SmsClientService.name); constructor( @Inject("SMS_SERVICE") private smsClient: ClientProxy, ) { } private readonly enabled = process.env.RABBITMQ_ENABLED !== "false"; async onApplicationBootstrap() { if (!this.enabled) return; this.smsClient .connect() .then(() => { this.logger.log("connected to SMS service"); }) .catch((err) => { this.logger.error("Error happened at SMS service", err); }); } async sendSms(dto: SingleMessageDto): Promise<{ queued: boolean }> { if (!this.enabled) { this.logger.warn(`RABBITMQ disabled — skipped SMS`); return { queued: false }; } const queued = await publishConfirmed( this.smsClient, "send-sms", { to: dto.to, text: dto.message, appKey: "IFHCRS-LICENSE-MANAGEMENT", }, this.logger, ); // Publisher-confirmed: RabbitMQ has taken ownership of the message. Still NOT // delivery — the consumer, the SMS gateway and the carrier are all downstream // of this and invisible from here. this.logger.log( `SMS publish to RabbitMQ [${process.env.SMS_QUEUE ?? "sms_queue"}] pattern='send-sms' confirmed=${queued}`, ); // Recipient + content are PII — debug only. this.logger.debug(`SMS payload to=${dto.to} text="${dto.message}"`); return { queued }; } async sendBulkMessages(dto: BulkMessagesDto): Promise<{ queued: boolean }> { if (!this.enabled) { this.logger.warn( `RABBITMQ disabled — skipped BULK SMS (${dto.messages?.length ?? 0} messages)`, ); return { queued: false }; } const messages = (dto.messages ?? []).map((m) => ({ to: m.to, text: m.message, from: m.from, })); const queued = await publishConfirmed( this.smsClient, "ozeking-bulk-sms", { messages, appKey: "IFHCRS-LICENSE-MANAGEMENT", }, this.logger, ); this.logger.log( `BULK SMS publish to RabbitMQ [${process.env.SMS_QUEUE ?? "sms_queue"}] pattern='ozeking-bulk-sms' count=${messages.length} confirmed=${queued}`, ); this.logger.debug(`BULK SMS payload messages=${JSON.stringify(messages)}`); return { queued }; } /** * Connection state for the health endpoint. `null` means the broker client did * not expose its manager — reported as "unknown" rather than assumed healthy. */ get brokerConnected(): boolean | null { if (!this.enabled) return false; return isBrokerConnected(this.smsClient); } }