Exemplo n.º 1
0
 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={})
     serializer = ConversationSerializer(conversation, data={}, context={'request': request})
     serializer.is_valid(raise_exception=True)
     return Response(serializer.data)
Exemplo n.º 2
0
 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)
     serializer = ConversationSerializer(
         conversation, data={}, context=self.get_serializer_context())
     serializer.is_valid(raise_exception=True)
     return Response(serializer.data)
Exemplo n.º 3
0
 def test_instantiation(self):
     serializer = ConversationSerializer(self.conversation)
     self.assertEqual(serializer.data['topic'], self.conversation.topic)
     self.assertEqual(serializer.data['id'], self.conversation.id)
     self.assertEqual([_['id'] for _ in serializer.data['participants']],
                      [_.id for _ in self.conversation.participants.all()])
     self.assertEqual([_['content'] for _ in serializer.data['messages']],
                      [_.content for _ in self.conversation.messages.all()])
Exemplo n.º 4
0
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'

    push_exclude_users = []

    for subscription in ChannelSubscription.objects.recent().filter(
            user__in=conversation.participants.all()):
        if not subscription.away_at:
            push_exclude_users.append(subscription.user)

        payload = ConversationMessageSerializer(
            message, context={
                'request': MockRequest(user=subscription.user)
            }).data
        send_in_channel(subscription.reply_channel, topic, payload)

    # Send push notifications when a message is created, but not when it is modified
    if created:
        tokens = [
            item.token for item in PushSubscription.objects.filter(
                Q(user__in=conversation.participants.all())
                & ~Q(user__in=push_exclude_users) & ~Q(user=message.author))
        ]

        if len(tokens) > 0:
            message_title = message.author.display_name
            if isinstance(conversation.target, Group):
                message_title = '{} / {}'.format(conversation.target.name,
                                                 message_title)

            notify_multiple_devices(
                registration_ids=tokens,
                message_title=message_title,
                message_body=message.content,
                # this causes each notification for a given conversation to replace previous notifications
                # fancier would be to make the new notifications show a summary not just the latest message
                tag='conversation:{}'.format(conversation.id))

    # 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'

    for subscription in ChannelSubscription.objects.recent()\
            .filter(user__in=conversation.participants.all())\
            .exclude(user=message.author):
        payload = ConversationSerializer(
            conversation,
            context={
                'request': MockRequest(user=subscription.user)
            }).data
        send_in_channel(subscription.reply_channel, topic, payload)
Exemplo n.º 5
0
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():
        payload = ConversationSerializer(
            conversation,
            context={
                'request': MockRequest(user=subscription.user)
            }).data
        send_in_channel(subscription.reply_channel, topic, payload)
Exemplo n.º 6
0
def send_participant_left(sender, instance, **kwargs):
    """Notify other conversation participants when someone leaves"""
    conversation = instance.conversation

    topic = 'conversations:conversation'

    for subscription in ChannelSubscription.objects.recent() \
            .filter(user__in=conversation.participants.all()) \
            .exclude(user=instance.user):
        payload = ConversationSerializer(
            conversation,
            context={
                'request': MockRequest(user=subscription.user)
            }).data
        send_in_channel(subscription.reply_channel, topic, payload)
Exemplo n.º 7
0
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)
    conversation = instance.conversation

    topic = 'conversations:conversation'
    payload = ConversationSerializer(conversation,
                                     context={
                                         'request':
                                         MockRequest(user=instance.user)
                                     }).data

    for subscription in ChannelSubscription.objects.recent().filter(
            user=instance.user):
        send_in_channel(subscription.reply_channel, topic, payload)
Exemplo n.º 8
0
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():
        payload = ConversationSerializer(
            conversation,
            context={
                'request': MockRequest(user=subscription.user)
            }).data
        send_in_channel(subscription.reply_channel, topic, payload)
Exemplo n.º 9
0
 def retrieve_conversation(self, request, *args, **kwargs):
     target = self.get_object()
     conversation = Conversation.objects.get_or_create_for_target(target)
     serializer = ConversationSerializer(conversation, context={'request': request})
     return Response(serializer.data)
Exemplo n.º 10
0
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'

    push_exclude_users = []

    for subscription in ChannelSubscription.objects.recent().filter(
            user__in=conversation.participants.all()):
        if not subscription.away_at:
            push_exclude_users.append(subscription.user)

        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

    subscriptions = PushSubscription.objects.filter(
        Q(user__in=conversation.participants.all())
        & ~Q(user__in=push_exclude_users) & ~Q(user=message.author))

    message_title = message.author.display_name
    if isinstance(conversation.target, Group):
        message_title = '{} / {}'.format(conversation.target.name,
                                         message_title)

    click_action = None
    if message.is_thread_reply():
        click_action = frontend_urls.thread_url(message.thread)
    else:
        click_action = frontend_urls.conversation_url(conversation,
                                                      message.author)

    notify_subscribers(
        subscriptions=subscriptions,
        fcm_options={
            'message_title': message_title,
            'message_body': message.content,
            'click_action': click_action,
            'message_icon': logo_url(),
            # this causes each notification for a given conversation to replace previous notifications
            # fancier would be to make the new notifications show a summary not just the latest message
            'tag': 'conversation:{}'.format(conversation.id)
        })

    # 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):
        payload = ConversationSerializer(
            conversation,
            context={
                'request': MockRequest(user=subscription.user)
            }).data
        send_in_channel(subscription.reply_channel, topic, payload)