diff --git a/fbchat/_mqtt.py b/fbchat/_mqtt.py index f01d6d2..c17d110 100644 --- a/fbchat/_mqtt.py +++ b/fbchat/_mqtt.py @@ -4,6 +4,24 @@ import paho.mqtt.client from . import _util, _graphql +def fetch_sequence_id(state): + """Fetch sequence ID.""" + params = { + "limit": 1, + "tags": ["INBOX"], + "before": None, + "includeDeliveryReceipts": False, + "includeSeqID": True, + } + # Same request as in `Client.fetchThreadList` + (j,) = state._graphql_requests(_graphql.from_doc_id("1349387578499440", params)) + try: + return int(j["viewer"]["message_threads"]["sync_sequence_id"]) + except (KeyError, ValueError): + # TODO: Proper exceptions + raise + + @attr.s(slots=True) class Mqtt: _state = attr.ib() @@ -21,6 +39,17 @@ class Mqtt: # Generate a random session ID between 1 and 9007199254740991 session_id = random.randint(1, 2 ** 53) + last_seq_id = fetch_sequence_id(state) + + messenger_sync_create_queue_payload = { + "sync_api_version": 10, + "max_deltas_able_to_process": 1000, + "delta_batch_size": 500, + "encoding": "JSON", + "entity_fbid": state.user_id, + "initial_titan_sequence_id": str(last_seq_id), + "device_params": None, + } username = { # The user ID @@ -62,7 +91,20 @@ class Mqtt: "/sr_res", ], # MQTT extension by FB, allows making a PUBLISH while CONNECTing - "pm": [], + "pm": [ + # This is required to actually receive messages + { + "topic": "/messenger_sync_create_queue", + "payload": _util.json_minimal(messenger_sync_create_queue_payload), + "qos": 1, + "messageId": 65536, + } + # The above is more efficient, but the same effect could have been + # acheived with: + # def on_connect(*args): + # mqtt.publish("/messenger_sync_create_queue", ..., qos=1) + # mqtt.on_connect = on_connect + ], # Unknown parameters "cp": 3, "ecp": 10,