update detech new message and auto sync conversations
This commit is contained in:
parent
83785fdf0a
commit
cf29ee8348
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -8,7 +8,7 @@
|
|||
"name": "re-make-bid-extension",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"axios": "^1.10.0",
|
||||
"axios": "^1.11.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"next-themes": "^0.4.6",
|
||||
|
|
@ -1862,13 +1862,13 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz",
|
||||
"integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==",
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz",
|
||||
"integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"form-data": "^4.0.4",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
|
|
@ -2693,9 +2693,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
|
||||
"integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
|
||||
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
"dev:build": "vite build --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.10.0",
|
||||
"axios": "^1.11.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"next-themes": "^0.4.6",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import axios from "@/lib/axios";
|
||||
|
||||
class ConversationApiService {
|
||||
async index(query: Record<string, any>) {
|
||||
try {
|
||||
const { data } = await axios({
|
||||
url: "conversations",
|
||||
params: query,
|
||||
});
|
||||
|
||||
console.log("[NestJS] Response (conversation-index):", data);
|
||||
return data;
|
||||
} catch (err) {
|
||||
console.error("[NestJS] Error (conversation-index):", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async getConversationByPrefix() {
|
||||
try {
|
||||
const { data } = await axios({
|
||||
url: "conversations/prefix",
|
||||
method: "POST",
|
||||
});
|
||||
|
||||
console.log("[NestJS] Response (conversation-prefix):", data);
|
||||
return data;
|
||||
} catch (err) {
|
||||
console.error("[NestJS] Error (conversation-prefix):", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const conversationApi = new ConversationApiService();
|
||||
|
|
@ -22,6 +22,18 @@ class MessageApiService {
|
|||
throw err;
|
||||
}
|
||||
}
|
||||
async createAndSendToZulip(messages: IMessage[]) {
|
||||
try {
|
||||
const { data } = await axios.post("/messages/create-and-send", {
|
||||
data: messages,
|
||||
});
|
||||
console.log("[NestJS] Response (create and send):", data);
|
||||
return data;
|
||||
} catch (err) {
|
||||
console.error("[NestJS] Error (create and send):", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const messageApi = new MessageApiService();
|
||||
|
|
|
|||
|
|
@ -39,12 +39,8 @@ port.onMessage.addListener((msg: IMsg<any>) => {
|
|||
}
|
||||
});
|
||||
|
||||
// DETECH NEW MESSAGE (INTERVAl)
|
||||
contentService.detectNewMessage();
|
||||
|
||||
// SYNC CONVERSASIONS (INTERVAL)
|
||||
contentService.startSyncConversations();
|
||||
|
||||
// const a = new TeamsChatService();
|
||||
|
||||
// a.start();
|
||||
// AUTO SYNC MESAGE PREFIX (INTERNAL)
|
||||
contentService.autoSyncConversationPrefixMessages();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { EVENTS } from "@/lib/event";
|
|||
import { typeingService } from "./typing.service";
|
||||
import { delay } from "@/features/app";
|
||||
import { messageApi } from "@/api/message-api.service";
|
||||
import { conversationApi } from "@/api/conversation-api.service";
|
||||
|
||||
export class ContentService {
|
||||
service: TeamsChatService;
|
||||
|
|
@ -532,6 +533,61 @@ export class ContentService {
|
|||
}
|
||||
|
||||
startSyncConversations() {
|
||||
setInterval(() => this.getConversations(), 20000);
|
||||
// Tạo namespace nếu chưa tồn tại
|
||||
(window as any)._chatIntervals = (window as any)?._chatIntervals || {};
|
||||
|
||||
// Kiểm tra xem interval đã tồn tại chưa
|
||||
if (!(window as any)._chatIntervals.syncConversations) {
|
||||
(window as any)._chatIntervals.syncConversations = window.setInterval(
|
||||
() => {
|
||||
this.getConversations();
|
||||
},
|
||||
20000
|
||||
);
|
||||
console.log("✅ startSyncConversations running");
|
||||
} else {
|
||||
console.log("ℹ️ startSyncConversations already running");
|
||||
}
|
||||
}
|
||||
|
||||
// Interval chạy, chỉ add task vào queue
|
||||
autoSyncConversationPrefixMessages() {
|
||||
(window as any)._chatIntervals = (window as any)?._chatIntervals || {};
|
||||
|
||||
if (!(window as any)._chatIntervals.syncPrefixMessages) {
|
||||
(window as any)._chatIntervals.syncPrefixMessages = (
|
||||
window as any
|
||||
).setInterval(() => {
|
||||
queue.add(async () => {
|
||||
try {
|
||||
const { data } =
|
||||
(await conversationApi.getConversationByPrefix()) as {
|
||||
data: ChatItem[];
|
||||
};
|
||||
|
||||
if (!data) return;
|
||||
|
||||
for (const chat of data) {
|
||||
this._clickToConversation(chat.id as string);
|
||||
await delay(1000);
|
||||
|
||||
const currentRoom = this.service.getCurrentRoomInfo();
|
||||
|
||||
if (!currentRoom || currentRoom.room_id !== chat.id) return;
|
||||
|
||||
const messages = this.service.extractAllMessages();
|
||||
|
||||
await messageApi.createAndSendToZulip(messages);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("❌ autoSyncConversationPrefixMessages error:", err);
|
||||
}
|
||||
});
|
||||
}, 10000);
|
||||
|
||||
console.log("✅ autoSyncConversationPrefixMessages running with PQueue");
|
||||
} else {
|
||||
console.log("ℹ️ autoSyncConversationPrefixMessages already running");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Controller, Get, Param } from '@nestjs/common';
|
||||
import { Controller, Get, Param, Post, Query } from '@nestjs/common';
|
||||
import { Paginate, PaginateQuery } from 'nestjs-paginate';
|
||||
import { ConversationsService } from './conversations.service';
|
||||
import { Conversation } from '@/entities/conversation.entity';
|
||||
|
|
@ -8,8 +8,16 @@ export class ConversationsController {
|
|||
constructor(private readonly service: ConversationsService) {}
|
||||
|
||||
@Get('')
|
||||
getConversations(@Paginate() query: PaginateQuery) {
|
||||
return this.service.index(query);
|
||||
getConversations(
|
||||
@Paginate() query: PaginateQuery,
|
||||
@Query('current') current: boolean = true,
|
||||
) {
|
||||
return this.service.index({ ...query, current });
|
||||
}
|
||||
|
||||
@Post('prefix')
|
||||
getConversationsByPrefix() {
|
||||
return this.service.getConversationsByPrefix();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
|
|
|
|||
|
|
@ -4,11 +4,10 @@ import { SystemLang } from '@/system/lang/system.lang';
|
|||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { paginate, PaginateQuery } from 'nestjs-paginate';
|
||||
import { Repository } from 'typeorm';
|
||||
import { ILike, Repository } from 'typeorm';
|
||||
import { CreateMessageDto } from '../messages/dtos/create-message.dto';
|
||||
import { MessagesEventService } from '../messages/messages-event.service';
|
||||
import { MessagesService } from '../messages/messages.service';
|
||||
import { delay } from '@/features/delay';
|
||||
|
||||
@Injectable()
|
||||
export class ConversationsService {
|
||||
|
|
@ -19,7 +18,8 @@ export class ConversationsService {
|
|||
private messageService: MessagesService,
|
||||
) {}
|
||||
|
||||
async index(query: PaginateQuery) {
|
||||
async index(query: PaginateQuery & { current: boolean }) {
|
||||
if (query.current) {
|
||||
await this.event.sendEvent(
|
||||
MessagesEventService.EVENTS.GET_CONVERSATIONS,
|
||||
{},
|
||||
|
|
@ -32,13 +32,15 @@ export class ConversationsService {
|
|||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
const result = await paginate(query, this.repo, {
|
||||
sortableColumns: ['created_at'],
|
||||
sortableColumns: ['created_at', 'name'],
|
||||
searchableColumns: ['name'],
|
||||
defaultLimit: 10,
|
||||
filterableColumns: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
maxLimit: 100,
|
||||
defaultSortBy: [['created_at', 'DESC']],
|
||||
|
|
@ -94,4 +96,16 @@ export class ConversationsService {
|
|||
|
||||
return AppResponse.toResponse(result);
|
||||
}
|
||||
|
||||
async getConversationsByPrefix() {
|
||||
const prefix = (process.env.GROUP_PREFIX || '').trim();
|
||||
|
||||
const conversations = await this.repo.find({
|
||||
where: {
|
||||
name: ILike(`%${prefix}%`),
|
||||
},
|
||||
});
|
||||
|
||||
return AppResponse.toResponse(conversations || []);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@ export class MessagesController {
|
|||
return this.service.sendMessage(data);
|
||||
}
|
||||
|
||||
@Post('create-and-send')
|
||||
createAndSendToZulip(@Body() data: CreateBulkMessageDto) {
|
||||
return this.service.createAndSendToZulip(data);
|
||||
}
|
||||
|
||||
@Post('')
|
||||
save(@Body() data: CreateMessageDto) {
|
||||
return this.service.create(data);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import { ReplyMessageDto } from './dtos/reply-message.dto';
|
|||
import { SendMessageDto } from './dtos/send-message.dto';
|
||||
import { MessagesEventService } from './messages-event.service';
|
||||
import { ZulipService } from './zulip.service';
|
||||
import { CreateBulkMessageDto } from './dtos/create-bulk-message.dto';
|
||||
@Injectable()
|
||||
export class MessagesService {
|
||||
constructor(
|
||||
|
|
@ -194,4 +195,18 @@ export class MessagesService {
|
|||
data,
|
||||
});
|
||||
}
|
||||
|
||||
async createAndSendToZulip({ data }: CreateBulkMessageDto) {
|
||||
const results = [];
|
||||
|
||||
for (const mes of data) {
|
||||
const result = await this.create(mes);
|
||||
|
||||
if (result) {
|
||||
results.push(result);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue