From 199af2c352a3e0bc51873ddff7be0e78561211ff Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Fri, 11 Feb 2022 05:46:42 +0330 Subject: [PATCH 1/6] update Whatsapp Web version --- backend/whatsapp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/whatsapp.py b/backend/whatsapp.py index a7a7dfa..fc069f3 100755 --- a/backend/whatsapp.py +++ b/backend/whatsapp.py @@ -31,7 +31,7 @@ from utilities import *; from whatsapp_binary_reader import whatsappReadBinary; -WHATSAPP_WEB_VERSION="2,2121,6" +WHATSAPP_WEB_VERSION="2,2136,10" reload(sys); sys.setdefaultencoding("utf-8"); From 98d91ed3e8819ea88cb85daf90529eb53b18939e Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Fri, 11 Feb 2022 05:48:27 +0330 Subject: [PATCH 2/6] rename save_session func to saveSession --- backend/whatsapp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/whatsapp.py b/backend/whatsapp.py index fc069f3..b51ee77 100755 --- a/backend/whatsapp.py +++ b/backend/whatsapp.py @@ -209,7 +209,7 @@ def onMessage(self, ws, message): self.loginInfo["key"]["encKey"] = keysDecrypted[:32]; self.loginInfo["key"]["macKey"] = keysDecrypted[32:64]; - self.save_session(); + self.saveSession(); # eprint("private key : ", base64.b64encode(self.loginInfo["privateKey"].serialize())); # eprint("secret : ", base64.b64encode(self.connInfo["secret"])); # eprint("shared secret : ", base64.b64encode(self.connInfo["sharedSecret"])); @@ -276,7 +276,7 @@ def restoreSession(self, callback=None): "serverToken"] + '", "' + self.loginInfo["clientId"] + '", "takeover"]' self.activeWs.send(message) - def save_session(self): + def saveSession(self): session = {"clientToken":self.connInfo["clientToken"],"serverToken":self.connInfo["serverToken"], "clientId":self.loginInfo["clientId"],"macKey": self.loginInfo["key"]["macKey"].decode("latin_1") ,"encKey": self.loginInfo["key"]["encKey"].decode("latin_1")}; From 1aae2e8dd78217860dfab8c782e25e412ba9174c Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Fri, 11 Feb 2022 05:50:14 +0330 Subject: [PATCH 3/6] add sortedContacts func --- backend/whatsapp.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/backend/whatsapp.py b/backend/whatsapp.py index b51ee77..90f6923 100755 --- a/backend/whatsapp.py +++ b/backend/whatsapp.py @@ -181,6 +181,15 @@ def onMessage(self, ws, message): try: processedData = whatsappReadBinary(decryptedMessage, True); messageType = "binary"; + + # sort contacts obj{jid : name} + try: + if processedData[1]['type'] is "contacts": + messageType = "jsonContacts"; + processedData.append(self.sortedContacts(processedData)) + except: + pass + except: processedData = { "traceback": traceback.format_exc().splitlines() }; messageType = "error"; @@ -284,6 +293,13 @@ def saveSession(self): f.write(json.dumps(session)) f.close() + def sortedContacts(self,processedData): + contacts = {} + for contact in range(len(processedData[2])): + if 'name' in processedData[2][contact][1].keys() : + contacts[processedData[2][contact][1]['jid']] = processedData[2][contact][1]['name'] + return contacts + def getLoginInfo(self, callback): callback["func"]({ "type": "login_info", "data": self.loginInfo }, callback); From 3ff95e2e06e03f95300325450734a6b5e6fdfb88 Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Fri, 11 Feb 2022 05:52:08 +0330 Subject: [PATCH 4/6] add getStatuses func to retrive Statuses --- backend/whatsapp.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/backend/whatsapp.py b/backend/whatsapp.py index 90f6923..2418b66 100755 --- a/backend/whatsapp.py +++ b/backend/whatsapp.py @@ -200,6 +200,7 @@ def onMessage(self, ws, message): if isinstance(jsonObj, list) and len(jsonObj) > 0: # check if the result is an array eprint(json.dumps(jsonObj)); if jsonObj[0] == "Conn": + self.getStatuses(); # request for contacts statuses Timer(20.0, self.keepAlive).start() # Keepalive Request self.connInfo["clientToken"] = jsonObj[1]["clientToken"]; self.connInfo["serverToken"] = jsonObj[1]["serverToken"]; @@ -300,6 +301,18 @@ def sortedContacts(self,processedData): contacts[processedData[2][contact][1]['jid']] = processedData[2][contact][1]['name'] return contacts + def getStatuses(self): + messageId = "3EB0"+binascii.hexlify(Random.get_random_bytes(8)).upper() + encryptedMessage = WhatsAppEncrypt( + self.loginInfo["key"]["encKey"], + self.loginInfo["key"]["macKey"], + whatsappWriteBinary(["query", {"type": "status","jid":""}, None]) + ) + payload = bytearray(messageId) + bytearray(",") + bytearray( + to_bytes(WAMetrics.QUERY_MEDIA, 1) + ) + bytearray([0x80]) + encryptedMessage + self.activeWs.send(payload, websocket.ABNF.OPCODE_BINARY) + def getLoginInfo(self, callback): callback["func"]({ "type": "login_info", "data": self.loginInfo }, callback); From 246472ccd150df5c0da227ad88b1a5e551145612 Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Fri, 11 Feb 2022 05:53:55 +0330 Subject: [PATCH 5/6] add sortedStatuses func to fixed statuses json --- backend/whatsapp.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/backend/whatsapp.py b/backend/whatsapp.py index 2418b66..13622e1 100755 --- a/backend/whatsapp.py +++ b/backend/whatsapp.py @@ -189,7 +189,14 @@ def onMessage(self, ws, message): processedData.append(self.sortedContacts(processedData)) except: pass - + # sort statuses + try: + if processedData[2][0][0] is "status": + processedData[2] = self.sortedStatuses(processedData) + messageType = "jsonStatuses"; + except: + pass + except: processedData = { "traceback": traceback.format_exc().splitlines() }; messageType = "error"; @@ -312,6 +319,23 @@ def getStatuses(self): to_bytes(WAMetrics.QUERY_MEDIA, 1) ) + bytearray([0x80]) + encryptedMessage self.activeWs.send(payload, websocket.ABNF.OPCODE_BINARY) + + def sortedStatuses(self,processedData): + entries = {} + bad = [] + for user in range(len(processedData[2])): + jid = processedData[2][user][1]['jid'] + for story in range(len(processedData[2][user][2])): + if processedData[2][user][2][story][0] == "picture" : + bad.append(story) + continue + decoded_msgs = WAWebMessageInfo.decode(processedData[2][user][2][story][2]) + processedData[2][user][2][story] = decoded_msgs['message'] + entries[jid] = processedData[2][user][2] + for b in bad: + del entries[jid][b] + return entries + def getLoginInfo(self, callback): callback["func"]({ "type": "login_info", "data": self.loginInfo }, callback); From ae577d83dc37e4206d673d2ff335562c14a4974d Mon Sep 17 00:00:00 2001 From: hossinasaadi Date: Fri, 11 Feb 2022 18:17:43 +0330 Subject: [PATCH 6/6] run getStatuses in both login and restore session --- backend/whatsapp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/whatsapp.py b/backend/whatsapp.py index 13622e1..5edb56f 100755 --- a/backend/whatsapp.py +++ b/backend/whatsapp.py @@ -207,7 +207,6 @@ def onMessage(self, ws, message): if isinstance(jsonObj, list) and len(jsonObj) > 0: # check if the result is an array eprint(json.dumps(jsonObj)); if jsonObj[0] == "Conn": - self.getStatuses(); # request for contacts statuses Timer(20.0, self.keepAlive).start() # Keepalive Request self.connInfo["clientToken"] = jsonObj[1]["clientToken"]; self.connInfo["serverToken"] = jsonObj[1]["serverToken"]; @@ -246,6 +245,7 @@ def onMessage(self, ws, message): eprint(json.dumps( [messageTag,["admin","challenge",challenge,self.connInfo["serverToken"],self.loginInfo["clientId"]]])) self.activeWs.send(json.dumps( [messageTag,["admin","challenge",challenge,self.connInfo["serverToken"],self.loginInfo["clientId"]]])); elif jsonObj[0] == "Stream": + self.getStatuses(); # request for contacts statuses pass; elif jsonObj[0] == "Props": pass;