Sending Notification to admin using Django Channels

Hy…
i am working an leave system where i want when user submit leave form then admin receive notification that particular user request for leave, so amdin can approve or decline it.
Form submission is done and for notification iam using Django Channels, I have configure django channels and also its dependencies, now websocket connection is established successfully and iam sending data form front end (websocket king client) to my backend (terminal) and it is working.

But as i discuss above the main part is i want to send leave application data to admin so admin can receive notification and approve or decline it.

I think for this we need to use channel_layer and send data to consumer and iam doing the same but it is not working and iam little bit confused about its flow that how data flow from user to admin.

This i smy view function…

def leaveForm(request):
    
    if request.method == "POST":
        try:
            leaveData = {
                'employeeLeave': request.user,
                'leaveApplyDate': request.POST.get('leaveApplyDate'),
                'leaveEmployeeName': request.POST.get('leaveEmployeeName'),
                'leaveEmployeeId': request.POST.get('leaveEmployeeId'),
                'leaveEmployeeDepartment': request.POST.get('leaveEmployeeDepartment'),
                'leaveEmployeeDesigination': request.POST.get('leaveEmployeeDesigination'),
                'leaveType': request.POST.get('leaveType'),
                'leaveCategory': request.POST.get('leaveCategory'),
                'leaveReason': request.POST.get('leaveReason'),
                # 'leaveStatus': request.POST.get('leaveStatus'),
                'leaveNoDays': request.POST.get('leaveNoDays'),
                'leaveDateFrom': request.POST.get('leaveDateFrom'),
                'leaveDateTo': request.POST.get('leaveDateTo'),
                'leaveDateHalfDay': request.POST.get('leaveDateHalfDay'),
                'leaveTimeFrom': request.POST.get('leaveTimeFrom'),
                'leaveTimeTo': request.POST.get('leaveTimeTo'),
                'leaveOtherReasons': request.POST.get('leaveOtherReasons'),
                'leaveStatus':'Pending'
            }

            print("leaveData",leaveData)

            leave_type = request.POST.get('leaveType')
            if leave_type == 'Leave':
                leaveData['leaveNoDays']: request.POST.get('leaveNoDays')
                leaveData['leaveDateFrom']: request.POST.get('leaveDateFrom')        
                leaveData['leaveDateTo']: request.POST.get('leaveDateTo')            
                leaveData['leaveDateHalfDay'] = None  
                leaveData['leaveTimeFrom'] = None  
                leaveData['leaveTimeTo'] = None
                leaveDataObject = Leave(**leaveData)
            elif leave_type == 'Half Day':
                leaveData['leaveDateHalfDay']: request.POST.get('leaveDateHalfDay')
                leaveData['leaveTimeFrom']: request.POST.get('leaveTimeFrom')
                leaveData['leaveTimeTo']: request.POST.get('leaveTimeTo')
                leaveData['leaveNoDays'] = None  
                leaveData['leaveDateFrom'] = None  
                leaveData['leaveDateTo'] = None
                leaveDataObject = Leave(**leaveData)
            else:
                leave_type = None

            leave_reason = request.POST.get('leaveReason')
            if leave_reason == 'Other':
                leaveData['leaveOtherReasons']: request.POST.get('leaveOtherReasons')
                leaveDataObject = Leave(**leaveData)
            else:
                leaveOtherReasons = None


            leaveDataObject = Leave(**leaveData)
            leaveDataObject.save()
            leave_application_id = leaveDataObject.id  # Use the ID here

            channel_layer = get_channel_layer()
            print("channel_layer", channel_layer)
            admin_channel_name = "admin_notifications"  # Choose a channel name for admin notifications
            message = {
                "type": "leave_application_submitted",
                "data": {
                    "user_id": request.user.id,
                    "user_name": request.user.username,
                    "leave_application_id": leave_application_id,  # Use the ID here
                },
            }
            print("message", message)
            async_to_sync(channel_layer.send)(admin_channel_name, message)
            print("1-----")
            print("2--",async_to_sync(channel_layer.send)(admin_channel_name, message))

            messages.success(request, 'Leave applied successfully.')
            return redirect('attendanceManagement')
        except Exception as e:
                messages.error(request, f'Some Error Occurred While Saving Data: {str(e)}')
    
    
    leaveData=Leave.objects.all()

    context={
        'leaveData':leaveData,
    }
    print("context",context)
    return render(request,'pages/attendance_management.html',context)

and this is my consumer.py file code…

class AdminNotificationConsumer(AsyncConsumer):
    async def websocket_connect(self, event):
        print('WebSocket connect', event)

        leave_data = {
            "user_id": event.get("user_id"),
            "user_name": event.get("user_name"),
            "leave_application_id": event.get("leave_application_id"),
        }
        print('leave_data', leave_data)
        await self.send({
            "type": "websocket.accept",
            "leave_data": leave_data, 
        })
        print('2---')

    async def websocket_receive(self, event):
        print('WebSocket message received:', event)
        for i in range(10):
            self.send({
                'type':'websocket.send',
                'text':str(i)
            })
            sleep(1)
        print("message")

    async def websocket_disconnect(self, event):
        print('WebSocket disconnect', event)
        pass

    async def leave_application_submitted(self, event):
        print('WebSocket submitted', event)
        # Send the notification message to the WebSocket
        await self.send(text_data=json.dumps(event["data"]))

and this i smy javascript function…

 <script>
         const socket = new WebSocket('ws://127.0.0.1:8000/ws/admin_notifications/');

        socket.onopen = function (event) {
            console.log("WebSocket connection established.");
            socket.send("Hi, Message from client");
        };

        socket.onmessage = function (event) {
            const data = JSON.parse(event.data);
            console.log("Received notification data:", data);

            
        };

        socket.onclose = function (e) {
            console.error("WebSocket connection closed:", e);
        };
            </script>

Does the admin user also have an active websocket to Channels?

If so, then the easiest way to send notifications to that person is to have the admin account join a group named “admin”.

The user’s consumer can then send a message to the “admin” group, which will be received by the admin consumer. The admin consumer function receiving that message can then send whatever websocket-based notification is appropriate to the admin’s browser.

This makes the flow of data something like this:
user (browser) → Channels consumer (user) → “Admin” group → Channels consumer (admin) → Admin (browser)

i have only one consumer where i want to get data from leave Form and trying to send that data first in consumer and then in javascript code

How are you expecting the “admin” person to receive this notification?