from channels.generic.websocket import WebsocketConsumer from .models import * import json from django.template.loader import render_to_string from asgiref.sync import async_to_sync from django.shortcuts import get_object_or_404 import requests from django.forms.models import model_to_dict from django.core.serializers.json import DjangoJSONEncoder class OsitcomVisitor(WebsocketConsumer): def connect(self): async_to_sync(self.channel_layer.group_add)( 'ositcom_visitors', self.channel_name ) self.accept() self.visitor = None def disconnect(self, close_code): if self.visitor: self.visitor.left_date = datetime.now() self.visitor.save() async_to_sync(self.channel_layer.group_discard)( 'ositcom_visitors', self.channel_name ) def receive(self, text_data): text_data_json = json.loads(text_data) event_type = text_data_json.get('event_type') if event_type == 'new_visitor': self.visitor = Visitor.objects.create( session_id = text_data_json.get('session_id'), ip_address = text_data_json.get('client_ip'), referrer = text_data_json.get('referrer'), country = text_data_json.get('client_country'), url = text_data_json.get('url'), visit_date = datetime.now() ) class OsitcomChatRoom(WebsocketConsumer): def connect(self): self.session_id = self.scope['url_route']['kwargs']['session_id'] async_to_sync(self.channel_layer.group_add)( self.session_id, self.channel_name ) self.accept() chat_room_guest = ChatRoomGuest.objects.filter(session_id=self.session_id).last() if chat_room_guest: chat_room = chat_room_guest.room self.chat_room = chat_room else: self.chat_room = None def disconnect(self, close_code): async_to_sync(self.channel_layer.group_discard)( self.session_id, self.channel_name ) def receive(self, text_data): text_data_json = json.loads(text_data) event_type = text_data_json.get('event_type') if event_type == 'load_chat': self.client_type = text_data_json.get('client_type') self.load_chat_handler() if event_type == 'start_conversation': chat_room = ChatRoom.objects.create( name=f"Support: {self.session_id}", date_created = datetime.now() ) chat_room_guest = ChatRoomGuest.objects.create( room=chat_room, name= text_data_json.get('guest_name'), mobile_number= text_data_json.get('guest_mobile_number'), session_id=self.session_id ) self.chat_room = chat_room event = { 'type': 'start_conversation_handler', 'chat_room_id': chat_room.id } async_to_sync(self.channel_layer.group_send)( self.session_id, event ) if event_type == 'send_message': if text_data_json.get('user_id'): member = get_object_or_404(User, id=text_data_json.get('user_id')) else: member = None chat_message = ChatMessage.objects.create( member = member, room = self.chat_room, content= text_data_json.get('message'), date_sent = datetime.now() ) event = { 'type': 'send_message_handler', 'chat_message_id': chat_message.id } async_to_sync(self.channel_layer.group_send)( self.session_id, event ) if event_type == 'uploaded_file': if text_data_json.get('user_id'): member = get_object_or_404(User, id=text_data_json.get('user_id')) else: member = None message = ChatMessage.objects.create( member = member, room = self.chat_room, date_sent = datetime.now() ) message_attachment = ChatMessageAttachment.objects.create( message = message, attachment = text_data_json.get('path'), ) event = { 'type': 'uploaded_file_handler', 'message_attachment_id': message_attachment.id, 'file_type': text_data_json.get('file_type'), 'file_name': text_data_json.get('file_name'), } async_to_sync(self.channel_layer.group_send)( self.session_id, event ) if event_type == 'update_read_messages' and self.chat_room: latest_unread_message = None number_of_unread = 0 if text_data_json.get('user_id'): member = get_object_or_404(User, id=text_data_json.get('user_id')) guest = None if text_data_json.get('chat_state') == 'open': messages = ChatMessage.objects.filter(room=self.chat_room).exclude(member=member) for message in messages: seen_message = ChatMessageSeen.objects.filter( message=message, member=member ).exists() if not seen_message: ChatMessageSeen.objects.create( message=message, member=member, seen_date = datetime.now() ) number_of_unread = 0 else: number_of_unread = ChatMessage.objects.filter(room=self.chat_room).exclude(member = member, chatmessageseen__member=member).count() latest_unread_message = ChatMessage.objects.filter(room=self.chat_room).exclude(chatmessageseen__member=member).last() else: member = None guest = self.chat_room.chatroomguest if text_data_json.get('chat_state') == 'open': messages = ChatMessage.objects.filter(room=self.chat_room).exclude(member=None) for message in messages: seen_message = ChatMessageSeen.objects.filter( message=message, guest=guest ).exists() if not seen_message: ChatMessageSeen.objects.create( message=message, guest=guest, seen_date = datetime.now() ) number_of_unread = 0 else: number_of_unread = ChatMessage.objects.filter(room=self.chat_room, member__isnull=False).exclude(chatmessageseen__guest=guest).count() latest_unread_message = ChatMessage.objects.filter(room=self.chat_room).exclude(chatmessageseen__guest=guest).last() event = { 'type': 'update_read_messages_handler', 'number_of_unread': number_of_unread, 'latest_unread_message_id': latest_unread_message.id if latest_unread_message else None } self.update_read_messages_handler(event) def load_chat_handler(self): if self.chat_room: chat_room = self.chat_room chat_room_messages = ChatMessage.objects.filter(room=chat_room).order_by('date_sent') else: chat_room = None chat_room_messages = None context = { 'chat_room': chat_room, 'chat_room_messages': chat_room_messages, } if self.client_type == 'mobile_admin': chat_room_data = model_to_dict(chat_room) chat_room_messages_data = [model_to_dict(message) for message in chat_room_messages] self.send(text_data=json.dumps({ 'event_type': 'load_chat', 'chat_room_data': chat_room_data, 'chat_room_messages_data': chat_room_messages_data },cls=DjangoJSONEncoder)) elif self.client_type == 'website_admin': html = render_to_string("chat_templates/chat-widget.html", context=context) self.send(text_data=json.dumps({ 'event_type': 'load_chat', 'html': html, })) else: html = render_to_string("chat-widget.html", context=context) self.send(text_data=json.dumps({ 'event_type': 'load_chat', 'html': html, })) def start_conversation_handler(self, event): chat_room = get_object_or_404(ChatRoom, id=event['chat_room_id']) context = { 'chat_room': chat_room, 'session_id':self.session_id } if self.client_type == 'mobile_admin': self.send(text_data=json.dumps({ 'event_type': 'start_conversation', 'context': context, })) else: html = render_to_string("chat-room.html", context=context) self.send(text_data=json.dumps({ 'event_type': 'start_conversation', 'html': html, })) def send_message_handler(self, event): chat_message = get_object_or_404(ChatMessage, id=event['chat_message_id']) context = { 'chat_message': chat_message, } if self.client_type == 'mobile_admin': chat_message_data = model_to_dict(chat_message) self.send(text_data=json.dumps({ 'event_type': 'send_message', 'chat_message_data': chat_message_data, },cls=DjangoJSONEncoder)) elif self.client_type == 'website_admin': html = render_to_string("chat_templates/message.html", context=context) self.send(text_data=json.dumps({ 'event_type': 'send_message', 'html': html, })) else: html = render_to_string("partials/message.html", context=context) self.send(text_data=json.dumps({ 'event_type': 'send_message', 'user': chat_message.member.id if chat_message.member else None, 'html': html, })) def uploaded_file_handler(self, event): message_attachment = get_object_or_404(ChatMessageAttachment, id=event['message_attachment_id']) context = { 'message_attachment': message_attachment, 'file_type': event['file_type'] } html = render_to_string("partials/message-attachment.html", context=context) self.send(text_data=json.dumps({ 'event_type': 'uploaded_file', 'file_name': event['file_name'], 'html': html, })) def update_read_messages_handler(self, event): latest_unread_message_id = event.get('latest_unread_message_id') if latest_unread_message_id: latest_unread_message = get_object_or_404(ChatMessage, id=latest_unread_message_id) context = { 'number_of_unread' : event['number_of_unread'], 'latest_unread_message': latest_unread_message } html = render_to_string("partials/unread-messages.html", context=context) self.send(text_data=json.dumps({ 'event_type': 'update_read_messages', 'html': html, })) else: latest_unread_message = None