diff --git a/fbchat/client.py b/fbchat/client.py index 110653b..6487eca 100644 --- a/fbchat/client.py +++ b/fbchat/client.py @@ -513,6 +513,7 @@ class Client(object): return [graphql_to_page(node) for node in j[name]['pages']['nodes']] + # TODO intergrate Rooms def searchForGroups(self, name, limit=1): """ Find and get group thread by its name @@ -553,6 +554,7 @@ class Client(object): elif node['__typename'] == 'Group': # We don't handle Facebook "Groups" pass + # TODO Add Rooms else: log.warning('Unknown __typename: {} in {}'.format(repr(node['__typename']), node)) @@ -707,6 +709,9 @@ class Client(object): if entry.get('thread_type') == 'GROUP': _id = entry['thread_key']['thread_fbid'] rtn[_id] = graphql_to_group(entry) + elif entry.get('thread_type') == 'ROOM': + _id = entry['thread_key']['thread_fbid'] + rtn[_id] = graphql_to_room(entry) elif entry.get('thread_type') == 'ONE_TO_ONE': _id = entry['thread_key']['other_user_id'] if pages_and_users.get(_id) is None: @@ -799,6 +804,18 @@ class Client(object): entries.append(participants[k['other_user_fbid']]) elif k['thread_type'] == 2: entries.append(Group(k['thread_fbid'], participants=set([p.strip('fbid:') for p in k['participants']]), photo=k['image_src'], name=k['name'], message_count=k['message_count'])) + elif k['thread_type'] == 3: + entries.append(Room( + k['thread_fbid'], + participants = set(p.lstrip('fbid:') for p in k['participants']), + photo = k['image_src'], + name = k['name'], + message_count = k['message_count'], + admins = set(p.lstrip('fbid:') for p in k['admin_ids']), + approval_mode = k['approval_mode'], + approval_requests = set(p.lstrip('fbid:') for p in k['approval_queue_ids']), + join_link = k['joinable_mode']['link'] + )) else: raise FBchatException('A thread had an unknown thread type: {}'.format(k)) diff --git a/fbchat/graphql.py b/fbchat/graphql.py index 857d19e..08150c6 100644 --- a/fbchat/graphql.py +++ b/fbchat/graphql.py @@ -42,7 +42,7 @@ def get_customization_info(thread): 'emoji': info.get('emoji'), 'color': graphql_color_to_enum(info.get('outgoing_bubble_color')) } - if thread.get('thread_type') == 'GROUP' or thread.get('is_group_thread') or thread.get('thread_key', {}).get('thread_fbid'): + if thread.get('thread_type') in ('GROUP', 'ROOM') or thread.get('is_group_thread') or thread.get('thread_key', {}).get('thread_fbid'): rtn['nicknames'] = {} for k in info.get('participant_customizations', []): rtn['nicknames'][k['participant_id']] = k.get('nickname') @@ -118,6 +118,26 @@ def graphql_to_group(group): message_count=group.get('messages_count') ) +def graphql_to_room(room): + if room.get('image') is None: + room['image'] = {} + c_info = get_customization_info(room) + return Room( + room['thread_key']['thread_fbid'], + participants=set([node['messaging_actor']['id'] for node in room['all_participants']['nodes']]), + nicknames=c_info.get('nicknames'), + color=c_info.get('color'), + emoji=c_info.get('emoji'), + photo=room['image'].get('uri'), + name=room.get('name'), + message_count=room.get('messages_count'), + admins = set([node.get('id') for node in room.get('thread_admins')]), + approval_mode = bool(room.get('approval_mode')), + approval_requests = set(node.get('id') for node in room['thread_queue_metadata'].get('approval_requests', {}).get('nodes')), + join_link = room['joinable_mode'].get('link'), + privacy_mode = bool(room.get('privacy_mode')), + ) + def graphql_to_page(page): if page.get('profile_picture') is None: page['profile_picture'] = {} diff --git a/fbchat/models.py b/fbchat/models.py index 4894cd2..fe289b7 100644 --- a/fbchat/models.py +++ b/fbchat/models.py @@ -109,6 +109,33 @@ class Group(Thread): self.emoji = emoji +class Room(Group): + # Set containing user IDs of thread admins + admins = set + # True if users need approval to join + approval_mode = bool + # Set containing user IDs requesting to join + approval_requests = set + # Link for joining room + join_link = str + # True is room is not discoverable + privacy_mode = bool + + def __init__(self, uid, admins=None, approval_mode=None, approval_requests=None, join_link=None, privacy_mode=None, **kwargs): + """Represents a Facebook room. Inherits `Group`""" + super(Room, self).__init__(uid, **kwargs) + self.type = ThreadType.ROOM + if admins is None: + admins = set() + self.admins = admins + self.approval_mode = approval_mode + if approval_requests is None: + approval_requests = set() + self.approval_requests = approval_requests + self.join_link = join_link + self.privacy_mode = privacy_mode + + class Page(Thread): #: The page's custom url url = str @@ -192,6 +219,7 @@ class ThreadType(Enum): USER = 1 GROUP = 2 PAGE = 3 + ROOM = 4 class ThreadLocation(Enum): """Used to specify where a thread is located (inbox, pending, archived, other)."""