def send_participant_left(sender, instance, **kwargs): """Notify conversation participants when someone leaves""" conversation = instance.conversation topic = 'conversations:conversation' # TODO send to all group members? for subscription in ChannelSubscription.objects.recent() \ .filter(user__in=conversation.participants.all()).distinct(): participant = conversation.conversationparticipant_set.get(user=subscription.user) payload = ConversationSerializer(participant, context={'request': MockRequest(user=subscription.user)}).data send_in_channel(subscription.reply_channel, topic, payload) participant = conversation.make_participant() payload = ConversationSerializer(participant).data for subscription in ChannelSubscription.objects.recent().filter(user=instance.user).distinct(): send_in_channel(subscription.reply_channel, topic, payload)
def retrieve_private_conversation(self, request, *args, **kwargs): user2 = self.get_object() try: conversation = Conversation.objects.get_or_create_for_two_users(request.user, user2) except Exception: return Response(status=status.HTTP_404_NOT_FOUND, data={}) participant = conversation.conversationparticipant_set.get(user=request.user) serializer = ConversationSerializer(participant, context=self.get_serializer_context()) return Response(serializer.data)
def send_conversation_update(sender, instance, **kwargs): # Update conversations object for user after updating their participation # (important for seen_up_to and unread_message_count) participant = instance topic = 'conversations:conversation' payload = ConversationSerializer(participant, context={'request': MockRequest(user=participant.user)}).data for subscription in ChannelSubscription.objects.recent().filter(user=instance.user): send_in_channel(subscription.reply_channel, topic, payload)
def send_messages(sender, instance, created, **kwargs): """When there is a message in a conversation we need to send it to any subscribed participants.""" message = instance conversation = message.conversation topic = 'conversations:message' for subscription in ChannelSubscription.objects.recent().filter( user__in=conversation.participants.all()).distinct(): payload = ConversationMessageSerializer( message, context={ 'request': MockRequest(user=subscription.user) }).data send_in_channel(subscription.reply_channel, topic, payload) if created and message.is_thread_reply( ) and subscription.user != message.author: payload = ConversationMessageSerializer( message.thread, context={ 'request': MockRequest(user=subscription.user) }).data send_in_channel(subscription.reply_channel, topic, payload) # Send push notification and conversation updates when a message is created, but not when it is modified if not created: return tasks.notify_message_push_subscribers(message) # Send conversations object to participants after sending a message # (important for unread_message_count) # Exclude the author because their seen_up_to status gets updated, # so they will receive the `send_conversation_update` message topic = 'conversations:conversation' # Can be skipped for thread replies, as they don't alter the conversations object if message.is_thread_reply(): return for subscription in ChannelSubscription.objects.recent()\ .filter(user__in=conversation.participants.all())\ .exclude(user=message.author).distinct(): participant = conversation.conversationparticipant_set.get( user=subscription.user) payload = ConversationSerializer( participant, context={ 'request': MockRequest(user=subscription.user) }).data send_in_channel(subscription.reply_channel, topic, payload)
def send_participant_joined(sender, instance, created, **kwargs): """Notify other participants when someone joins""" if not created: return conversation = instance.conversation topic = 'conversations:conversation' for subscription in ChannelSubscription.objects.recent() \ .filter(user__in=conversation.participants.all()) \ .exclude(user=instance.user).distinct(): participant = conversation.conversationparticipant_set.get(user=subscription.user) payload = ConversationSerializer(participant, context={'request': MockRequest(user=subscription.user)}).data send_in_channel(subscription.reply_channel, topic, payload)
def retrieve_conversation(self, request, *args, **kwargs): target = self.get_object() conversation = Conversation.objects. \ prefetch_related('conversationparticipant_set'). \ select_related('target_type'). \ get_or_create_for_target(target) participant = conversation.conversationparticipant_set.filter(user=request.user).first() if not participant: if conversation.can_access(request.user): participant = conversation.make_participant() else: self.permission_denied(request, message=_('You are not in this conversation')) serializer = ConversationSerializer(participant, context=self.get_serializer_context()) return Response(serializer.data)