notif after request
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
export class RequestCreatedEvent {
|
||||||
|
constructor(
|
||||||
|
public readonly requestId: string,
|
||||||
|
public readonly requestNumber: number,
|
||||||
|
public readonly userId: string,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import { OnEvent } from '@nestjs/event-emitter';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
import { AdminRepository } from 'src/modules/admin/repositories/admin.repository';
|
||||||
|
import { PermissionEnum } from 'src/common/enums/permission.enum';
|
||||||
|
import { NotificationService } from 'src/modules/notification/services/notification.service';
|
||||||
|
import { NotifChannelEnum, NotifTitle } from 'src/modules/notification/interfaces/notification.interface';
|
||||||
|
import { RequestCreatedEvent } from '../events/request.events';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RequestListeners {
|
||||||
|
private readonly logger = new Logger(RequestListeners.name);
|
||||||
|
private newRequestSmsTemplateId: string;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly adminRepository: AdminRepository,
|
||||||
|
private readonly notificationService: NotificationService,
|
||||||
|
private readonly configService: ConfigService,
|
||||||
|
) {
|
||||||
|
this.newRequestSmsTemplateId =
|
||||||
|
this.configService.get<string>('SMS_PATTERN_NEW_REQUEST') ?? 'new-request';
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnEvent(RequestCreatedEvent.name)
|
||||||
|
async handleRequestCreated(event: RequestCreatedEvent) {
|
||||||
|
try {
|
||||||
|
this.logger.log(
|
||||||
|
`Request created event: requestId=${event.requestId}, requestNumber=${event.requestNumber}, userId=${event.userId}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const admins = await this.adminRepository.findAdminsWithPermission(
|
||||||
|
PermissionEnum.NEW_REQUEST_NOTIFICATION,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (admins.length === 0) {
|
||||||
|
this.logger.log('No admins with NEW_REQUEST_NOTIFICATION permission');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = `درخواست جدید شماره ${event.requestNumber}`;
|
||||||
|
|
||||||
|
await this.notificationService.sendNotification({
|
||||||
|
channels: [NotifChannelEnum.SMS],
|
||||||
|
recipients: admins.map((admin) => ({ adminId: admin.id })),
|
||||||
|
message: {
|
||||||
|
title: NotifTitle.NEW_REQUEST,
|
||||||
|
content: body,
|
||||||
|
sms: {
|
||||||
|
templateId: this.newRequestSmsTemplateId,
|
||||||
|
parameters: {
|
||||||
|
requestNumber: String(event.requestNumber),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this.logger.log(
|
||||||
|
`SMS notification sent for ${admins.length} admin(s) for new request ${event.requestId}`,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(
|
||||||
|
`Failed to send notification for request created: ${event.requestId}`,
|
||||||
|
error instanceof Error ? error.stack : String(error),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,9 @@ import { ProductModule } from '../product/product.module';
|
|||||||
import { FormBuilderModule } from '../form-builder/form-builder.module';
|
import { FormBuilderModule } from '../form-builder/form-builder.module';
|
||||||
import { AuthModule } from '../auth/auth.module';
|
import { AuthModule } from '../auth/auth.module';
|
||||||
import { JwtModule } from '@nestjs/jwt';
|
import { JwtModule } from '@nestjs/jwt';
|
||||||
|
import { AdminModule } from '../admin/admin.module';
|
||||||
|
import { NotificationsModule } from '../notification/notifications.module';
|
||||||
|
import { RequestListeners } from './listeners/request.listeners';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -18,9 +21,11 @@ import { JwtModule } from '@nestjs/jwt';
|
|||||||
ProductModule,
|
ProductModule,
|
||||||
FormBuilderModule,
|
FormBuilderModule,
|
||||||
JwtModule,
|
JwtModule,
|
||||||
AuthModule
|
AuthModule,
|
||||||
|
AdminModule,
|
||||||
|
NotificationsModule,
|
||||||
],
|
],
|
||||||
controllers: [RequestController],
|
controllers: [RequestController],
|
||||||
providers: [RequestService, RequestRepository],
|
providers: [RequestService, RequestRepository, RequestListeners],
|
||||||
})
|
})
|
||||||
export class RequestModule {}
|
export class RequestModule {}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
|
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
|
||||||
import { EntityManager } from '@mikro-orm/postgresql';
|
import { EntityManager } from '@mikro-orm/postgresql';
|
||||||
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
import { CreateRequestDto } from './dto/create-request.dto';
|
import { CreateRequestDto } from './dto/create-request.dto';
|
||||||
import { UpdateRequestDto } from './dto/update-request.dto';
|
import { UpdateRequestDto } from './dto/update-request.dto';
|
||||||
import { FindRequestsDto } from './dto/find-requests.dto';
|
import { FindRequestsDto } from './dto/find-requests.dto';
|
||||||
@@ -10,6 +11,7 @@ import { UserService } from '../user/providers/user.service';
|
|||||||
import { ProductService } from '../product/providers/product.service';
|
import { ProductService } from '../product/providers/product.service';
|
||||||
import { FieldRepository } from '../form-builder/repository/field.repository';
|
import { FieldRepository } from '../form-builder/repository/field.repository';
|
||||||
import { RequestRepository } from './repositories/request.repository';
|
import { RequestRepository } from './repositories/request.repository';
|
||||||
|
import { RequestCreatedEvent } from './events/request.events';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RequestService {
|
export class RequestService {
|
||||||
@@ -19,6 +21,7 @@ export class RequestService {
|
|||||||
private readonly userService: UserService,
|
private readonly userService: UserService,
|
||||||
private readonly productService: ProductService,
|
private readonly productService: ProductService,
|
||||||
private readonly fieldRepository: FieldRepository,
|
private readonly fieldRepository: FieldRepository,
|
||||||
|
private readonly eventEmitter: EventEmitter2,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
async create(createRequestDto: CreateRequestDto, userId: string) {
|
async create(createRequestDto: CreateRequestDto, userId: string) {
|
||||||
@@ -47,6 +50,10 @@ export class RequestService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await em.flush();
|
await em.flush();
|
||||||
|
this.eventEmitter.emit(
|
||||||
|
RequestCreatedEvent.name,
|
||||||
|
new RequestCreatedEvent(request.id, request.requestNumber, user.id),
|
||||||
|
);
|
||||||
return request;
|
return request;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user