diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index c1f25419..ccf96c77 100644 Binary files a/osinaweb/db.sqlite3 and b/osinaweb/db.sqlite3 differ diff --git a/osinaweb/firebase_credentials.json b/osinaweb/firebase_credentials.json new file mode 100644 index 00000000..3c0ec108 --- /dev/null +++ b/osinaweb/firebase_credentials.json @@ -0,0 +1,13 @@ +{ + "type": "service_account", + "project_id": "yasour-13931", + "private_key_id": "60f5e3a2345e6d2252f0b87eec606a8cdffe4588", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCm9jffoWF8+745\nwvLH7IkxAbko2E9s8Jl72UqXlT8iv22w0mU18jjCWVz/Z35BhSrLk4oAodpV9q2a\nMHMYtT5ZCgNeV9Do98dO5xhizvRv+sqQKuYXRVyHBa39jYHoCFCuNQ8L71masVmb\nJugvmxiv4WZHjxwzLBoz/usj7VpBUxISRaG+g4W3UX+b0w6LKlNa7EJRJtOKIS4p\nUsmius9NcXuMqiKEWESY3muB1EQpWc2kmg6Xw8xSgdFFEIj3ctUVCEDs047F8ypW\nZN06XBshX56owEaGqNaSIFo3h0PFy4QckeYCueyt4H/4nyZ85YLZG4yj9kWCnsMW\nSsGQsr5tAgMBAAECggEABw+xR8I/yQUto6xAz99LYxj3T4isfUdEuoXzX2tWvv25\nIioX0TsEFwYoBn5GSveamn8MLmAqB4o2B+gmKgSaVTI098O/iGbYVVg1QhKOKIFD\nGWtTDWdn1ScSl39pX9qgLOn+D6tpDv+SslroJYFJ/0BJbtvY3bovBoVwxPV4JHyR\nKHFB8OI7V7B5SGincMzFNP6NoSekOYAOpAZRk0ZPv70CyKuyRb0COK0cZyJ8cF1K\nZFeEEiy99yShmtgqpEGfZsL8TaqfTauqevdPU2GnBxv325dy4DLAPQebHfrAn1pS\nfONqKdZDuYykBmcs50oAVS/ACZabvonKTLYA8iV+iQKBgQDcUCflPal151u5+Eie\nMgGo+pNP9vVo4NGOIqD4jBqQJKBRnZj2F0deKmV6HPSTnQuQDtftiq1XlvX7nZYC\nZ24wjm7PcLQpGXyOZDWn9dikFEaS8WSz7fDZLwmU0kB2Hdluv/hrJEqrbFepAMLq\n0gzz0GFn75dlMFGTsWMdzrUEtQKBgQDCAbbPuW4AlIUeM0JpYRr+3Jgn7NwEeX0N\nrGqBWYFfgQseL/O9KS2gwGlfdwhp7eLk4jfZuzRSVsWnA7LSEwey98BYGEPKOiWk\nLVCACe+auWtvLtIY4AJebpRAksyZ4NhCpSJyGDCJVl/NPkQ/sDYth8LftALDHz7/\n67kZP9xd2QKBgAczX3pwn39JBoh3gvgYrlE1j2cHrVG2N2Mr4pL9EUkwyUShoAQ7\nEowTWqm5FI1WjrAwrAIJjEzWlEebCPIfK0zO+vQwvNKzEI0e3VoWAPSr7PqUhTQU\nTNDsZqXEkXLK2vZxs87cqswbiGnvqm8+WkoFv4lEHXCjOadYHuM0hFoZAoGAZLC7\nDuiwnQB4boowJ71MY4ZeOiqGrpPXQaeAx42KxeSVvp8oo76hfdMfXXrMFR5wKlb2\noby1lR6QCvSydLGHx20qmQ5O8MBpFOKn6yw8/VLK3bOxO1PYJubBbxpBsoOt+jj2\nvbysRDteEYoFpgBwvgS+MZid7mNjMTRIp0ArwVECgYB8HJy0vJvyciTQ6qug5NXS\n4Q5geilYIfLNJJOdfN1s/F+2U3bfRkjjC4eQ+9klOCnGTQ3bwWfTll+BxRxgGmLj\nc0DUac45d5g1fu8W6szQDXn1rdHU2D3HFgWyCWlvVWUCEOmLzCcLEweyHqr/QCJT\nbN94GGUM4e3lU7Vhy7jMEw==\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-f6oi5@yasour-13931.iam.gserviceaccount.com", + "client_id": "110869359640165866535", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-f6oi5%40yasour-13931.iam.gserviceaccount.com", + "universe_domain": "googleapis.com" +} diff --git a/osinaweb/osichat/__pycache__/admin.cpython-310.pyc b/osinaweb/osichat/__pycache__/admin.cpython-310.pyc index 935cc9d7..66347c43 100644 Binary files a/osinaweb/osichat/__pycache__/admin.cpython-310.pyc and b/osinaweb/osichat/__pycache__/admin.cpython-310.pyc differ diff --git a/osinaweb/osichat/__pycache__/consumers.cpython-310.pyc b/osinaweb/osichat/__pycache__/consumers.cpython-310.pyc index f01fdaf2..eecff37a 100644 Binary files a/osinaweb/osichat/__pycache__/consumers.cpython-310.pyc and b/osinaweb/osichat/__pycache__/consumers.cpython-310.pyc differ diff --git a/osinaweb/osichat/__pycache__/models.cpython-310.pyc b/osinaweb/osichat/__pycache__/models.cpython-310.pyc index 636fc3c1..86c48ab2 100644 Binary files a/osinaweb/osichat/__pycache__/models.cpython-310.pyc and b/osinaweb/osichat/__pycache__/models.cpython-310.pyc differ diff --git a/osinaweb/osichat/admin.py b/osinaweb/osichat/admin.py index 5d0fe1d5..c5adceef 100644 --- a/osinaweb/osichat/admin.py +++ b/osinaweb/osichat/admin.py @@ -12,3 +12,4 @@ admin.site.register(ChatMessageAttachment) admin.site.register(ChatMessageReaction) admin.site.register(ChatMessageSeen) admin.site.register(ChatRoomReview) +admin.site.register(ChatNotification) diff --git a/osinaweb/osichat/consumers.py b/osinaweb/osichat/consumers.py index 8b7c35d1..d68a3f54 100644 --- a/osinaweb/osichat/consumers.py +++ b/osinaweb/osichat/consumers.py @@ -87,17 +87,13 @@ class Osichat(WebsocketConsumer): event = { 'type': 'get_chats_handler', } - async_to_sync(self.channel_layer.group_send)( - 'osichat', event - ) + self.get_chats_handler(event) if event_type == 'get_visitors': event = { 'type': 'get_visitors_handler', } - async_to_sync(self.channel_layer.group_send)( - 'osichat', event - ) + self.get_visitors_handler(event) def get_chats_handler(self, event): diff --git a/osinaweb/osichat/migrations/0024_chatotification.py b/osinaweb/osichat/migrations/0024_chatotification.py new file mode 100644 index 00000000..42ec0d60 --- /dev/null +++ b/osinaweb/osichat/migrations/0024_chatotification.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.5 on 2024-08-13 06:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osichat', '0023_visitor_browser_name_visitor_os_name'), + ] + + operations = [ + migrations.CreateModel( + name='Chatotification', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=255)), + ('message', models.TextField()), + ('image', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ], + ), + ] diff --git a/osinaweb/osichat/migrations/0025_rename_chatotification_chatnotification.py b/osinaweb/osichat/migrations/0025_rename_chatotification_chatnotification.py new file mode 100644 index 00000000..40228beb --- /dev/null +++ b/osinaweb/osichat/migrations/0025_rename_chatotification_chatnotification.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.5 on 2024-08-13 06:49 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osichat', '0024_chatotification'), + ] + + operations = [ + migrations.RenameModel( + old_name='Chatotification', + new_name='ChatNotification', + ), + ] diff --git a/osinaweb/osichat/migrations/__pycache__/0024_chatotification.cpython-310.pyc b/osinaweb/osichat/migrations/__pycache__/0024_chatotification.cpython-310.pyc new file mode 100644 index 00000000..4cee47ac Binary files /dev/null and b/osinaweb/osichat/migrations/__pycache__/0024_chatotification.cpython-310.pyc differ diff --git a/osinaweb/osichat/migrations/__pycache__/0025_rename_chatotification_chatnotification.cpython-310.pyc b/osinaweb/osichat/migrations/__pycache__/0025_rename_chatotification_chatnotification.cpython-310.pyc new file mode 100644 index 00000000..adb12998 Binary files /dev/null and b/osinaweb/osichat/migrations/__pycache__/0025_rename_chatotification_chatnotification.cpython-310.pyc differ diff --git a/osinaweb/osichat/models.py b/osinaweb/osichat/models.py index b8e0a152..fdc5c24e 100644 --- a/osinaweb/osichat/models.py +++ b/osinaweb/osichat/models.py @@ -4,10 +4,46 @@ import mimetypes import os from channels.layers import get_channel_layer from asgiref.sync import async_to_sync -import json +from fcm_django.models import FCMDevice +from firebase_admin.messaging import Message, Notification as NotificationFB +from django.utils.safestring import mark_safe + + +def send_notification(notification): + notification_data = { + 'title': notification.title, + 'body': mark_safe(notification.message), + } + if notification.image: + FCMDevice.objects.send_message( + Message(notification=NotificationFB( + title=notification_data['title'], + body=notification_data['body'], + image= notification.image + ), data={"image": notification.image}) + ) + else: + FCMDevice.objects.send_message( + Message(notification=NotificationFB( + title=notification_data['title'], + body=notification_data['body'] + )) + ) # Create your models here. +class ChatNotification(models.Model): + title = models.CharField(max_length=255) + message = models.TextField() + image = models.TextField(blank=True,null=True) + created_at = models.DateTimeField(auto_now_add=True) + def save(self, *args, **kwargs): + is_new = not self.pk + super().save(*args, **kwargs) + if is_new: + send_notification(self) + + class Visitor(models.Model): session_id = models.CharField(max_length=300) ip_address = models.CharField(max_length=300) @@ -42,6 +78,7 @@ class Visitor(models.Model): return f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}" else: return f"{int(minutes):02}:{int(seconds):02}" + def save(self, *args, **kwargs): super().save(*args, **kwargs) channel_layer = get_channel_layer() @@ -51,6 +88,13 @@ class Visitor(models.Model): 'action': 'new_visitor' } async_to_sync(channel_layer.group_send)("osichat", event) + self.send_visitor_notification() + + def send_visitor_notification(self): + notification = ChatNotification.objects.create( + title="New visitor on Ositcom!", + image = self.flag_image_url + ) @@ -62,6 +106,7 @@ class VisitorLog(models.Model): visit_date = models.DateTimeField(null=True) left_date = models.DateTimeField(null=True) def save(self, *args, **kwargs): + is_new = not self.pk if self.left_date: action = 'end_log' else: @@ -74,6 +119,14 @@ class VisitorLog(models.Model): 'action': action } async_to_sync(channel_layer.group_send)("osichat", event) + if is_new: + self.send_visitorlog_notification() + + def send_visitorlog_notification(self): + notification = ChatMessage.objects.create( + title=f"Visitor navigated to: {self.title}.", + image=self.visitor.flag_image_url + ) class ChatRoom(models.Model): diff --git a/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc b/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc index d3062be3..e598d4db 100644 Binary files a/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc and b/osinaweb/osinaweb/__pycache__/settings.cpython-310.pyc differ diff --git a/osinaweb/osinaweb/settings.py b/osinaweb/osinaweb/settings.py index 88d5f350..be45d255 100644 --- a/osinaweb/osinaweb/settings.py +++ b/osinaweb/osinaweb/settings.py @@ -12,10 +12,22 @@ https://docs.djangoproject.com/en/4.1/ref/settings/ from pathlib import Path import os +from firebase_admin import initialize_app # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent +FIREBASE_APP = initialize_app() + +FCM_DJANGO_SETTINGS = { + + "DEFAULT_FIREBASE_APP": None, + "APP_VERBOSE_NAME": "Osichat", + "ONE_DEVICE_PER_USER": True, + "DELETE_INACTIVE_DEVICES": True, + "UPDATE_ON_DUPLICATE_REG_ID": False, +} + # settings.py @@ -44,6 +56,7 @@ INSTALLED_APPS = [ 'daphne', 'support', 'rest_framework', + 'fcm_django', 'osinacore', 'customercore', 'addressbook', @@ -167,6 +180,10 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'static/images') DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +new_credentials_path = "firebase_credentials.json" + +os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = new_credentials_path + EMAIL_HOST = 'osinamail.ositcom.com' EMAIL_PORT = 587