Hello guys, how do I create/update the messages that end-users will send to the other users in my consumers? Would I have to implement something like self.send()
in the receive method?
Here is my consumers.py
import json
from channels.consumer import AsyncConsumer
from channels.generic.websocket import AsyncJsonWebsocketConsumer
from asgiref.sync import sync_to_async
import base64
# Channel consumer for both chat room group
class ChatConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.room_name
# 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 WebSocket
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
if message_type == 'edit_message':
message_id = text_data_json['message_id']
new_message = text_data_json['new_message']
await self.edit_message(message_id, new_message)
@sync_to_async
def edit_message(self, message_id, new_message):
# update retreived message from database
message = Message.objects.get(id=message_id)
message.content = new_message
message.save()
# broadcast (send) to group
self.channel_layer.group_send(
self.group_name,
{
'type': 'message_edited',
'message_id': message_id,
'new_message': new_message,
}
}
async def message_edited(self, event):
message_id = event['message_id']
new_message = event['new_message']
await self.send(text_data=json.dumps({
'type': 'message_edited',
'message_id': message_id,
'new_message': new_message,
}))
print(f"Received message: {message}")
# Send message to room group
await self.channel_layer.group_send(
self.room_group_name, {'type': 'chat.message', 'message': message}
)
# Receive message from room group
async def chat_message(self, event):
message = event['message']
print(f"Broadcasting message: {message}") # Debugging output
# send message to websocket
await self.send(text_data=json.dumps({'message': message}))
# Channel Consumer that consumed events for uploading/receiving image files in the message room
class UploadImageConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
await self.accept()
async def disconnect(self, close_code):
async def receive(self, bytes_data=None, text_data=None):
if bytes_data:
# Handles image file chunks (binary data)
with open('image.jpg', 'rb') as f:
fcontent = f.read()
await self.send(base64.b64encode(fcontent).decode('utf-8'))
elif text_data:
# Handles metadata (text data)
await self.send(text_data=json.dumps({'message': text_data}))
async def send_image(self, event):
image_data = event['image_text']
await self.send(bytes_data=image_data)
messenger.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>ArborHub messenger</title>
<link rel="icon" href="{% static 'favicon.ico' %}">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
<style>
#messageLog {
height: 300px;
background-color: #FFFFFF;
resize: none;
}
#onlineArboristSelector {
height: 300px;
}
</style>
</head>
<body>
<textarea id='chat-text' cols='80' rows='30'></textarea>
<div id='hello-world'></div>
<div class="container mt-3 p-5">
<h2>ArborHub messenger</h2>
<div class="row">
<div class="col-12 col-md-8">
<div class="mb-2">
<label for="messageLog">Room: #{{ room.name}}</label>
<textarea class="form-control" id="messageLog" readOnly></textarea>
</div>
<div class="input-group">
<input type="text" class="form-control" id="channelMessage" placeholder="Message here">
<div class="input-group-append">
<button class="btn btn-success" id="sendMessage" type="button">Send</button>
</div>
</div>
</div>
<div class="col-12 col-md-4">
<label for="onlineArboristSelector">Online arborists</label>
<select multiple class="form-control" id="onlineArboristSelector">
</select>
</div>
</div>
</div>
{{ room_name|json_script:'room-name'}}
<script>
document.querySelector('#sendMessage').onclick = function (e) {
const messageInputDom = document.querySelector('#channelMessage');
const message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'message': message,
}));
function editMessage(messageId, newMessage) {
websocket.send(JSON.stringify({
'type': 'edit_message',
'message_id': messageId,
'new_message': new Message
}));
}
websocket.onmessaage = function(event) {
const data = JSON.parse(event.data);
if (dataa.type === 'message_edited') {
const messageId = data.message_id;
const newMessage = data.new_message;
}
}
messageInputDom.value = '';
};
const roomName = JSON.parse(document.getElementById('room-name').textContent);
const chatSocket = new WebSocket(
'ws://' +
location.host +
'/ws/arborchat/' +
roomName +
'/'
);
chatSocket.onmessage = function (e) {
const data = JSON.parse(e.data);
console.log("Received message:", data);
const messageLog = document.querySelector('#messageLog');
messageLog.value += data.message + '\n';
}
</script>
</body>
</html>
Someone suggested that the code doesn’t specify when the message ID was created in consumers. Please I need guidance on this.
Even a link would help