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()})
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]
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))
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})
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)
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())
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())
from models.conversation import Conversation list_conversation = [ Conversation(userone_id=1, usertwo_id=2), Conversation(userone_id=1, usertwo_id=3), ]
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)
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)