refactor: made the sms to use queue
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
export const SMS_CONFIG = "SMS_CONFIG";
|
||||
export const SMS_QUEUE = 'sms';
|
||||
@@ -0,0 +1,24 @@
|
||||
export interface SmsParameter {
|
||||
name: SmsTemplateParameter;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface SmsRequest {
|
||||
Mobile: string;
|
||||
TemplateId: string;
|
||||
Parameters: SmsParameter[];
|
||||
}
|
||||
|
||||
export interface SmsResponse {
|
||||
status: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface SmsSendResponse extends SmsResponse {
|
||||
data: {
|
||||
MessageId: number;
|
||||
Cost: number;
|
||||
};
|
||||
}
|
||||
|
||||
export type SmsTemplateParameter = string;
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { BullModule } from '@nestjs/bullmq';
|
||||
import { SmsService } from './providers/sms.service';
|
||||
import { SmsProducer } from './producers/sms.producer';
|
||||
import { SmsProcessor } from './processors/sms.processor';
|
||||
import { SMS_CONFIG, SMS_QUEUE } from './constants';
|
||||
import { smsConfigsProvider } from 'src/config/sms.config';
|
||||
import { HttpModule } from '@nestjs/axios';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
HttpModule,
|
||||
BullModule.registerQueue({
|
||||
name: SMS_QUEUE,
|
||||
}),
|
||||
],
|
||||
providers: [SmsService, smsConfigsProvider, SmsProducer, SmsProcessor],
|
||||
exports: [SmsProducer, SMS_CONFIG],
|
||||
})
|
||||
export class NotificationModule {}
|
||||
|
||||
export { SMS_QUEUE };
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Processor, WorkerHost } from '@nestjs/bullmq';
|
||||
import { Job } from 'bullmq';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { SMS_QUEUE } from '../constants';
|
||||
import { SmsService } from '../providers/sms.service';
|
||||
import { SmsRequest } from '../interfaces/ISms';
|
||||
|
||||
@Processor(SMS_QUEUE)
|
||||
export class SmsProcessor extends WorkerHost {
|
||||
private readonly logger = new Logger(SmsProcessor.name);
|
||||
|
||||
constructor(private readonly smsService: SmsService) {
|
||||
super();
|
||||
}
|
||||
|
||||
async process(job: Job<SmsRequest>): Promise<void> {
|
||||
this.logger.log(
|
||||
`Processing SMS job ${job.id} (attempt ${job.attemptsMade + 1})`,
|
||||
);
|
||||
await this.smsService.sendSms(job.data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectQueue } from '@nestjs/bullmq';
|
||||
import { Queue } from 'bullmq';
|
||||
import { SMS_QUEUE } from '../constants';
|
||||
import { SmsRequest } from '../interfaces/ISms';
|
||||
|
||||
@Injectable()
|
||||
export class SmsProducer {
|
||||
constructor(@InjectQueue(SMS_QUEUE) private readonly smsQueue: Queue) {}
|
||||
|
||||
async sendSms(body: SmsRequest) {
|
||||
return this.smsQueue.add('send-sms', body, {
|
||||
attempts: 3,
|
||||
backoff: { type: 'exponential', delay: 2000 },
|
||||
removeOnComplete: true,
|
||||
removeOnFail: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import {
|
||||
Inject,
|
||||
Injectable,
|
||||
InternalServerErrorException,
|
||||
Logger,
|
||||
} from '@nestjs/common';
|
||||
import { SMS_CONFIG } from '../constants';
|
||||
import type { ISmsConfigs } from 'src/config/sms.config';
|
||||
import { catchError, firstValueFrom } from 'rxjs';
|
||||
import { HttpService } from '@nestjs/axios';
|
||||
import { AxiosError } from 'axios';
|
||||
import { SmsRequest, SmsSendResponse } from '../interfaces/ISms';
|
||||
|
||||
@Injectable()
|
||||
export class SmsService {
|
||||
private readonly logger = new Logger(SmsService.name);
|
||||
|
||||
constructor(
|
||||
@Inject(SMS_CONFIG) private smsConfigs: ISmsConfigs,
|
||||
private readonly httpService: HttpService,
|
||||
) {}
|
||||
|
||||
async sendSms(body: SmsRequest): Promise<SmsSendResponse> {
|
||||
try {
|
||||
const { data } = await firstValueFrom(
|
||||
this.httpService
|
||||
.post<SmsSendResponse>(
|
||||
`${this.smsConfigs.API_URL}/send/verify`,
|
||||
body,
|
||||
{
|
||||
headers: {
|
||||
'X-API-KEY': this.smsConfigs.API_KEY,
|
||||
},
|
||||
timeout: 5000,
|
||||
},
|
||||
)
|
||||
.pipe(
|
||||
catchError((error: AxiosError) => {
|
||||
this.logger.error(
|
||||
'Error while calling SMS provider.',
|
||||
error.stack,
|
||||
);
|
||||
|
||||
throw new InternalServerErrorException(
|
||||
'Failed to communicate with SMS provider.',
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
'Failed to send SMS.',
|
||||
error instanceof Error ? error.stack : undefined,
|
||||
);
|
||||
|
||||
throw new InternalServerErrorException('Failed to send SMS.');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user