notification
This commit is contained in:
parent
46979c6b9e
commit
88bf1cabb6
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"id": -1002593407119,
|
||||
"title": "Bid histories dev",
|
||||
"type": "supergroup",
|
||||
"invite_link": "https://t.me/+CSBIA7mbyBhkM2Jl",
|
||||
"permissions": {
|
||||
"can_send_messages": true,
|
||||
"can_send_media_messages": true,
|
||||
"can_send_audios": true,
|
||||
"can_send_documents": true,
|
||||
"can_send_photos": true,
|
||||
"can_send_videos": true,
|
||||
"can_send_video_notes": true,
|
||||
"can_send_voice_notes": true,
|
||||
"can_send_polls": true,
|
||||
"can_send_other_messages": true,
|
||||
"can_add_web_page_previews": true,
|
||||
"can_change_info": true,
|
||||
"can_invite_users": true,
|
||||
"can_pin_messages": true,
|
||||
"can_manage_topics": true
|
||||
},
|
||||
"join_to_send_messages": true,
|
||||
"max_reaction_count": 11,
|
||||
"accent_color_id": 2
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"createdAt":1743133400720}
|
||||
|
|
@ -13,6 +13,7 @@ import {
|
|||
} from './system/routes/exclude-route';
|
||||
import { AuthorizationMiddleware } from './modules/admins/middlewares/authorization.middleware';
|
||||
import { ClientAuthenticationMiddleware } from './modules/auth/middlewares/client-authentication.middleware';
|
||||
import { NotificationModule } from './modules/notification/notification.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
|
|
@ -22,6 +23,7 @@ import { ClientAuthenticationMiddleware } from './modules/auth/middlewares/clien
|
|||
AppValidatorsModule,
|
||||
AuthModule,
|
||||
AdminsModule,
|
||||
NotificationModule,
|
||||
],
|
||||
controllers: [],
|
||||
providers: [],
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { EventEmitterModule } from '@nestjs/event-emitter';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
}),
|
||||
EventEmitterModule.forRoot({
|
||||
wildcard: true,
|
||||
global: true,
|
||||
}),
|
||||
],
|
||||
})
|
||||
export class AppConfigsModule {}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,18 @@ import { escapeMarkdownV2 } from 'src/ultils';
|
|||
import { Bid } from '../entities/bid.entity';
|
||||
import * as dayjs from 'dayjs';
|
||||
import { SendMessageHistoriesService } from '../services/send-message-histories.service';
|
||||
import { join } from 'path';
|
||||
import { Constant } from '../utils/constant';
|
||||
import {
|
||||
existsSync,
|
||||
mkdir,
|
||||
mkdirSync,
|
||||
readdirSync,
|
||||
readFileSync,
|
||||
statSync,
|
||||
writeFile,
|
||||
writeFileSync,
|
||||
} from 'fs';
|
||||
|
||||
@Injectable()
|
||||
export class BotTelegramApi {
|
||||
|
|
@ -64,6 +76,73 @@ export class BotTelegramApi {
|
|||
}
|
||||
}
|
||||
|
||||
async createFolderPath(): Promise<string> {
|
||||
const rootDir = process.cwd();
|
||||
const folderPath = join(rootDir, `${Constant.BOT_TELEGRAM_PATH}`);
|
||||
|
||||
if (!existsSync(folderPath)) {
|
||||
mkdirSync(folderPath, { recursive: true, mode: 0o777 });
|
||||
|
||||
// ✅ Lưu metadata lần đầu
|
||||
const metadataPath = join(folderPath, 'metadata.json');
|
||||
writeFileSync(
|
||||
metadataPath,
|
||||
JSON.stringify({ createdAt: Date.now() }),
|
||||
'utf-8',
|
||||
);
|
||||
}
|
||||
|
||||
return folderPath;
|
||||
}
|
||||
|
||||
async getGroupInfo(
|
||||
chatId: string = this.configService.get<string>('CHAT_ID'),
|
||||
): Promise<any> {
|
||||
try {
|
||||
const folderPath = await this.createFolderPath();
|
||||
const metadataPath = join(folderPath, 'metadata.json');
|
||||
const dataFilePath = join(folderPath, `group_${chatId}.json`);
|
||||
|
||||
// 10 minute
|
||||
const TIME_TO_REFRESH_DATA = 10;
|
||||
|
||||
if (existsSync(metadataPath)) {
|
||||
const metadata = JSON.parse(readFileSync(metadataPath, 'utf-8'));
|
||||
const createdAt = metadata?.createdAt || 0;
|
||||
const now = Date.now();
|
||||
const diffMinutes = (now - createdAt) / 60000;
|
||||
|
||||
if (diffMinutes < TIME_TO_REFRESH_DATA && existsSync(dataFilePath)) {
|
||||
return JSON.parse(readFileSync(dataFilePath, 'utf-8'));
|
||||
}
|
||||
}
|
||||
|
||||
const url = `${this.apiUrl}/getChat`;
|
||||
const { data } = await axios({
|
||||
url,
|
||||
params: { chat_id: chatId },
|
||||
family: 4,
|
||||
});
|
||||
|
||||
if (data?.ok) {
|
||||
writeFileSync(
|
||||
dataFilePath,
|
||||
JSON.stringify(data.result, null, 2),
|
||||
'utf-8',
|
||||
);
|
||||
writeFileSync(
|
||||
metadataPath,
|
||||
JSON.stringify({ createdAt: Date.now() }),
|
||||
'utf-8',
|
||||
);
|
||||
|
||||
return data.result;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error || error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async sendBidInfo(bid: Bid): Promise<boolean> {
|
||||
try {
|
||||
const text = this.formatBidMessage(bid);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import { AdminSendMessageHistoriesController } from './controllers/admin/admin-s
|
|||
import { AuthModule } from '../auth/auth.module';
|
||||
import { AdminsModule } from '../admins/admins.module';
|
||||
import { AdminBidGateway } from './getways/admin-bid-getway';
|
||||
import { NotificationModule } from '../notification/notification.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
|
|
@ -35,11 +36,9 @@ import { AdminBidGateway } from './getways/admin-bid-getway';
|
|||
WebBid,
|
||||
SendMessageHistory,
|
||||
]),
|
||||
EventEmitterModule.forRoot({
|
||||
wildcard: true,
|
||||
}),
|
||||
// AuthModule,
|
||||
AdminsModule,
|
||||
NotificationModule,
|
||||
],
|
||||
controllers: [
|
||||
BidsController,
|
||||
|
|
@ -62,5 +61,6 @@ import { AdminBidGateway } from './getways/admin-bid-getway';
|
|||
GraysApi,
|
||||
SendMessageHistoriesService,
|
||||
],
|
||||
exports: [BotTelegramApi],
|
||||
})
|
||||
export class BidsModule {}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,16 @@
|
|||
import { AdminsService } from '@/modules/admins/services/admins.service';
|
||||
import { getWayMiddleware } from '@/modules/auth/middlewares/get-way.middleware';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import {
|
||||
OnGatewayConnection,
|
||||
WebSocketGateway,
|
||||
WebSocketServer,
|
||||
SubscribeMessage,
|
||||
OnGatewayConnection,
|
||||
} from '@nestjs/websockets';
|
||||
import { Server, Socket } from 'socket.io';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { BidsService } from '../services/bids.service';
|
||||
import { WebBidsService } from '../services/web-bids.service';
|
||||
import { plainToClass } from 'class-transformer';
|
||||
import { Server, Socket } from 'socket.io';
|
||||
import { WebBid } from '../entities/wed-bid.entity';
|
||||
import * as cookie from 'cookie';
|
||||
import { Constant } from '@/modules/auth/ultils/constant';
|
||||
import { getWayMiddleware } from '@/modules/auth/middlewares/get-way.middleware';
|
||||
import { AdminsService } from '@/modules/admins/services/admins.service';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { WebBidsService } from '../services/web-bids.service';
|
||||
|
||||
@WebSocketGateway({
|
||||
namespace: 'admin-bid-ws',
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { Bid } from '../entities/bid.entity';
|
|||
import { CreateBidHistoryDto } from '../dto/bid-history/create-bid-history.dto';
|
||||
import { BotTelegramApi } from '../apis/bot-telegram.api';
|
||||
import { SendMessageHistoriesService } from './send-message-histories.service';
|
||||
import { NotificationService } from '@/modules/notification/notification.service';
|
||||
|
||||
@Injectable()
|
||||
export class BidHistoriesService {
|
||||
|
|
@ -23,6 +24,7 @@ export class BidHistoriesService {
|
|||
readonly bidsRepo: Repository<Bid>,
|
||||
private readonly botTelegramApi: BotTelegramApi,
|
||||
readonly sendMessageHistoriesService: SendMessageHistoriesService,
|
||||
private readonly notificationService: NotificationService,
|
||||
) {}
|
||||
|
||||
async index() {
|
||||
|
|
@ -54,6 +56,9 @@ export class BidHistoriesService {
|
|||
if (price + bid.plus_price > bid.max_price) {
|
||||
this.bidsRepo.update(bid_id, { status: 'out-bid' });
|
||||
|
||||
// send message event
|
||||
this.notificationService.emitBidStatus({ ...bid, status: 'out-bid' });
|
||||
|
||||
throw new BadRequestException(
|
||||
AppResponse.toResponse(null, {
|
||||
message: 'Price is more than Max price ' + bid.max_price,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import { Bid } from '../entities/bid.entity';
|
|||
import { ImageCompressionPipe } from '../pipes/image-compression-pipe';
|
||||
import { Constant } from '../utils/constant';
|
||||
import { WebBidsService } from './web-bids.service';
|
||||
import { NotificationService } from '@/modules/notification/notification.service';
|
||||
|
||||
@Injectable()
|
||||
export class BidsService {
|
||||
|
|
@ -39,6 +40,7 @@ export class BidsService {
|
|||
readonly bidHistoriesRepo: Repository<BidHistory>,
|
||||
private readonly webBidsService: WebBidsService,
|
||||
private eventEmitter: EventEmitter2,
|
||||
private notificationService: NotificationService,
|
||||
) {}
|
||||
|
||||
async index(query: PaginateQuery) {
|
||||
|
|
@ -159,6 +161,9 @@ export class BidsService {
|
|||
|
||||
this.emitAllBidEvent();
|
||||
|
||||
// send message event
|
||||
this.notificationService.emitBidStatus({ ...bid, status: 'out-bid' });
|
||||
|
||||
return AppResponse.toResponse(true);
|
||||
}
|
||||
|
||||
|
|
@ -183,6 +188,9 @@ export class BidsService {
|
|||
|
||||
await this.bidsRepo.update(id, { status: 'biding' });
|
||||
|
||||
// send message event
|
||||
this.notificationService.emitBidStatus({ ...bid, status: 'biding' });
|
||||
|
||||
this.emitAllBidEvent();
|
||||
return AppResponse.toResponse(true);
|
||||
}
|
||||
|
|
@ -210,12 +218,6 @@ export class BidsService {
|
|||
data.current_price >= bid.max_price + bid.plus_price ||
|
||||
(bid.close_time && isTimeReached(bid.close_time))
|
||||
) {
|
||||
console.log({
|
||||
a: data.current_price >= bid.max_price + bid.plus_price,
|
||||
b: bid.close_time && !close_time,
|
||||
c: bid.close_time && isTimeReached(bid.close_time),
|
||||
});
|
||||
|
||||
bid.status = 'out-bid';
|
||||
}
|
||||
|
||||
|
|
@ -234,16 +236,26 @@ export class BidsService {
|
|||
|
||||
this.emitAllBidEvent();
|
||||
|
||||
// send event message
|
||||
if (result.status === 'out-bid') {
|
||||
this.notificationService.emitBidStatus(result);
|
||||
}
|
||||
|
||||
return AppResponse.toResponse(plainToClass(Bid, result));
|
||||
}
|
||||
|
||||
async outBid(id: Bid['id']) {
|
||||
const result = await this.bidsRepo.update(id, { status: 'out-bid' });
|
||||
|
||||
const bid = await this.bidsRepo.findOne({ where: { id } });
|
||||
|
||||
if (!result) throw new BadRequestException(AppResponse.toResponse(false));
|
||||
|
||||
await this.emitAllBidEvent();
|
||||
|
||||
// send message event
|
||||
this.notificationService.emitBidStatus(bid);
|
||||
|
||||
return AppResponse.toResponse(true);
|
||||
}
|
||||
|
||||
|
|
@ -309,9 +321,25 @@ export class BidsService {
|
|||
});
|
||||
|
||||
if (lastHistory && lastHistory.price === data.current_price) {
|
||||
await this.bidsRepo.update(bid.id, { status: 'win-bid' });
|
||||
if (bid.status !== 'win-bid') {
|
||||
await this.bidsRepo.update(bid.id, { status: 'win-bid' });
|
||||
|
||||
// send event message
|
||||
this.notificationService.emitBidStatus({
|
||||
...bid,
|
||||
status: 'win-bid',
|
||||
});
|
||||
}
|
||||
} else {
|
||||
await this.bidsRepo.update(bid.id, { status: 'out-bid' });
|
||||
if (bid.status !== 'out-bid') {
|
||||
await this.bidsRepo.update(bid.id, { status: 'out-bid' });
|
||||
|
||||
// send event message
|
||||
this.notificationService.emitBidStatus({
|
||||
...bid,
|
||||
status: 'out-bid',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.emitAllBidEvent();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
export class Constant {
|
||||
public static MEDIA_PATH = 'public';
|
||||
public static BOT_TELEGRAM_PATH = 'bot-data';
|
||||
|
||||
public static WORK_IMAGES_FOLDER = 'work-images';
|
||||
public static TMP_FOLDER = 'tmp';
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
export const NAME_EVENTS = {
|
||||
BID_STATUS: 'notify.bid-status',
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export class CreateNotificationDto {}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { PartialType } from '@nestjs/mapped-types';
|
||||
import { CreateNotificationDto } from './create-notification.dto';
|
||||
|
||||
export class UpdateNotificationDto extends PartialType(CreateNotificationDto) {}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { Timestamp } from './timestamp';
|
||||
|
||||
@Entity('notifications')
|
||||
@Index(['message', 'raw_data'])
|
||||
export class Notification extends Timestamp {
|
||||
@PrimaryGeneratedColumn('increment')
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
message: string;
|
||||
|
||||
@Column({ type: 'varchar' })
|
||||
raw_data: string;
|
||||
|
||||
@Column({ default: null, nullable: true })
|
||||
read_at: Date | null;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
send_to: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { CreateDateColumn, UpdateDateColumn } from 'typeorm';
|
||||
export abstract class Timestamp {
|
||||
@CreateDateColumn({ type: 'timestamp', name: 'created_at' })
|
||||
created_at: Date;
|
||||
|
||||
@UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })
|
||||
updated_at: Date;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { OnEvent } from '@nestjs/event-emitter';
|
||||
import { NAME_EVENTS } from '../constants';
|
||||
import { Bid } from '@/modules/bids/entities/bid.entity';
|
||||
import { Notification } from '../entities/notification.entity';
|
||||
import { BotTelegramApi } from '@/modules/bids/apis/bot-telegram.api';
|
||||
|
||||
@Injectable()
|
||||
export class AdminNotificationListener {
|
||||
constructor(private readonly botTelegramApi: BotTelegramApi) {}
|
||||
|
||||
@OnEvent(NAME_EVENTS.BID_STATUS)
|
||||
handleBidStatus({
|
||||
bid,
|
||||
notification,
|
||||
}: {
|
||||
bid: Bid;
|
||||
notification: Notification;
|
||||
}) {
|
||||
if (JSON.parse(notification.send_to).length <= 0) return;
|
||||
|
||||
this.botTelegramApi.sendMessage(notification.message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { NotificationController } from './notification.controller';
|
||||
import { NotificationService } from './notification.service';
|
||||
|
||||
describe('NotificationController', () => {
|
||||
let controller: NotificationController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [NotificationController],
|
||||
providers: [NotificationService],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<NotificationController>(NotificationController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import { Controller, Get } from '@nestjs/common';
|
||||
import { BotTelegramApi } from '../bids/apis/bot-telegram.api';
|
||||
import { NotificationService } from './notification.service';
|
||||
|
||||
@Controller('admin/notifications')
|
||||
export class NotificationController {
|
||||
constructor(
|
||||
private readonly notificationService: NotificationService,
|
||||
private botTelegramApi: BotTelegramApi,
|
||||
) {}
|
||||
|
||||
@Get('')
|
||||
async test() {
|
||||
return await this.botTelegramApi.getGroupInfo();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import { forwardRef, Module } from '@nestjs/common';
|
||||
import { NotificationService } from './notification.service';
|
||||
import { NotificationController } from './notification.controller';
|
||||
import { BidsModule } from '../bids/bids.module';
|
||||
import { Notification } from './entities/notification.entity';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { AdminNotificationListener } from './listeners/admin-notification.listener';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
forwardRef(() => BidsModule),
|
||||
TypeOrmModule.forFeature([Notification]),
|
||||
],
|
||||
controllers: [NotificationController],
|
||||
providers: [NotificationService, AdminNotificationListener],
|
||||
exports: [NotificationService],
|
||||
})
|
||||
export class NotificationModule {}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { NotificationService } from './notification.service';
|
||||
|
||||
describe('NotificationService', () => {
|
||||
let service: NotificationService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [NotificationService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<NotificationService>(NotificationService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { Bid } from '../bids/entities/bid.entity';
|
||||
import { NAME_EVENTS } from './constants';
|
||||
import { BotTelegramApi } from '../bids/apis/bot-telegram.api';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Notification } from './entities/notification.entity';
|
||||
import { Repository } from 'typeorm';
|
||||
import { isTimeReached } from '@/ultils';
|
||||
import {
|
||||
FilterOperator,
|
||||
FilterSuffix,
|
||||
paginate,
|
||||
PaginateQuery,
|
||||
} from 'nestjs-paginate';
|
||||
import { Column } from 'nestjs-paginate/lib/helper';
|
||||
import AppResponse from '@/response/app-response';
|
||||
|
||||
@Injectable()
|
||||
export class NotificationService {
|
||||
constructor(
|
||||
private eventEmitter: EventEmitter2,
|
||||
private readonly botTelegramApi: BotTelegramApi,
|
||||
@InjectRepository(Notification)
|
||||
readonly notificationRepo: Repository<Notification>,
|
||||
) {}
|
||||
|
||||
async index(query: PaginateQuery) {
|
||||
const filterableColumns: {
|
||||
[key in Column<Bid> | (string & {})]?:
|
||||
| (FilterOperator | FilterSuffix)[]
|
||||
| true;
|
||||
} = {
|
||||
id: true,
|
||||
message: true,
|
||||
};
|
||||
|
||||
query.filter = AppResponse.processFilters(query.filter, filterableColumns);
|
||||
|
||||
const data = await paginate(query, this.notificationRepo, {
|
||||
sortableColumns: ['id'],
|
||||
searchableColumns: ['id'],
|
||||
defaultLimit: 15,
|
||||
filterableColumns,
|
||||
defaultSortBy: [['id', 'DESC']],
|
||||
maxLimit: 100,
|
||||
});
|
||||
|
||||
return AppResponse.toPagination<Notification>(data, true, Notification);
|
||||
}
|
||||
|
||||
getBidStatusMessage(bid: Bid): string | null {
|
||||
switch (bid.status) {
|
||||
case 'biding':
|
||||
return !bid.name ? null : `✅ The item has been activated. ${bid.name}`;
|
||||
|
||||
case 'out-bid':
|
||||
if (isTimeReached(bid.close_time)) {
|
||||
return `⏳ The auction for *${bid.name || 'this item'}* has ended.`;
|
||||
}
|
||||
|
||||
const itemName = `*${bid.name || 'the item'}*`;
|
||||
|
||||
if (
|
||||
bid.max_price + bid.plus_price <= bid.current_price ||
|
||||
bid.reserve_price > bid.max_price + bid.plus_price
|
||||
) {
|
||||
return `💰 The current bid for ${itemName} has exceeded your maximum bid.`;
|
||||
}
|
||||
|
||||
return `🛑 The auction for ${itemName} has been canceled.`;
|
||||
|
||||
case 'win-bid':
|
||||
return `🎉 Congratulations! You won the auction for ${itemName} at *${bid.current_price}*.`;
|
||||
|
||||
default:
|
||||
return '❓ Unknown auction status.';
|
||||
}
|
||||
}
|
||||
|
||||
async emitBidStatus(bid: Bid, sendTo: boolean = true) {
|
||||
const groupData = await this.botTelegramApi.getGroupInfo();
|
||||
const sendToData = groupData && sendTo ? [groupData?.title || 'None'] : [];
|
||||
|
||||
const message = this.getBidStatusMessage(bid);
|
||||
if (!message) return;
|
||||
|
||||
const notification = await this.notificationRepo.save({
|
||||
message,
|
||||
raw_data: JSON.stringify({
|
||||
id: bid.id,
|
||||
status: bid.status,
|
||||
name: bid.name,
|
||||
close_time: bid.close_time,
|
||||
current_price: bid.current_price,
|
||||
}),
|
||||
send_to: JSON.stringify(sendToData),
|
||||
});
|
||||
|
||||
this.eventEmitter.emit(NAME_EVENTS.BID_STATUS, {
|
||||
bid: {
|
||||
...bid,
|
||||
status: 'out-bid',
|
||||
},
|
||||
notification,
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue