diff --git a/matrix_client/client.py b/matrix_client/client.py index af0e08f6..466cc427 100644 --- a/matrix_client/client.py +++ b/matrix_client/client.py @@ -583,60 +583,68 @@ def _sync(self, timeout_ms=30000): response = self.api.sync(self.sync_token, timeout_ms, filter=self.sync_filter) self.sync_token = response["next_batch"] - for presence_update in response['presence']['events']: - for callback in self.presence_listeners.values(): - callback(presence_update) - - for room_id, invite_room in response['rooms']['invite'].items(): - for listener in self.invite_listeners: - listener(room_id, invite_room['invite_state']) - - for room_id, left_room in response['rooms']['leave'].items(): - for listener in self.left_listeners: - listener(room_id, left_room) - if room_id in self.rooms: - del self.rooms[room_id] + if 'presence' in response and 'events' in response['presence']: + for presence_update in response['presence']['events']: + for callback in self.presence_listeners.values(): + callback(presence_update) if self._encryption and 'device_one_time_keys_count' in response: self.olm_device.update_one_time_key_counts( response['device_one_time_keys_count']) - for room_id, sync_room in response['rooms']['join'].items(): - if room_id not in self.rooms: - self._mkroom(room_id) - room = self.rooms[room_id] - # TODO: the rest of this for loop should be in room object method - room.prev_batch = sync_room["timeline"]["prev_batch"] - - for event in sync_room["state"]["events"]: - event['room_id'] = room_id - room._process_state_event(event) - - for event in sync_room["timeline"]["events"]: - event['room_id'] = room_id - room._put_event(event) - - # TODO: global listeners can still exist but work by each - # room.listeners[uuid] having reference to global listener - - # Dispatch for client (global) listeners - for listener in self.listeners: - if ( - listener['event_type'] is None or - listener['event_type'] == event['type'] - ): - listener['callback'](event) - - for event in sync_room['ephemeral']['events']: - event['room_id'] = room_id - room._put_ephemeral_event(event) - - for listener in self.ephemeral_listeners: - if ( - listener['event_type'] is None or - listener['event_type'] == event['type'] - ): - listener['callback'](event) + rooms = response.get("rooms", {}) + if 'invite' in rooms: + for room_id, invite_room in rooms['invite'].items(): + for listener in self.invite_listeners: + listener(room_id, invite_room['invite_state']) + + if 'leave' in rooms: + for room_id, left_room in rooms['leave'].items(): + for listener in self.left_listeners: + listener(room_id, left_room) + if room_id in self.rooms: + del self.rooms[room_id] + + if 'join' in rooms: + for room_id, sync_room in rooms['join'].items(): + if room_id not in self.rooms: + self._mkroom(room_id) + room = self.rooms[room_id] + # TODO: the rest of this for loop should be in room object method + room.prev_batch = sync_room["timeline"]["prev_batch"] + + if "state" in sync_room and "events" in sync_room["state"]: + for event in sync_room["state"]["events"]: + event['room_id'] = room_id + room._process_state_event(event) + + if "timeline" in sync_room and "events" in sync_room["timeline"]: + for event in sync_room["timeline"]["events"]: + event['room_id'] = room_id + room._put_event(event) + + # TODO: global listeners can still exist but work by each + # room.listeners[uuid] having reference to global listener + + # Dispatch for client (global) listeners + for listener in self.listeners: + if ( + listener['event_type'] is None or + listener['event_type'] == event['type'] + ): + listener['callback'](event) + + if "ephemeral" in sync_room and "events" in sync_room["ephemeral"]: + for event in sync_room['ephemeral']['events']: + event['room_id'] = room_id + room._put_ephemeral_event(event) + + for listener in self.ephemeral_listeners: + if ( + listener['event_type'] is None or + listener['event_type'] == event['type'] + ): + listener['callback'](event) def get_user(self, user_id): """Deprecated. Return a User by their id.