Sreekanth Reddy Balne
Sreekanth Reddy Balne

Reputation: 3424

How to send user notifications using django-channels 2.0?

I am working on a chat app that has Rooms. Each room has two users. A user can be in multiple rooms i.e, a user has multiple rooms. And now he is chatting in one room. But he receives a message in another room. I would like to notify about the message from other room to the user. How should I implement this?

Currently a websocket connection is established as: ws://localhost:8000/chat/int<room_id>/

And the group_name is named as "room"+room_id. and So far I have:

async def connect(self):
    room_id = self.scope['url_route']['kwargs']['room_id']
    await self.channel_layer.group_add(
            "room"+room_id,
            self.channel_name
        )
    await self.accept()

async def receive(self, text_data):
    await self.channel_layer.group_send(
        self.room_name,
        {
            'type': 'chat_message',
            'message': json.loads(text_data)
        }
    )
async def chat_message(self, event):
    await self.send(text_data=json.dumps({
        'message': event['message']
    }))

Django 2.x django-channels 2.x python 3.6

Upvotes: 2

Views: 4084

Answers (4)

shripad
shripad

Reputation: 1

django code for circulars and notifications system using class based and using serializer function with hole project code in step by step

Upvotes: -2

Mohammad Aqajani
Mohammad Aqajani

Reputation: 178

(idea:)I opened two sockets:

  1. one for current room which user is texting in
  2. the second for chat rooms list (a hidden base chatroom created as well; better to say: a channel layer that belongs to chat rooms list),

then on every message received from any user in the first explained channel(above), I will send proper reply to both of the sockets.

example at here: chatroom.subtionary.com (just click on one chatroom and enter with email) it also reorder the chat rooms list and pulse the element and also write the last message of each chatroom under its element, also enjoy reply and delete options!!

(I know this is the laziest way, but works well)

Upvotes: 0

bdoubleu
bdoubleu

Reputation: 6107

You need at least two models Message, MessageThread. When the user connects to the socket the channel is added to each thread group that the user is included in. You also have to add the channel_name to the user session.

messaging/models.py

class MessageThread(models.Model):
    title = models.CharField()
    clients = models.ManyToManyField(User, blank=True)

class Message(models.Model):
    date = models.DateField()
    text = models.CharField()
    thread = models.ForeignKey('messaging.MessageThread', on_delete=models.CASCADE)
    sender = models.ForeignKey(User, on_delete=models.SET_NULL)

chat/consumers.py

class ChatConsumer(WebSocketConsumer):
    def connect(self):
        if self.scope['user'].is_authenticated:
            self.accept()
            # add connection to existing groups
            for thread in MessageThread.objects.filter(clients=self.scope['user']).values('id'):
                async_to_sync(self.channel_layer.group_add)(thread.id, self.channel_name)
            # store client channel name in the user session
            self.scope['session']['channel_name'] = self.channel_name
            self.scope['session'].save()

    def disconnect(self, close_code):
        # remove channel name from session
        if self.scope['user'].is_authenticated:
            if 'channel_name' in self.scope['session']:
                del self.scope['session']['channel_name']
                self.scope['session'].save()
            async_to_sync(self.channel_layer.group_discard)(self.scope['user'].id, self.channel_name)

Upvotes: 1

ThatCampbellKid
ThatCampbellKid

Reputation: 523

I do something similar, you can try something like this:

connect(message):
    // however you get your chatroom value from the socket
    Group("%s" % chatroom).add(message.reply_channel)

message(message):
    message = json.loads(message.content['text'])
    chatroom = message['chatroom']  
    Group("%s" % chatroom).send({
            "text": json.dumps({
                "id": "newuser",
                "username": message['username'],
                "message": message['message']
            })
        })

I might have misread your question. Maybe something more like:

Create a unique id for each user and use that value as the 'chatroom', then send each message with a chatroom number and the user number that it should go to. Django can interpret the user id and sent the message to the right channel, then have the Javascript interpret it the message and roomnumber to bring them to the right page?

That is an interesting idea

Upvotes: 0

Related Questions