diff --git a/chatApp/models/message.py b/chatApp/models/message.py index d08e237..1ec6ed7 100644 --- a/chatApp/models/message.py +++ b/chatApp/models/message.py @@ -1,10 +1,11 @@ -from collections.abc import Mapping from datetime import datetime -from typing import Any from pydantic import BaseModel, Field -from chatApp.config.database import get_messages_collection +from chatApp.config.database import ( + get_messages_collection, + get_private_rooms_collection, +) from chatApp.utils.object_id import PydanticObjectId from .public_room import fetch_public_room_by_id @@ -29,27 +30,51 @@ class MessageInDB(Message): # return result.inserted_id -async def get_public_messages( - room_id: str, -) -> tuple[bool, list[Mapping[str, Any]]]: +async def get_public_messages(room_id: str) -> list[MessageInDB]: """ Fetch public messages from a specific room. - - :param room_id: The ID of the public room to fetch messages from. - :return: A tuple where the first element is a boolean indicating success, - and the second element is a list of messages (each message represented as a dictionary). """ messages_collection = get_messages_collection() # Fetch the public room by ID room = await fetch_public_room_by_id(room_id) if room is None: - return False, [] + return [] + + room_id_obj = PydanticObjectId(room_id) + query = {"room_id": room_id_obj, "room_type": "public"} + + # Fetch the documents using the query + cursor = messages_collection.find(query) + + # Convert the cursor to a list and await the result + messages = await cursor.to_list(length=None) + + # Convert each document to MessageInDB + return [MessageInDB(**message) for message in messages] + + +async def get_private_messages( + room_id: str, +) -> list[MessageInDB]: + """ + Fetch private messages from a specific room between two users. + """ + # Fetch the private room by ID + room_collection = get_private_rooms_collection() + room_id_obj = PydanticObjectId(room_id) + room = await room_collection.find_one({"_id": room_id_obj}) + if room is None: + return [] + + messages_collection = get_messages_collection() + query = {"room_id": room_id_obj, "room_type": "private"} + + # Fetch the documents using the query + cursor = messages_collection.find(query) - # Fetch messages from the messages collection - cursor = messages_collection.find({"room_id": room_id}) - messages = await cursor.to_list( - length=None - ) # Await the cursor to list conversion + # Convert the cursor to a list and await the result + messages = await cursor.to_list(length=None) - return True, messages + # Convert each document to MessageInDB + return [MessageInDB(**message) for message in messages] diff --git a/chatApp/models/private_room.py b/chatApp/models/private_room.py index ea1cbb3..5208c05 100644 --- a/chatApp/models/private_room.py +++ b/chatApp/models/private_room.py @@ -1,8 +1,11 @@ +from collections.abc import Mapping from datetime import datetime +from typing import Any from pydantic import BaseModel, Field from chatApp.config.database import get_private_rooms_collection +from chatApp.models.message import MessageInDB, get_private_messages from chatApp.utils.object_id import PydanticObjectId @@ -16,14 +19,17 @@ class PrivateRoomInDB(PrivateRoom): id: PydanticObjectId = Field(alias="_id") -async def fetch_private_room_by_id(id: str): +async def fetch_private_room_by_id(id: str) -> PrivateRoomInDB | None: room_collection = get_private_rooms_collection() - return await room_collection.find_one({"_id": PydanticObjectId(id)}) + room = await room_collection.find_one({"_id": PydanticObjectId(id)}) + return PrivateRoomInDB(**room) if room else None -async def check_members_in_room(user1_id: str, user2_id: str): +async def fetch_private_room_by_members( + user1_id: str, user2_id: str +) -> PrivateRoomInDB | None: rooms_collection = get_private_rooms_collection() - room = await rooms_collection.find_one( + room: Mapping[str, Any] | None = await rooms_collection.find_one( { "$or": [ { @@ -37,21 +43,61 @@ async def check_members_in_room(user1_id: str, user2_id: str): ], } ) - return str(room["_id"]) if room is not None else None + return PrivateRoomInDB(**room) if room else None -async def join_private_room(user1_id: str, user2_id: str) -> str: +async def check_user_in_private_room(room_id: str, user_id: str) -> bool: + room: PrivateRoomInDB | None = await fetch_private_room_by_id(room_id) + user_id_obj = PydanticObjectId(user_id) + return user_id_obj in [room.member1, room.member2] if room else False + + +async def get_user_private_rooms(user_id: str) -> list[PrivateRoomInDB]: + rooms_collection = get_private_rooms_collection() + + # Create a query to find private rooms for the specified user + query = { + "$or": [ + {"member1": PydanticObjectId(user_id)}, + {"member2": PydanticObjectId(user_id)}, + ] + } + + # Fetch the documents using the query + cursor = rooms_collection.find(query) + + # Convert the cursor to a list and await the result + rooms = await cursor.to_list(length=None) + + # Convert each document to PrivateRoomInDB + return [PrivateRoomInDB(**room) for room in rooms] + + +async def get_private_room_messages(room_id: str) -> list[MessageInDB]: + return await get_private_messages(room_id) + + +async def create_private_room(user1_id: str, user2_id: str) -> PrivateRoomInDB: + if user1_id == user2_id: + raise ValueError("Users cannot be the same") + rooms_collection = get_private_rooms_collection() - room_id = await check_members_in_room(user1_id, user2_id) + room = await fetch_private_room_by_members(user1_id, user2_id) - if room_id is not None: - return room_id + if room is not None: + return room else: - room = await rooms_collection.insert_one( - { - "member1": PydanticObjectId(user1_id), - "member2": PydanticObjectId(user2_id), - } + user1_id_obj = PydanticObjectId(user1_id) + user2_id_obj = PydanticObjectId(user2_id) + new_room = PrivateRoom( + member1=user1_id_obj, + member2=user2_id_obj, + created_at=datetime.now(), + ) + new_room_obj = await rooms_collection.insert_one( + new_room.model_dump(by_alias=True) + ) + return PrivateRoomInDB( + **new_room.model_dump(by_alias=True), _id=new_room_obj.inserted_id ) - return str(room.inserted_id) diff --git a/chatApp/models/public_room.py b/chatApp/models/public_room.py index 66d8d15..59aea9d 100644 --- a/chatApp/models/public_room.py +++ b/chatApp/models/public_room.py @@ -1,8 +1,11 @@ from datetime import datetime +from typing import Any +from fastapi import status from pydantic import BaseModel, Field from chatApp.config.database import get_public_rooms_collection +from chatApp.schemas.public_room import GetPublicRoomSchema from chatApp.utils.object_id import PydanticObjectId @@ -44,25 +47,36 @@ class PublicRoomInDB(PublicRoom): id: PydanticObjectId = Field(alias="_id", serialization_alias="id") -async def fetch_public_room_by_id(id: str): +async def fetch_all_public_rooms() -> list[GetPublicRoomSchema]: + """Fetch all public rooms and return them as a list of GetPublicRoomSchema.""" + rooms_collection = get_public_rooms_collection() + rooms = await rooms_collection.find().to_list(length=None) + return [ + GetPublicRoomSchema(**room, members_count=len(room["members"])) + for room in rooms + ] + + +async def fetch_public_room_by_id(id: str) -> PublicRoomInDB | None: room_collection = get_public_rooms_collection() - return await room_collection.find_one({"_id": PydanticObjectId(id)}) + room = await room_collection.find_one({"_id": PydanticObjectId(id)}) + return PublicRoomInDB(**room) if room else None -async def join_public_room(room_id: str, user_id: str) -> bool: +async def join_public_room( + room_id: str, user_id: str +) -> tuple[bool, str | None, int]: rooms_collection = get_public_rooms_collection() - room = await rooms_collection.find_one({"_id": PydanticObjectId(room_id)}) + room: PublicRoomInDB | None = await fetch_public_room_by_id(room_id) # Ensure room is not None if room is None: - return False - - # Define the expected structure of the room dictionary - # Adjust this according to the actual structure - ban_list: list[PydanticObjectId] = room.get("ban_list", []) - members: list[PydanticObjectId] = room.get("members", []) + return False, "room not found", status.HTTP_404_NOT_FOUND + ban_list: list[PydanticObjectId] = room.ban_list + members: list[PydanticObjectId] = room.members userObjId = PydanticObjectId(user_id) + if userObjId not in ban_list: if userObjId not in members: members.append(userObjId) @@ -74,8 +88,51 @@ async def join_public_room(room_id: str, user_id: str) -> bool: ) if result.modified_count == 1: - return True + return True, None, status.HTTP_204_NO_CONTENT else: - return False # Failed to update the room in the database - return True # User is already a member - return False # User is banned + return ( + False, + "something went wrong, please try again", + status.HTTP_500_INTERNAL_SERVER_ERROR, + ) # Failed to update the room in the database + return ( + True, + None, + status.HTTP_204_NO_CONTENT, + ) # User is already a member + return ( + False, + "you are banned from this room", + status.HTTP_403_FORBIDDEN, + ) # User is banned + + +async def check_user_in_public_room(room_id: str, user_id: str) -> bool: + room: PublicRoomInDB | None = await fetch_public_room_by_id(room_id) + user_id_obj = PydanticObjectId(user_id) + if room is None: + return False + if user_id_obj not in room.ban_list or user_id_obj not in room.members: + return False + return True + + +async def create_public_room( + owner: str, room_info: dict[str, Any] +) -> PublicRoomInDB | None: + rooms_collection = get_public_rooms_collection() + + user_id_obj = PydanticObjectId(owner) + room = PublicRoom( + **room_info, + owner=user_id_obj, + created_at=datetime.now(), + members=[user_id_obj], + ) + + room_obj = await rooms_collection.insert_one( + room.model_dump(by_alias=True) + ) + return PublicRoomInDB( + **room.model_dump(by_alias=True), _id=room_obj.inserted_id + ) diff --git a/chatApp/routes/chat.py b/chatApp/routes/chat.py index f61c6ec..8fbcff0 100644 --- a/chatApp/routes/chat.py +++ b/chatApp/routes/chat.py @@ -1,105 +1,71 @@ from collections.abc import Mapping -from datetime import datetime from typing import Any from fastapi import APIRouter, Depends, HTTPException, Path -from motor.motor_asyncio import AsyncIOMotorCollection, AsyncIOMotorCursor from chatApp.config import auth -from chatApp.config.database import ( - get_messages_collection, - get_private_rooms_collection, - get_public_rooms_collection, -) -from chatApp.models.message import MessageInDB -from chatApp.models.private_room import PrivateRoom, PrivateRoomInDB -from chatApp.models.public_room import PublicRoom, PublicRoomInDB -from chatApp.models.user import UserInDB -from chatApp.schemas.private_room import CreatePrivateRoom -from chatApp.schemas.public_room import CreatePublicRoom, GetPulbicRoomsSchema -from chatApp.utils.object_id import PydanticObjectId, is_valid_object_id +from chatApp.models import message, private_room, public_room, user +from chatApp.schemas.public_room import CreatePublicRoom, GetPublicRoomSchema +from chatApp.utils.object_id import is_valid_object_id router = APIRouter() -@router.post("/create-public-room", response_model=PublicRoomInDB) +@router.post("/create-public-room", response_model=public_room.PublicRoomInDB) async def create_public_room( room_info: CreatePublicRoom, - user: UserInDB = Depends(auth.get_current_user), + user: user.UserInDB = Depends(auth.get_current_user), ): - rooms_collection: AsyncIOMotorCollection = get_public_rooms_collection() - - # Convert room_info to dictionary and add the owner - room_dict: dict[str, Any] = room_info.model_dump() - room_dict["owner"] = user.id - room_dict["members"] = [user.id] - - room = PublicRoom(**room_dict) - - # Insert the room into the database - result = await rooms_collection.insert_one(room.model_dump(by_alias=True)) - - return PublicRoomInDB( - **room.model_dump(by_alias=True), _id=result.inserted_id + return await public_room.create_public_room( + owner=str(user.id), room_info=room_info.model_dump(by_alias=True) ) -@router.get("/join-public-room/{room_id}") +@router.get( + "/join-public-room/{room_id}", response_model=public_room.PublicRoomInDB +) async def join_public_room( room_id: str = Path(..., description="ID of the public room to join"), - user: UserInDB = Depends(auth.get_current_user), + user: user.UserInDB = Depends(auth.get_current_user), ): - rooms_collection: AsyncIOMotorCollection = get_public_rooms_collection() - if not is_valid_object_id(room_id): raise HTTPException(status_code=400, detail="Invalid room ID format") # Check if the room exists - room = await rooms_collection.find_one({"_id": PydanticObjectId(room_id)}) + room = await public_room.fetch_public_room_by_id(room_id) if room is None: raise HTTPException(status_code=404, detail="Room not found") - if user.id not in room["ban_list"]: - if user.id not in room["members"]: - room["members"].append(user.id) - - # Update the room in the database - await rooms_collection.update_one( - {"_id": room["_id"]}, {"$set": room} - ) + result, report, code = await public_room.join_public_room( + room_id, str(user.id) + ) + if result: + return room else: - raise HTTPException( - status_code=403, detail="You are banned from this room" - ) - - return PublicRoomInDB(**room) + raise HTTPException(detail=report, status_code=code) -@router.get("/get-public-rooms/", response_model=Mapping[str, Any]) +@router.get("/get-public-rooms", response_model=Mapping[str, Any]) async def get_public_rooms( page: int = 1, per_page: int = 10, ): - rooms_collection: AsyncIOMotorCollection = get_public_rooms_collection() - total_count = await rooms_collection.count_documents({}) - rooms = ( - await rooms_collection.find( - {}, - { - "_id": 1, - "name": 1, - "description": 1, - "owner": 1, - "created_at": 1, - }, - ) - .skip((page - 1) * per_page) - .limit(per_page) - .to_list(None) - ) + all_rooms: list[ + GetPublicRoomSchema + ] = await public_room.fetch_all_public_rooms() + total_count = len(all_rooms) + + # Calculate pagination indexes + start_index = (page - 1) * per_page + end_index = start_index + per_page + + if start_index >= total_count: + raise HTTPException(status_code=404, detail="Page out of range") + + paginated_rooms = all_rooms[start_index:end_index] data_to_return = { - "data": [GetPulbicRoomsSchema(**room) for room in rooms], + "data": paginated_rooms, "meta": { "total_count": total_count, "page": page, @@ -110,153 +76,94 @@ async def get_public_rooms( @router.post( - "/create-private-room/{person_id}", response_model=PrivateRoomInDB + "/create-private-room/{person_id}", + response_model=private_room.PrivateRoomInDB, ) async def create_private_room( person_id: str = Path(..., description="other person's id"), - user: UserInDB = Depends(auth.get_current_user), + user: user.UserInDB = Depends(auth.get_current_user), ): - rooms_collection: AsyncIOMotorCollection = get_private_rooms_collection() - if not is_valid_object_id(person_id): raise HTTPException(status_code=400, detail="Invalid person ID format") - # Create a PrivateRoomInDB instance with current time - room_schema = CreatePrivateRoom( - member1=user.id, member2=PydanticObjectId(person_id) - ) - room_dict = room_schema.model_dump() - room_dict["created_at"] = datetime.now() - - # Ensure member1 and member2 are not the same - if room_dict["member1"] == room_dict["member2"]: - raise HTTPException( - status_code=400, detail="Members must be different" - ) - - recently_created = await rooms_collection.find_one( - { - "$or": [ - { - "member1": room_dict["member1"], - "member2": room_dict["member2"], - }, - { - "member1": room_dict["member2"], - "member2": room_dict["member1"], - }, - ] - } - ) - if recently_created is not None: - raise HTTPException( - status_code=400, - detail="A private room already exists between you and this user", - ) - # Create the PrivateRoom instance - room = PrivateRoom(**room_dict) + return await private_room.create_private_room(str(user.id), person_id) - # Insert the room into the database - result = await rooms_collection.insert_one(room.model_dump(by_alias=True)) - return PrivateRoomInDB( - **room.model_dump(by_alias=True), _id=result.inserted_id - ) +@router.get( + "/get-private-rooms", response_model=list[private_room.PrivateRoomInDB] +) +async def get_private_rooms( + user: user.UserInDB = Depends(auth.get_current_user), +): + return await private_room.get_user_private_rooms(str(user.id)) -@router.get("/private-room/{room_id}", response_model=PrivateRoomInDB) +@router.get( + "/get-private-room/{room_id}", response_model=private_room.PrivateRoomInDB +) async def get_private_room( room_id: str = Path(..., description="ID of the private room to retrieve"), - user: UserInDB = Depends(auth.get_current_user), + user: user.UserInDB = Depends(auth.get_current_user), ): - rooms_collection: AsyncIOMotorCollection = get_private_rooms_collection() - if not is_valid_object_id(room_id): raise HTTPException(status_code=400, detail="Invalid room ID format") - # Fetch the room from the database - room_data = await rooms_collection.find_one( - {"_id": PydanticObjectId(room_id)} - ) - - if room_data is None: + room = await private_room.fetch_private_room_by_id(room_id) + if room is None: raise HTTPException(status_code=404, detail="Private room not found") - if user.id not in [room_data.get("member1"), room_data.get("member2")]: + if not await private_room.check_user_in_private_room( + str(room.id), str(user.id) + ): raise HTTPException( status_code=403, detail="You are not a member of this room" ) - return PrivateRoomInDB(**room_data) + return room -@router.get("/messages/public/{room_id}", response_model=list[MessageInDB]) +@router.get( + "/get-messages/public/{room_id}", response_model=list[message.MessageInDB] +) async def get_messages_of_public_room( room_id: str = Path(..., description="id of the public room"), - user: UserInDB = Depends(auth.get_current_user), + user: user.UserInDB = Depends(auth.get_current_user), ): - messages_collection: AsyncIOMotorCollection = get_messages_collection() - public_room_collection: AsyncIOMotorCollection = ( - get_public_rooms_collection() - ) - if not is_valid_object_id(room_id): raise HTTPException(status_code=400, detail="Invalid room id") - room = await public_room_collection.find_one( - {"_id": PydanticObjectId(room_id)} - ) + room = await public_room.fetch_public_room_by_id(room_id) if room is None: raise HTTPException(status_code=404, detail="Public room not found") - if user.id not in room["members"]: + if not await public_room.check_user_in_public_room(room_id, str(user.id)): raise HTTPException( status_code=403, detail="User not a member of the room" ) - cursor: AsyncIOMotorCursor = messages_collection.find( - {"room_id": PydanticObjectId(room_id)} - ) - messages_dicts: list[Mapping[str, Any]] = await cursor.to_list(length=None) - messages: list[MessageInDB] = [ - MessageInDB(**message_dict) for message_dict in messages_dicts - ] - - return messages + return await message.get_public_messages(room_id) -@router.get("/messages/private/{room_id}", response_model=MessageInDB) -async def get_message_of_private_room( +@router.get( + "/get-messages/private/{room_id}", response_model=list[message.MessageInDB] +) +async def get_messages_of_private_room( room_id: str = Path(..., description="id of the private room"), - user: UserInDB = Depends(auth.get_current_user), + user: user.UserInDB = Depends(auth.get_current_user), ): - messages_collection: AsyncIOMotorCollection = get_messages_collection() - private_rooms_collection: AsyncIOMotorCollection = ( - get_private_rooms_collection() - ) - if not is_valid_object_id(room_id): raise HTTPException(status_code=400, detail="Invalid room id") - room = await private_rooms_collection.find_one( - {"_id": PydanticObjectId(room_id)} - ) + room = await private_room.fetch_private_room_by_id(room_id) if room is None: raise HTTPException(status_code=404, detail="Private room not found") - if user.id not in [room["member1"], room["member2"]]: + if not await public_room.check_user_in_public_room( + str(room.id), str(user.id) + ): raise HTTPException( status_code=403, detail="User not a member of the room" ) - # Get the last message from the room - cursor: AsyncIOMotorCursor = messages_collection.find( - {"room_id": PydanticObjectId(room_id)} - ) - messages_dicts: list[Mapping[str, Any]] = await cursor.to_list(length=None) - messages: list[MessageInDB] = [ - MessageInDB(**message_dict) for message_dict in messages_dicts - ] - - return messages + return await message.get_private_messages(room_id) diff --git a/chatApp/schemas/public_room.py b/chatApp/schemas/public_room.py index 70086b0..820b736 100644 --- a/chatApp/schemas/public_room.py +++ b/chatApp/schemas/public_room.py @@ -26,7 +26,7 @@ class CreatePublicRoom(BaseModel): ) -class GetPulbicRoomsSchema(BaseModel): +class GetPublicRoomSchema(BaseModel): id: PydanticObjectId = Field( ..., description="id of the room", @@ -37,3 +37,4 @@ class GetPulbicRoomsSchema(BaseModel): name: str description: str | None = None created_at: datetime + members_count: int = Field(..., description="number of members") diff --git a/chatApp/sockets.py b/chatApp/sockets.py index 4768e9f..3747b77 100644 --- a/chatApp/sockets.py +++ b/chatApp/sockets.py @@ -5,15 +5,7 @@ from chatApp.config.config import get_settings from chatApp.config.database import get_messages_collection from chatApp.config.logs import get_logger -from chatApp.models.message import Message -from chatApp.models.private_room import ( - check_members_in_room, - join_private_room, -) -from chatApp.models.public_room import ( - fetch_public_room_by_id, - join_public_room, -) +from chatApp.models import message, private_room, public_room from chatApp.models.user import fetch_user_by_id from chatApp.utils.object_id import PydanticObjectId @@ -72,7 +64,9 @@ async def joining_public_room(sid: str, data: dict[str, Any]) -> None: ) return - room_joined: bool = await join_public_room(room_id, user_id) + room_joined, report, _ = await public_room.join_public_room( + room_id, user_id + ) if room_joined: await sio_server.enter_room(sid, room_id) @@ -91,17 +85,19 @@ async def joining_public_room(sid: str, data: dict[str, Any]) -> None: @sio_server.event async def joining_private_room(sid: str, data: dict[str, Any]) -> None: """Handle user joining a private room.""" - user1 = data.get("user1") - user2 = data.get("user2") + # user1 = data.get("user1") + # user2 = data.get("user2") - if not isinstance(user1, str) or not isinstance(user2, str): - await sio_server.emit("error", data="Invalid user1 or user2", room=sid) - return + ... - room_id = await join_private_room(user1, user2) - await sio_server.enter_room(sid, room_id) - print(f"User {user1} joined private room {room_id} with {user2}") - await sio_server.emit("user_joined", data=user1, room=room_id) + # if not isinstance(user1, str) or not isinstance(user2, str): + # await sio_server.emit("error", data="Invalid user1 or user2", room=sid) + # return + + # room_id = await private_room.join_private_room(user1, user2) + # await sio_server.enter_room(sid, room_id) + # print(f"User {user1} joined private room {room_id} with {user2}") + # await sio_server.emit("user_joined", data=user1, room=room_id) @sio_server.event @@ -131,12 +127,12 @@ async def leave_room(sid: str, data: dict[str, Any]) -> None: async def send_public_message(sid: str, data: dict[str, Any]) -> None: """Handle sending a message to a public group.""" room_id = data.get("room_id") - message = data.get("message") + message_sent = data.get("message") user_id = data.get("user_id") if ( not isinstance(room_id, str) - or not isinstance(message, str) + or not isinstance(message_sent, str) or not isinstance(user_id, str) ): await sio_server.emit( @@ -144,9 +140,11 @@ async def send_public_message(sid: str, data: dict[str, Any]) -> None: ) return - print(f"Sending message to room {room_id}: {message} from user {user_id}") + print( + f"Sending message to room {room_id}: {message_sent} from user {user_id}" + ) - room = await fetch_public_room_by_id(room_id) + room = await public_room.fetch_public_room_by_id(room_id) if not room: await sio_server.emit( @@ -157,11 +155,11 @@ async def send_public_message(sid: str, data: dict[str, Any]) -> None: messages_collection = get_messages_collection() user = await fetch_user_by_id(user_id) - if user and user["_id"] in room["members"]: - new_message = Message( + if user and user["_id"] in room.members: + new_message = message.Message( user_id=PydanticObjectId(user_id), room_id=PydanticObjectId(room_id), - content=message, + content=message_sent, room_type="public", ) await messages_collection.insert_one(new_message.model_dump()) @@ -181,13 +179,13 @@ async def send_private_message(sid: str, data: dict[str, Any]) -> None: room_id = data.get("room_id") user1_id = data.get("user1") user2_id = data.get("user2") - message = data.get("message") + message_sent = data.get("message") if ( not isinstance(room_id, str) or not isinstance(user1_id, str) or not isinstance(user2_id, str) - or not isinstance(message, str) + or not isinstance(message_sent, str) ): await sio_server.emit( "error", @@ -204,8 +202,10 @@ async def send_private_message(sid: str, data: dict[str, Any]) -> None: ) return - room_id = await check_members_in_room(user1_id, user2_id) - if not room_id: + room: ( + private_room.PrivateRoomInDB | None + ) = await private_room.fetch_private_room_by_members(user1_id, user2_id) + if not room: await sio_server.emit( "error", data={"error": "Room not found"}, room=sid ) @@ -213,10 +213,10 @@ async def send_private_message(sid: str, data: dict[str, Any]) -> None: messages_collection = get_messages_collection() - new_message = Message( + new_message = message.Message( user_id=PydanticObjectId(user1_id), room_id=PydanticObjectId(room_id), - content=message, + content=message_sent, room_type="private", ) await messages_collection.insert_one(new_message.model_dump())