from channels.generic.websocket import AsyncWebsocketConsumer import json from channels.exceptions import StopConsumer from django.utils import timezone from chat.models import ChatGroup, ChatMessage from channels.db import database_sync_to_async from rest_framework_simplejwt.authentication import JWTAuthentication class ChatConsumer(AsyncWebsocketConsumer): async def connect(self): print("self.scope: ", self.scope) self.room_name = ( self.scope.get("url_route", {}).get("kwargs", {}).get("room_name") ) print("self.room_name: ", self.room_name) token_key = self.scope["url_route"]["kwargs"]["token"] print("token_key: ", token_key) self.user = await self.get_user_async(token_key) print("self.user: ", self.user) # Join room group await self.channel_layer.group_add(self.room_name, self.channel_name) print("Time: ", timezone.now()) await self.accept() async def disconnect(self, close_code): # Leave room group print("Time: ", timezone.now()) await self.channel_layer.group_discard(self.room_name, self.channel_name) raise StopConsumer() # await self.disconnect(close_code) # Receive message from WebSocket async def receive(self, text_data): print("text_data: ", text_data) print("self.user: ", self.user) try: text_data_json = json.loads(text_data) message = text_data_json["message"] except json.JSONDecodeError: # Handle non-JSON message message = text_data print("message: ", message) group = await self.get_chat_group(self.room_name) print("group: ", group) await self.create_chat_message(group, message, self.user) # await self.create_chat_message(group, text_data_json, user) # Send message to room group await self.channel_layer.group_send( # self.room_name, {"type": "chat.message", "message": message} self.room_name, { "type": "chat.message", "message": message, "timestamp": str(timezone.now()), "user": self.user.email, "first_name": self.user.first_name, "profile_photo": self.user.profile_photo.url if self.user.profile_photo and self.user.profile_photo.url else None, }, ) @database_sync_to_async def create_chat_message(self, room_name, message, user): # principal = IAmPrincipal.objects.get(id=self.user) return ChatMessage.objects.create( group=room_name, timestamp=timezone.now(), message=message, user=self.user, ) @database_sync_to_async def get_chat_group(self, room_name): return ChatGroup.objects.filter(name=room_name).first() # Receive message from room group async def chat_message(self, event): print("event: ", event) message = event["message"] user = event["user"] first_name = event["first_name"] profile_photo = event["profile_photo"] timestamp = event["timestamp"] # new_message = str(user) + " :- " + message # Send message to WebSocket await self.send( text_data=json.dumps( { "message": message, "user": user, "first_name": first_name, "profile_photo": profile_photo, "timestamp": timestamp, } ) ) @database_sync_to_async def get_user_async(self, token): try: decoded_token = JWTAuthentication().get_validated_token(token) user = JWTAuthentication().get_user(decoded_token) self.user = user return user except Exception as e: self.user = None