Using Django Channels 2.1.1 and Django 2.0, I'm building a site where a customer presses a button and is brought into a chatroom with one staff in it. I'm beginning from Andrew Godwin's multichat example.
In short: I can't figure out how to properly add staff to group so that he can both receive and send messages in the chatroom.
I've read the documentation on layers, groups, and channels. I can't say I'm very clear on the concepts, but I figure a channel pertains to an individual user, a group pertains to a chatroom or its equivalent where users are somehow grouped together, and the layer is the medium through which communication takes place.
Using this understanding, the best I've been able to do has been to add to the join_room(self, room_id)
function like this, which is probably completely the wrong thing to do:
async def join_room_client(self, room_id):
...
# Added to find all staff who are logged in
authenticated_staff = get_all_logged_in_users()
# Added to list staff who are in less than 3 chatrooms
available_staff = []
if len(authenticated_staff) > 0:
for staff in authenticated_staff:
if staff in users_and_rooms and len(users_and_rooms[staff]) in range(3):
available_staff.append(staff)
random_available_staff = random.choice(available_staff)
# I thought receive_json() would look for "content", but I was wrong
content = {
"command": "join",
"join": room_id,
"type": "chat.join",
"room_id": room_id,
"text": "Hello there!",
"username": random_available_staff,
"title": room.title,
}
# Helps to open room in conjunction with chat_join()?
from channels.layers import get_channel_layer
channel_layer = get_channel_layer()
await channel_layer.send(users_and_channels[random_available_staff], content)
# This allows staff to receive messages in the chatroom but not to reply.
await self.channel_layer.group_add(
room.group_name,
# The line below is staff's channel name, eg: specific.PhCvZeuI!aCOgcyvgDanT
# I got it by accessing self.channel_name in connect(self)
users_and_channels[random_available_staff],
)
else:
print("Staff are not yet ready.")
else:
print("There are no staff available.")
With this code, the room automatically opens on the staff's browser. He can see customer's messages, but trying to reply raises "ROOM_ACCESS_DENIED"
, which means he hasn't been added to the room. But I thought I'd done that with group.add(room.group_name, users_and_channels[random_available_staff])
.
Anyway, presumably, the most efficient way is for data about the chatroom to be sent to the staff member's instance of receive_json(self, content)
when customer presses the button, right? But the function receives data from the Javascript in the template via this:
socket.send(JSON.stringify({
"command": "join",
"room": roomId
})
If it's possible, how do I send data about the customer's chatroom to staff's receive_json()
using the consumers in consumers.py itself? If not, what other approaches should I use?