feat: implement messaging functionality with real-time updates
- Introduced a messaging module on the backend using NestJS, including repository, service, controller, DTOs, and WebSocket Gateway. - Developed a frontend messaging page with conversation management, real-time message handling, and chat UI. - Implemented `MessageService` for API integrations and `SocketProvider` for real-time WebSocket updates. - Enhanced database schema to support conversations, participants, and messages with Drizzle ORM.
This commit is contained in:
60
backend/src/messages/messages.service.ts
Normal file
60
backend/src/messages/messages.service.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import {
|
||||
ForbiddenException,
|
||||
Injectable,
|
||||
NotFoundException,
|
||||
} from "@nestjs/common";
|
||||
import { EventsGateway } from "../realtime/events.gateway";
|
||||
import type { CreateMessageDto } from "./dto/create-message.dto";
|
||||
import { MessagesRepository } from "./repositories/messages.repository";
|
||||
|
||||
@Injectable()
|
||||
export class MessagesService {
|
||||
constructor(
|
||||
private readonly messagesRepository: MessagesRepository,
|
||||
private readonly eventsGateway: EventsGateway,
|
||||
) {}
|
||||
|
||||
async sendMessage(senderId: string, dto: CreateMessageDto) {
|
||||
let conversation = await this.messagesRepository.findConversationBetweenUsers(
|
||||
senderId,
|
||||
dto.recipientId,
|
||||
);
|
||||
|
||||
if (!conversation) {
|
||||
const newConv = await this.messagesRepository.createConversation();
|
||||
await this.messagesRepository.addParticipant(newConv.id, senderId);
|
||||
await this.messagesRepository.addParticipant(newConv.id, dto.recipientId);
|
||||
conversation = newConv;
|
||||
}
|
||||
|
||||
const message = await this.messagesRepository.createMessage({
|
||||
conversationId: conversation.id,
|
||||
senderId,
|
||||
text: dto.text,
|
||||
});
|
||||
|
||||
// Notify recipient via WebSocket
|
||||
this.eventsGateway.sendToUser(dto.recipientId, "new_message", {
|
||||
conversationId: conversation.id,
|
||||
message,
|
||||
});
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
async getConversations(userId: string) {
|
||||
return this.messagesRepository.findAllConversations(userId);
|
||||
}
|
||||
|
||||
async getMessages(userId: string, conversationId: string) {
|
||||
const isParticipant = await this.messagesRepository.isParticipant(
|
||||
conversationId,
|
||||
userId,
|
||||
);
|
||||
if (!isParticipant) {
|
||||
throw new ForbiddenException("You are not part of this conversation");
|
||||
}
|
||||
|
||||
return this.messagesRepository.findMessagesByConversationId(conversationId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user