Project-Stage-Academy / UA1244_beta

1 stars 0 forks source link

Notification System for New Messages [40-5] #49

Open mehalyna opened 3 weeks ago

mehalyna commented 3 weeks ago

Description: Develop a notification system to alert users when they receive new messages. This system will leverage Django signals to detect when messages are sent and use Django Channels to deliver these notifications to users in real-time.

Technical Steps:

1. Design Notification Model

Create a model to store notifications. This model will keep track of which messages have been notified to users and their read status.

2. Set Up Django Signals

Configure Django signals to create a notification each time a message is sent. This ensures that every message triggers a real-time alert to the intended recipient. E.g.

from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Message, Notification

@receiver(post_save, sender=Message)
def create_notification(sender, instance, created, **kwargs):
    if created:
        Notification.objects.create(
            recipient=instance.receiver,
            message=instance
        )

3. Implement WebSocket Consumer for Notifications

Define a WebSocket consumer that handles sending notification data to the user’s client. This consumer listens for notification messages and sends them to the frontend. E.g.

from channels.generic.websocket import AsyncWebsocketConsumer
import json

class NotificationConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_group_name = f'notifications_{self.scope["user"].id}'

        # Join room group
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )
        await self.accept()

    async def disconnect(self, close_code):
        # Leave room group
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    # Receive message from room group
    async def send_notification(self, event):
        notification = event['notification']

        # Send message to WebSocket
        await self.send(text_data=json.dumps({
            'notification': notification
        }))

4. Trigger Real-Time Notifications

Modify the signal to send notifications through Django Channels when a new message is saved. This uses the Channels layer to broadcast the notification. E.g.

@receiver(post_save, sender=Message)
def send_notification_via_channels(sender, instance, created, **kwargs):
    if created:
        notification = Notification.objects.create(
            recipient=instance.receiver,
            message=instance
        )
        channel_layer = get_channel_layer()
        async_to_sync(channel_layer.group_send)(
            f'notifications_{instance.receiver.id}',
            {
                'type': 'send_notification',
                'notification': f'New message from {instance.sender.username}'
            }
        )

5. Routing and URL Configuration for WebSocket

Set up routing in routing.py to map the notification path to the consumer. E.g.

from django.urls import re_path
from .consumers import NotificationConsumer

websocket_urlpatterns = [
    re_path(r'ws/notifications/', NotificationConsumer.as_asgi()),
]

https://docs.djangoproject.com/en/5.0/topics/signals/ https://channels.readthedocs.io/en/latest/topics/channel_layers.html

Task #40