proper implementation of new message, color, emoji, title, nick change

This commit is contained in:
Dainius
2017-05-08 16:05:14 +03:00
parent 1700f95810
commit 2721004777
2 changed files with 99 additions and 66 deletions

View File

@@ -75,8 +75,6 @@ class Client(object):
import fbchat import fbchat
chat = fbchat.Client(email, password) chat = fbchat.Client(email, password)
""" """
if do_login and not (email and password):
raise Exception("Email and password not found.")
self.is_def_recipient_set = False self.is_def_recipient_set = False
self.debug = debug self.debug = debug
@@ -105,34 +103,48 @@ class Client(object):
# Setup event hooks # Setup event hooks
self.onLoggingIn = EventHook() self.onLoggingIn = EventHook()
self.onLoggedIn = EventHook() self.onLoggedIn = EventHook()
self.onListening = EventHook()
self.onMessage = EventHook(mid=str, author_id=str, message=str, recipient_id=int, msg_type=MsgType, ts=str, metadata=dict) self.onMessage = EventHook(mid=str, author_id=str, message=str, thread_id=int, thread_type=ThreadType, ts=str, metadata=dict)
self.onColorChange = EventHook(mid=str, author_id=str, new_color=str, changed_for=str, msg_type=MsgType, ts=str) self.onColorChange = EventHook(mid=str, author_id=str, new_color=str, thread_id=str, thread_type=ThreadType, ts=str, metadata=dict)
self.onTitleChange = EventHook(mid=str, author_id=str, new_title=str, changed_for=str, thread_id=str, ts=str) self.onEmojiChange = EventHook(mid=str, author_id=str, new_emoji=str, thread_id=str, thread_type=ThreadType, ts=str, metadata=dict)
self.onTyping = EventHook(author_id=int, typing_status=TypingStatus) self.onTitleChange = EventHook(mid=str, author_id=str, new_title=str, thread_id=str, thread_type=ThreadType, ts=str, metadata=dict)
self.onSeen = EventHook(seen_by=str, thread_id=str, timestamp=str) self.onNicknameChange = EventHook(mid=str, author_id=str, changed_for=str, new_title=str, thread_id=str, thread_type=ThreadType, ts=str, metadata=dict)
# self.onTyping = EventHook(author_id=int, typing_status=TypingStatus)
# self.onSeen = EventHook(seen_by=str, thread_id=str, timestamp=str)
self.onInbox = EventHook(unseen=int, unread=int, recent_unread=int) self.onInbox = EventHook(unseen=int, unread=int, recent_unread=int)
self.onPeopleAdded = EventHook(added_ids=list, author_id=str, thread_id=str) self.onPeopleAdded = EventHook(added_ids=list, author_id=str, thread_id=str)
self.onPersonRemoved = EventHook(removed_id=str, author_id=str, thread_id=str) self.onPersonRemoved = EventHook(removed_id=str, author_id=str, thread_id=str)
self.onFriendRequest = EventHook(from_id=str) self.onFriendRequest = EventHook(from_id=str)
self.onUnknownMesssageType = EventHook(msg=dict)
# Setup event handlers # Setup event handlers
self.onLoggingIn += lambda: log.info("Logging in...") self.onLoggingIn += lambda: log.info("Logging in...")
self.onLoggedIn += lambda: log.info("Login successful.") self.onLoggedIn += lambda: log.info("Login successful.")
self.onListening += lambda: log.info("Listening...") self.onListening += lambda: log.info("Listening...")
self.onMessage += lambda mid, author_id, message, recipient_id, msg_type, ts, metadata:\ self.onMessage += lambda mid, author_id, message, thread_id, thread_type, ts, metadata:\
log.info("Message from %s: %s" % (author_id, message)) log.info("Message from %s in %s (%s): %s" % (author_id, thread_id, thread_type.name, message))
self.onColorChange += lambda mid, author_id, new_color, changed_for, msg_type, ts:\
log.info("%s changed color to %s" % (author_id, new_color)) self.onColorChange += lambda mid, author_id, new_color, thread_id, thread_type, ts, metadata:\
self.onTitleChange += lambda mid, author_id, new_title, changed_for, thread_id, ts:\ log.info("Color change from %s in %s (%s): %s" % (author_id, thread_id, thread_type.name, new_color))
log.info("%s changed title of %s to %s" % (author_id, changed_for, new_title)) self.onEmojiChange += lambda mid, author_id, new_emoji, thread_id, thread_type, ts, metadata:\
log.info("Emoji change from %s in %s (%s): %s" % (author_id, thread_id, thread_type.name, new_emoji))
self.onTitleChange += lambda mid, author_id, new_title, thread_id, thread_type, ts, metadata:\
log.info("Title change from %s in %s (%s): %s" % (author_id, thread_id, thread_type.name, new_title))
self.onNicknameChange += lambda mid, author_id, new_title, changed_for, thread_id, thread_type, ts, metadata:\
log.info("Nickname change from %s in %s (%s) for %s: %s" % (author_id, thread_id, thread_type.name, changed_for, new_title))
self.onPeopleAdded += lambda added_ids, author_id, thread_id:\ self.onPeopleAdded += lambda added_ids, author_id, thread_id:\
log.info("%s added: %s" % (author_id, [x for x in added_ids])) log.info("%s added: %s" % (author_id, [x for x in added_ids]))
self.onPersonRemoved += lambda removed_id, author_id, thread_id:\ self.onPersonRemoved += lambda removed_id, author_id, thread_id:\
log.info("%s removed: %s" % (author_id, removed_id)) log.info("%s removed: %s" % (author_id, removed_id))
self.onUnknownMesssageType += lambda msg:\
log.info("Unknown message type received: %s" % msg)
if not user_agent: if not user_agent:
user_agent = choice(USER_AGENTS) user_agent = choice(USER_AGENTS)
@@ -777,77 +789,96 @@ class Client(object):
# Things that directly change chat # Things that directly change chat
if mtype == "delta": if mtype == "delta":
def getRecipientIdAndMsgType(msg_metadata): def getThreadIdAndThreadType(msg_metadata):
"""Returns a tuple consisting of recipient id and message type""" """Returns a tuple consisting of thread id and thread type"""
recipient = None id_thread = None
message_type = None type_thread = None
if 'threadFbId' in msg_metadata['threadKey']: if 'threadFbId' in msg_metadata['threadKey']:
recipient = msg_metadata['threadKey']['threadFbId'] id_thread = str(msg_metadata['threadKey']['threadFbId'])
message_type = MsgType.GROUP type_thread = ThreadType.GROUP
elif 'otherUserFbId' in msg_metadata['threadKey']: elif 'otherUserFbId' in msg_metadata['threadKey']:
recipient = msg_metadata['threadKey']['otherUserFbId'] id_thread = str(msg_metadata['threadKey']['otherUserFbId'])
message_type = MsgType.USER type_thread = ThreadType.USER
return recipient, message_type return id_thread, type_thread
delta = m["delta"] delta = m["delta"]
delta_type = delta.get("type") delta_type = delta.get("type")
metadata = delta.get("messageMetadata") metadata = delta.get("messageMetadata")
if metadata is not None:
mid = metadata["messageId"]
author_id = str(metadata['actorFbId'])
ts = int(metadata["timestamp"])
# Added participants # Added participants
if 'addedParticipants' in delta: if 'addedParticipants' in delta:
added_ids = [x['userFbId'] for x in delta['addedParticipants']] added_ids = [str(x['userFbId']) for x in delta['addedParticipants']]
author_id = metadata['actorFbId'] thread_id = str(metadata['threadKey']['threadFbId'])
thread_id = metadata['threadKey']['threadFbId'] self.onPeopleAdded(mid=mid, added_ids=added_ids, author_id=author_id, thread_id=thread_id, ts=ts)
ts = metadata["timestamp"] continue
self.onPeopleAdded(added_ids=added_ids, author_id=author_id, thread_id=thread_id, ts=ts)
# Left/removed participants # Left/removed participants
elif 'leftParticipantFbId' in delta: elif 'leftParticipantFbId' in delta:
removed_id = delta['leftParticipantFbId'] removed_id = str(delta['leftParticipantFbId'])
author_id = metadata['actorFbId'] thread_id = str(metadata['threadKey']['threadFbId'])
thread_id = metadata['threadKey']['threadFbId'] self.onPersonRemoved(mid=mid, removed_id=removed_id, author_id=author_id, thread_id=thread_id, ts=ts)
ts = metadata["timestamp"] continue
self.onPersonRemoved(removed_id=removed_id, author_id=author_id, thread_id=thread_id, ts=ts)
# Seen
elif delta.get("class") == "ReadReceipt":
seen_by = delta["actorFbId"] or delta["threadKey"]["otherUserFbId"]
thread_id = delta["threadKey"].get("threadFbId")
timestamp = delta["actionTimestampMs"]
self.onSeen(seen_by=seen_by, thread_id=thread_id, timestamp=timestamp)
# Color change # Color change
elif delta_type == "change_thread_theme": elif delta_type == "change_thread_theme":
mid = metadata["messageId"]
author_id = metadata["actorFbId"]
new_color = delta["untypedData"]["theme_color"] new_color = delta["untypedData"]["theme_color"]
changed_for, msg_type = getRecipientIdAndMsgType(metadata) thread_id, thread_type = getThreadIdAndThreadType(metadata)
ts = metadata["timestamp"] self.onColorChange(mid=mid, author_id=author_id, new_color=new_color, thread_id=thread_id,
self.onColorChange(mid=mid, author_id=author_id, new_color=new_color, changed_for=changed_for, thread_type=thread_type, ts=ts, metadata=metadata)
msg_type=msg_type, ts=ts) continue
# Title change # Emoji change
elif delta_type == "change_thread_icon":
new_emoji = delta["untypedData"]["thread_icon"]
thread_id, thread_type = getThreadIdAndThreadType(metadata)
self.onEmojiChange(mid=mid, author_id=author_id, new_emoji=new_emoji, thread_id=thread_id,
thread_type=thread_type, ts=ts, metadata=metadata)
continue
# Thread title change
elif delta.get("class") == "ThreadName":
new_title = delta["name"]
thread_id, thread_type = getThreadIdAndThreadType(metadata)
self.onTitleChange(mid=mid, author_id=author_id, new_title=new_title, thread_id=thread_id,
thread_type=thread_type, ts=ts, metadata=metadata)
continue
# Nickname change
elif delta_type == "change_thread_nickname": elif delta_type == "change_thread_nickname":
mid = metadata["messageId"] changed_for = str(delta["untypedData"]["participant_id"])
author_id = metadata["actorFbId"] new_title = delta["untypedData"]["nickname"]
changed_for = delta["untypedData"]["participant_id"] thread_id, thread_type = getThreadIdAndThreadType(metadata)
new_title = delta["untypedData"]["nickanme"] self.onNicknameChange(mid=mid, author_id=author_id, changed_for=changed_for, new_title=new_title,
thread_id = metadata["threadKey"].get("threadFbId") thread_id=thread_id, thread_type=thread_type, ts=ts, metadata=metadata)
ts = metadata["timestamp"] continue
self.onTitleChange(mid=mid, author_id=author_id, changed_for=changed_for, new_title=new_title,
thread_id=thread_id, ts=ts)
# TODO properly implement these as they differ on different scenarios
# Seen
# elif delta.get("class") == "ReadReceipt":
# seen_by = delta["actorFbId"] or delta["threadKey"]["otherUserFbId"]
# thread_id = delta["threadKey"].get("threadFbId")
# self.onSeen(seen_by=seen_by, thread_id=thread_id, ts=ts)
#
# # Message delivered
# elif delta.get("class") == 'DeliveryReceipt':
# time_delivered = delta['deliveredWatermarkTimestampMs']
# self.onDelivered()
# New message # New message
elif "messageMetadata" in delta: elif delta.get("class") == "NewMessage":
mid = metadata['messageId']
message = delta.get('body', '') message = delta.get('body', '')
author_id = metadata['actorFbId'] thread_id, thread_type = getThreadIdAndThreadType(metadata)
recipient_id, msg_type = getRecipientIdAndMsgType(metadata)
ts = metadata["timestamp"]
self.onMessage(mid=mid, author_id=author_id, message=message, self.onMessage(mid=mid, author_id=author_id, message=message,
recipient_id=recipient_id, msg_type=msg_type, ts=ts, metadata=m) thread_id=thread_id, thread_type=thread_type, ts=ts, metadata=m)
continue
# Inbox
if mtype == "inbox": if mtype == "inbox":
self.onInbox(unseen=m["unseen"], unread=m["unread"], recent_unread=m["recent_unread"]) self.onInbox(unseen=m["unseen"], unread=m["unread"], recent_unread=m["recent_unread"])
@@ -858,9 +889,9 @@ class Client(object):
# self.onTyping(author_id=author_id, typing_status=typing_status) # self.onTyping(author_id=author_id, typing_status=typing_status)
# Seen # Seen
elif mtype == "m_read_receipt": # elif mtype == "m_read_receipt":
#
self.onSeen(m.get('realtime_viewer_fbid'), m.get('reader'), m.get('time')) # self.onSeen(m.get('realtime_viewer_fbid'), m.get('reader'), m.get('time'))
# elif mtype in ['jewel_requests_add']: # elif mtype in ['jewel_requests_add']:
# from_id = m['from'] # from_id = m['from']
@@ -874,8 +905,10 @@ class Client(object):
elif mtype == "deltaflow": elif mtype == "deltaflow":
pass pass
# Unknown message type
else: else:
log.debug("Unknown type %s" % m) self.onUnknownMesssageType(msg=m)
except Exception as e: except Exception as e:
log.debug(str(e)) log.debug(str(e))

View File

@@ -70,7 +70,7 @@ class Message():
self.__dict__.update(entries) self.__dict__.update(entries)
class MsgType(Enum): class ThreadType(Enum):
USER = 1 USER = 1
GROUP = 2 GROUP = 2