Esempio n. 1
0
def create_conversation():
    # Insert into DB
    req_conversation = request.json['conversation']

    conversation = Conversation(
        id=None,
        user_a_id=ObjectId(req_conversation['user_a_id']),
        user_b_id=ObjectId(req_conversation['user_b_id']))

    conversation_id = mongo.db.conversations.insert(conversation.to_dict())

    conversation.id = str(conversation_id)
    conversation.user_a_id = str(conversation.user_a_id)
    conversation.user_b_id = str(conversation.user_b_id)

    # Make a conversation analysis model for this conversation
    conversation_analysis = ConversationAnalysis(id=None,
                                                 conversation_id=ObjectId(
                                                     conversation.id),
                                                 sentiment_a=0,
                                                 sentiment_b=0,
                                                 text_to_analyse_a="",
                                                 text_to_analyse_b="",
                                                 sent_insights=[])

    mongo.db.conversation_analysis.insert(conversation_analysis.to_dict())

    # Notify via Socket
    for user_id in [conversation.user_a_id, conversation.user_b_id]:
        socketio.emit("/users/{}/new_conversations".format(user_id),
                      {'conversation': conversation.to_str_dict()},
                      broadcast=True)

    return jsonify({'conversation': conversation.to_dict()})
Esempio n. 2
0
 def get_or_create_conversation(self, conversation):
     return Conversation.get_or_create(
         id=conversation.conversation_id.id,
         defaults={
             'group':
             conversation.type ==
             ConversationType.CONVERSATION_TYPE_GROUP.value
         })[0]
Esempio n. 3
0
def send_message(conversation_id):
    # Insert into DB
    req_message = request.json['message']

    message = Message(id=None,
                      conversation_id=ObjectId(conversation_id),
                      sending_user_id=ObjectId(req_message['sending_user_id']),
                      time=req_message['time'],
                      text=req_message['text'])

    # Notify via websocket
    socketio.emit("/conversations/{}/new_message".format(conversation_id),
                  {'message': message.to_str_dict()},
                  broadcast=True)

    message_id = mongo.db.messages.insert(message.to_dict())
    message.id = str(message_id)
    message.conversation_id = str(message.conversation_id)
    message.sending_user_id = str(message.sending_user_id)

    # Track in conversation analysis model
    # ... Get conversation model
    db_conversation = mongo.db.conversations.find_one(
        {'_id': ObjectId(conversation_id)})

    conversation = Conversation.from_db_document(db_conversation)

    # ... Determine if user who sent message is user_a or user_b
    user_key = 'a'

    if str(conversation.user_b_id) == message.sending_user_id:
        user_key = 'b'

    # ... Accumulate sent text in conversation analysis model
    db_conversation_analysis = mongo.db.conversation_analysis.find_one(
        {'conversation_id': ObjectId(conversation_id)})

    conversation_analysis = ConversationAnalysis.from_db_document(
        db_conversation_analysis)

    current_text = conversation_analysis.to_dict()["text_to_analyse_{}".format(
        user_key)]
    current_text += " {}".format(message.text)

    if user_key == 'a':
        conversation_analysis.text_to_analyse_a = current_text
    else:
        conversation_analysis.text_to_analyse_b = current_text

    # ... Save conversation analysis model
    mongo.db.conversation_analysis.update({'_id': conversation_analysis.id},
                                          conversation_analysis.to_dict())

    # Analyse conversation
    analyse_hook(conversation_id, message.sending_user_id)

    return jsonify({'message': message.to_dict()})
 def get(self, conversation_id=None):
     output = []
     for conversation in Conversation.select().order_by(Conversation.count_messages.desc()):
         if conversation.title == "":
             continue
         output.append({
             "title": conversation.title,
             "nb_messages": str(conversation.count_messages),
             "is_still_participant": conversation.is_still_participant,
             "conversation_id": conversation.conversation_id
         })
     return messages.message(output, namespace=self.get_namespace(request))
Esempio n. 5
0
def get_conversations(user_id):
    db_conversations = mongo.db.conversations.find({
        '$or': [{
            'user_a_id': ObjectId(user_id)
        }, {
            'user_b_id': ObjectId(user_id)
        }]
    })

    conversations = []

    for db_conversation in db_conversations:
        conversations.append(
            Conversation.from_db_document(db_conversation).to_str_dict())

    return jsonify({'conversations': conversations})
Esempio n. 6
0
def handle_im_message(msg):
    obj = json.loads(msg)
    if "appid" not in obj or \
       "sender" not in obj or \
       "receiver" not in obj:
        logging.warning("invalid push msg:%s", msg)
        return

    logging.debug("push msg:%s", msg)
    appid = obj["appid"]
    sender = obj["sender"]
    receiver = obj["receiver"]

    appname = get_title(appid)
    sender_name = user.get_user_name(rds, appid, sender)
    extra = {}
    extra["sender"] = sender

    do_not_disturb = Conversation.get_do_not_disturb(rds,
                                                     appid,
                                                     receiver,
                                                     peer_id=sender)
    if do_not_disturb:
        logging.debug("uid:%s do not disturb :%s", receiver, sender)
        return

    content_obj = json.loads(obj['content'])
    if content_obj.get('revoke'):
        collapse_id = content_obj.get('revoke').get('msgid')
        sender_name = sender_name if sender_name else ''
        content = "%s撤回了一条消息" % sender_name
    else:
        collapse_id = content_obj.get('uuid')
        content = push_content(sender_name, obj["content"])
    push_message(appid,
                 appname,
                 receiver,
                 content,
                 extra,
                 collapse_id=collapse_id)
Esempio n. 7
0
    def analyse(self, conversation_id, last_message_sender_id):
        conversation_query = {'conversation_id': ObjectId(conversation_id)}

        # Get conversation analysis
        db_conversation_analysis = self.mongo.db.conversation_analysis.find_one(
            conversation_query)
        conversation_analysis = ConversationAnalysis.from_db_document(
            db_conversation_analysis)

        # Get conversation
        db_conversation = self.mongo.db.conversations.find_one(
            {'_id': ObjectId(conversation_id)})
        conversation = Conversation.from_db_document(db_conversation)

        # Determine if last message sender is a or b
        last_message_sender_letter = 'a'
        other_letter = 'b'

        if last_message_sender_id == str(conversation.user_b_id):
            last_message_sender_letter = 'b'
            other_letter = 'a'

        # Get other user id
        other_user_id = str(conversation.user_a_id)

        if other_user_id == last_message_sender_id:
            other_user_id = str(conversation.user_b_id)

        # Get sentiments
        last_message_sender_sentiment = conversation_analysis.sentiment_a
        other_user_sentiment = conversation_analysis.sentiment_b

        if last_message_sender_id == str(conversation.user_b_id):
            last_message_sender_sentiment = conversation_analysis.sentiment_b
            other_user_sentiment = conversation_analysis.sentiment_a

        conversation_message_count = self.mongo.db.messages.count_documents(
            conversation_query)

        # Boring intro
        if conversation_message_count == 1:
            db_message = self.mongo.db.messages.find_one(conversation_query)
            message = Message.from_db_document(db_message)

            if len(message.text) < 10:
                send_insight(self.socketio, conversation_id,
                             str(message.sending_user_id), INSIGHT_OPENER,
                             "Try starting with a more interesting message")

        # Ask them out
        if ("{}.{}".format(last_message_sender_letter, INSIGHT_DATE) not in conversation_analysis.sent_insights) and \
                last_message_sender_sentiment >= 0.3 and \
                conversation_message_count > 5:
            send_insight(
                self.socketio, conversation_id, other_user_id, INSIGHT_DATE,
                "It seams like your match is into you, try asking them out on a date!"
            )

            conversation_analysis.sent_insights.append("{}.{}".format(
                last_message_sender_letter, INSIGHT_DATE))

        # Message ratio
        if conversation_message_count > 5:
            # Get message counts
            last_sender_msg_count = self.mongo.db.messages.count_documents({
                'conversation_id':
                ObjectId(conversation_id),
                'sending_user_id':
                ObjectId(last_message_sender_id)
            })
            other_msg_count = self.mongo.db.messages.count_documents({
                'conversation_id':
                ObjectId(conversation_id),
                'sending_user_id':
                ObjectId(other_user_id)
            })

            if last_sender_msg_count > 0 and other_msg_count > 0:

                # Compute ratios
                last_sender_ratio = last_sender_msg_count / other_msg_count
                other_ratio = other_msg_count / last_sender_msg_count

                # Determine if ratios are bad
                ratio_user_ids = []

                if ("{}.{}".format(last_message_sender_letter, INSIGHT_RATIO) not in conversation_analysis.sent_insights) and \
                        last_sender_ratio > 2.5:

                    ratio_user_ids.append(ObjectId(last_message_sender_id))
                    conversation_analysis.sent_insights.append("{}.{}".format(
                        last_message_sender_letter, INSIGHT_RATIO))

                if ("{}.{}".format(other_letter, INSIGHT_RATIO) not in conversation_analysis.sent_insights) and \
                        other_ratio > 2.5:

                    ratio_user_ids.append(ObjectId(other_user_id))
                    conversation_analysis.sent_insights.append("{}.{}".format(
                        other_letter, INSIGHT_RATIO))

                # Send insights
                for user_id in ratio_user_ids:
                    send_insight(
                        self.socketio, conversation_id, str(user_id),
                        INSIGHT_RATIO,
                        "Looks like you are sending a lot of messages, try toning it down"
                    )

        # Topic change
        if ("{}.{}".format(other_letter, INSIGHT_TOPIC)) and \
                other_user_sentiment < -0.2 and \
                conversation_message_count > 5 :

            db_other_user_topics = self.mongo.db.user_topics.find_one(
                {'user_id': ObjectId(other_user_id)})
            other_user_topics = User_Topics.from_db_document(
                db_other_user_topics)

            if len(other_user_topics.topics) > 0:
                msg = "It doesn't look like your match is interested, try talking about {}".format(
                    ", ".join(other_user_topics.topics))

                send_insight(self.socketio, conversation_id, other_user_id,
                             INSIGHT_TOPIC, msg)

                conversation_analysis.sent_insights.append("{}.{}".format(
                    other_letter, INSIGHT_TOPIC))

        # Save conversation analysis
        self.mongo.db.conversation_analysis.update(
            {'_id': conversation_analysis.id}, conversation_analysis.to_dict())
Esempio n. 8
0
    def analyse(self, conversation_id):
        # Get conversation analysis model
        db_conversation_analysis = self.mongo.db.conversation_analysis.find_one(
            {'conversation_id': ObjectId(conversation_id)})

        conversation_analysis = ConversationAnalysis.from_db_document(
            db_conversation_analysis)

        # Get conversation
        db_conversation = self.mongo.db.conversations.find_one(
            {'_id': ObjectId(conversation_id)})

        conversation = Conversation.from_db_document(db_conversation)

        # Get user topics for each user
        # ... User a
        db_user_a_topics = self.mongo.db.user_topics.find_one(
            {'user_id': conversation.user_a_id})
        user_a_topics = User_Topics.from_db_document(db_user_a_topics)

        # ... User b
        db_user_b_topics = self.mongo.db.user_topics.find_one(
            {'user_id': conversation.user_b_id})
        user_b_topics = User_Topics.from_db_document(db_user_b_topics)

        # Setup the GAPI NLP request
        # ... Make one request for user a's text
        document_a = types.Document(
            content=conversation_analysis.text_to_analyse_a,
            type=enums.Document.Type.PLAIN_TEXT)

        # ... Make one request for user b's text
        document_b = types.Document(
            content=conversation_analysis.text_to_analyse_b,
            type=enums.Document.Type.PLAIN_TEXT)

        # Make sentiment calls
        sentiment_a = self.make_sentiment_call(document_a)
        sentiment_b = self.make_sentiment_call(document_b)

        # Update conversation analysis sentiment
        conversation_analysis.sentiment_a = sentiment_a.score * sentiment_a.magnitude
        conversation_analysis.sentiment_b = sentiment_b.score * sentiment_b.magnitude

        # Make categories calls
        user_a_categories = self.make_categories_call(document_a)
        user_b_categories = self.make_categories_call(document_b)

        if user_a_categories is not None:
            # Add new categories
            for name in user_a_categories:
                if name not in user_a_topics.topics:
                    user_a_topics.topics.append(name)

            # Save topics
            self.mongo.db.user_topics.update({'_id': user_a_topics.id},
                                             user_a_topics.to_dict())

            # Clear text to analyse a
            conversation_analysis.text_to_analyse_a = ""

        if user_b_categories is not None:
            # Add new categories
            for name in user_b_categories:
                if name not in user_b_topics.topics:
                    user_b_topics.topics.append(name)

            # Save topics
            self.mongo.db.user_topics.update({'_id': user_b_topics.id},
                                             user_b_topics.to_dict())

            # Clear text to analyse a
            conversation_analysis.text_to_analyse_b = ""

        # Update conversation analysis
        self.mongo.db.conversation_analysis.update(
            {'_id': conversation_analysis.id}, conversation_analysis.to_dict())
Esempio n. 9
0
from models.conversation import Conversation

list_conversation = [
    Conversation(userone_id=1, usertwo_id=2),
    Conversation(userone_id=1, usertwo_id=3),
]
Esempio n. 10
0
def send_group_message(obj):
    appid = obj["appid"]
    sender = obj["sender"]
    receivers = obj["receivers"]
    group_id = obj["group_id"]

    appname = get_title(appid)
    sender_name = user.get_user_name(rds, appid, sender)
    group_name = get_group_name(group_id)
    title = group_name if group_name else appname

    content = push_content(sender_name, obj["content"])

    try:
        c = json.loads(obj["content"])
        collapse_id = c.get('uuid')
        if "revoke" in c:
            collapse_id = c['revoke']['msgid']
            sender_name = sender_name if sender_name else ''
            content = "%s撤回了一条消息" % sender_name
        at = c.get('at', [])
        at_all = c.get('at_all', False)
    except ValueError:
        at = []
        at_all = False
        collapse_id = None

    extra = {}
    extra["sender"] = sender
    extra["group_id"] = group_id

    apns_users = []
    jp_users = []
    xg_users = []
    hw_users = []
    gcm_users = []
    mi_users = []
    ali_users = []

    # 群聊中被at的用户
    at_users = []
    for receiver in receivers:
        do_not_disturb = Conversation.get_do_not_disturb(rds,
                                                         appid,
                                                         receiver,
                                                         group_id=group_id)
        if do_not_disturb:
            logging.info("uid:%d group id:%d do not disturb", receiver,
                         group_id)

        if do_not_disturb and receiver not in at:
            continue

        u = user.get_user(rds, appid, receiver)
        if u is None:
            logging.info("uid:%d nonexist", receiver)
            continue

        if (at_all or receiver in at) and sender_name:
            at_users.append(u)
            continue

        # 找出最近绑定的token
        ts = max(u.apns_timestamp, u.xg_timestamp, u.mi_timestamp,
                 u.hw_timestamp, u.gcm_timestamp, u.ali_timestamp,
                 u.jp_timestamp)

        if u.apns_device_token and u.apns_timestamp == ts:
            apns_users.append(u)
        elif u.xg_device_token and u.xg_timestamp == ts:
            xg_users.append(u)
        elif u.mi_device_token and u.mi_timestamp == ts:
            mi_users.append(u)
        elif u.hw_device_token and u.hw_timestamp == ts:
            hw_users.append(u)
        elif u.gcm_device_token and u.gcm_timestamp == ts:
            gcm_users.append(u)
        elif u.ali_device_token and u.ali_timestamp == ts:
            ali_users.append(u)
        elif u.jp_device_token and u.jp_timestamp == ts:
            jp_users.append(u)
        else:
            logging.info("uid:%d has't device token", receiver)

    for u in at_users:
        content = "%s在群聊中@了你" % sender_name
        push_message_u(appid, appname, u, content, extra)

    for u in xg_users:
        xg_push(appid, appname, u.xg_device_token, content, extra)

    for u in hw_users:
        HuaWeiPush.push(appid, title, u.hw_device_token, content)

    gcm_device_tokens = [u.gcm_device_token for u in gcm_users]
    if gcm_device_tokens:
        FCMPush.push_batch(appid, title, gcm_device_tokens, content)

    for u in ali_users:
        AliPush.push(appid, appname, u.ali_device_token, content)

    # ios apns
    notifications = []
    for u in apns_users:
        sound = 'default'
        alert = PayloadAlert(title=group_name, body=content)
        payload = Payload(alert=alert,
                          sound=sound,
                          badge=u.unread + 1,
                          custom=extra)
        token = u.apns_device_token
        n = Notification(token, payload, None)
        notifications.append(n)

    if notifications:
        IOSPush.push_group_batch(appid, notifications, collapse_id)

    for u in apns_users:
        user.set_user_unread(rds, appid, receiver, u.unread + 1)

    # 极光推送
    #tokens = []
    #for u in jp_users:
    #    tokens.append(u.jp_device_token)
    #if tokens:
    #    JGPush.push(appid, appname, tokens, content)

    tokens = []
    for u in mi_users:
        tokens.append(u.mi_device_token)

    if tokens:
        MiPush.push_batch(appid, title, tokens, content)
Esempio n. 11
0
def handle_im_messages(msgs):
    msg_objs = []
    for msg in msgs:
        obj = json.loads(msg)
        if "appid" not in obj or \
           "sender" not in obj or \
           "receiver" not in obj:
            logging.warning("invalid push msg:%s", msg)
            continue

        msg_objs.append(obj)
        logging.debug("push msg:%s", msg)

    apns_users = []
    jp_users = []
    xg_users = []
    hw_users = []
    gcm_users = []
    mi_users = []
    ali_users = []

    for obj in msg_objs:
        appid = obj["appid"]
        sender = obj["sender"]
        receiver = obj["receiver"]

        appname = get_title(appid)
        sender_name = user.get_user_name(rds, appid, sender)

        do_not_disturb = Conversation.get_do_not_disturb(rds,
                                                         appid,
                                                         receiver,
                                                         peer_id=sender)
        if do_not_disturb:
            logging.debug("uid:%s do not disturb :%s", receiver, sender)
            continue

        u = user.get_user(rds, appid, receiver)
        if u is None:
            logging.info("uid:%d nonexist", receiver)
            continue

        content_obj = json.loads(obj['content'])
        if "readed" in content_obj or "tag" in content_obj:
            continue

        if content_obj.get('revoke'):
            collapse_id = content_obj.get('revoke').get('msgid')
            sender_name = sender_name if sender_name else ''
            content = "%s撤回了一条消息" % sender_name
        else:
            collapse_id = content_obj.get('uuid')
            content = push_content(sender_name, obj["content"])

        # 找出最近绑定的token
        ts = max(u.apns_timestamp, u.xg_timestamp, u.mi_timestamp,
                 u.hw_timestamp, u.gcm_timestamp, u.ali_timestamp,
                 u.jp_timestamp)

        if u.apns_device_token and u.apns_timestamp == ts:
            apns_users.append((u, appname, content, collapse_id))
        elif u.xg_device_token and u.xg_timestamp == ts:
            xg_users.append((u, appname, content, collapse_id))
        elif u.mi_device_token and u.mi_timestamp == ts:
            mi_users.append((u, appname, content, collapse_id))
        elif u.hw_device_token and u.hw_timestamp == ts:
            hw_users.append((u, appname, content, collapse_id))
        elif u.gcm_device_token and u.gcm_timestamp == ts:
            gcm_users.append((u, appname, content, collapse_id))
        elif u.ali_device_token and u.ali_timestamp == ts:
            ali_users.append((u, appname, content, collapse_id))
        elif u.jp_device_token and u.jp_timestamp == ts:
            jp_users.append((u, appname, content, collapse_id))
        else:
            logging.info("uid:%d has't device token", receiver)

    for u, appname, content, _ in xg_users:
        xg_push(u.appid, appname, u.xg_device_token, content, {})

    for u, appname, content, _ in hw_users:
        HuaWeiPush.push(u.appid, appname, u.hw_device_token, content)

    for u, appname, content, _ in gcm_users:
        FCMPush.push(u.appid, appname, u.gcm_device_token, content)

    for u, appname, content, _ in jp_users:
        JGPush.push(u.appid, appname, u.jp_device_token, content)

    for u, appname, content, _ in mi_users:
        MiPush.push(u.appid, appname, u.mi_device_token, content)

    # ios apns
    notifications = []
    for u, appname, content, collapse_id in apns_users:
        sound = 'default'
        payload = Payload(alert=content, sound=sound, badge=u.unread + 1)
        token = u.apns_device_token
        n = Notification(token, payload, collapse_id)
        notifications.append(n)

    if notifications:
        IOSPush.push_peer_batch(u.appid, notifications)

    for u, appname, content, collapse_id in apns_users:
        user.set_user_unread(rds, u.appid, u.uid, u.unread + 1)