From c5b81183f094b9a65688aa46462ace25157197f0 Mon Sep 17 00:00:00 2001 From: gitCommitWiL <43019766+gitCommitWiL@users.noreply.github.com> Date: Mon, 6 Apr 2020 11:06:36 -0400 Subject: [PATCH 1/4] Added way to send url previews sendUri(link, message) will send the preview for link below the message in chat --- fbchat/_client.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ fbchat/_state.py | 7 +++++++ 2 files changed, 53 insertions(+) diff --git a/fbchat/_client.py b/fbchat/_client.py index fc856058..b63dc19c 100644 --- a/fbchat/_client.py +++ b/fbchat/_client.py @@ -1066,6 +1066,52 @@ def sendMessage(self, message, thread_id=None, thread_type=ThreadType.USER): Message(text=message), thread_id=thread_id, thread_type=thread_type ) + def sendUri(self, uri, message=None, thread_id=None, thread_type=ThreadType.USER): + """Send a uri preview to a thread. + + Args: + uri: uri to preview + message (Message): Message to send + thread_id: User/Group ID to send to. See :ref:`intro_threads` + thread_type (ThreadType): See :ref:`intro_threads` + + Returns: + :ref:`Message ID ` of the sent message + + Raises: + FBchatException: If request failed + """ + + urlData = self._state._uri_share_data({"uri": uri}) + thread_id, thread_type = self._getThread(thread_id, thread_type) + thread = thread_type._to_class()(thread_id) + data = thread._to_send_data() + if message is not None: + data.update(message._to_send_data()) + data["action_type"] = "ma-type:user-generated-message" + data["shareable_attachment[share_type]"] = urlData["share_type"] + # most uri params will come back as dict + if isinstance(urlData["share_params"], dict): + data["has_attachment"] = True + for key in urlData["share_params"]: + if isinstance(urlData["share_params"][key], dict): + for key2 in urlData["share_params"][key]: + data[ + "shareable_attachment[share_params][{}][{}]".format( + key, key2 + ) + ] = urlData["share_params"][key][key2] + else: + data[ + "shareable_attachment[share_params][{}]".format(key) + ] = urlData["share_params"][key] + # some (such as facebook profile pages) will just be a list + else: + data["has_attachment"] = False + for index, val in enumerate(urlData["share_params"]): + data["shareable_attachment[share_params][{}]".format(index)] = val + return self._doSendRequest(data) + def sendEmoji( self, emoji=None, diff --git a/fbchat/_state.py b/fbchat/_state.py index a20e4f23..2bd95d90 100644 --- a/fbchat/_state.py +++ b/fbchat/_state.py @@ -329,3 +329,10 @@ def _do_send_request(self, data): "Error when sending message: " "No message IDs could be found: {}".format(j) ) + + def _uri_share_data(self, data): + data["image_height"] = 960 + data["image_width"] = 960 + data["__user"] = self.user_id + j = self._post("/message_share_attachment/fromURI/", data) + return j["payload"]["share_data"] From 2f6e08dc6f2448c63a8b16995d55a16a4aa9df40 Mon Sep 17 00:00:00 2001 From: gitCommitWiL <43019766+gitCommitWiL@users.noreply.github.com> Date: Thu, 5 Nov 2020 20:04:39 -0500 Subject: [PATCH 2/4] updated _state.py so that can login changed regex --- fbchat/_state.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fbchat/_state.py b/fbchat/_state.py index 34ed3d41..64295f91 100644 --- a/fbchat/_state.py +++ b/fbchat/_state.py @@ -9,7 +9,7 @@ from . import _graphql, _util, _exception -FB_DTSG_REGEX = re.compile(r'name="fb_dtsg" value="(.*?)"') +FB_DTSG_REGEX = re.compile(r'"fb_dtsg","value":"(.*?)"') def get_user_id(session): From c5813ce3d503cb8ed683822f7ad5892bf06aae35 Mon Sep 17 00:00:00 2001 From: gitCommitWiL <43019766+gitCommitWiL@users.noreply.github.com> Date: Wed, 17 Mar 2021 01:32:12 -0400 Subject: [PATCH 3/4] fix login issue --- fbchat/_state.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fbchat/_state.py b/fbchat/_state.py index 64295f91..a1383f76 100644 --- a/fbchat/_state.py +++ b/fbchat/_state.py @@ -9,7 +9,7 @@ from . import _graphql, _util, _exception -FB_DTSG_REGEX = re.compile(r'"fb_dtsg","value":"(.*?)"') +FB_DTSG_REGEX = re.compile(r'"token":"(.*?)"') def get_user_id(session): @@ -138,6 +138,13 @@ def login(cls, email, password, on_2fa_callback, user_agent=None): r = session.post("https://m.facebook.com/login.php?login_attempt=1", data=data) + if "cookie" in r.url: + beg = r.text.find("action=") + 8 + end = r.text.find("\"", beg) + urlCookies = "https://m.facebook.com" + r.text[beg:end] + payload = {i["name"]: i["value"] for i in find_input_fields(r.text).find_all('input')} + r = session.post(urlCookies, data=payload) + # Usually, 'Checkpoint' will refer to 2FA if "checkpoint" in r.url and ('id="approvals_code"' in r.text.lower()): code = on_2fa_callback() @@ -187,7 +194,7 @@ def from_session(cls, session): # Fall back to searching with a regex fb_dtsg = FB_DTSG_REGEX.search(r.text).group(1) - revision = int(r.text.split('"client_revision":', 1)[1].split(",", 1)[0]) + revision = 1 logout_h_element = soup.find("input", {"name": "h"}) logout_h = logout_h_element["value"] if logout_h_element else None From ac9b18ad3d0757b4879a26ed6a5f472c397c8bef Mon Sep 17 00:00:00 2001 From: gitCommitWiL <43019766+gitCommitWiL@users.noreply.github.com> Date: Wed, 17 Mar 2021 02:16:13 -0400 Subject: [PATCH 4/4] updated save-device url --- fbchat/_state.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fbchat/_state.py b/fbchat/_state.py index a1383f76..3e705c89 100644 --- a/fbchat/_state.py +++ b/fbchat/_state.py @@ -151,7 +151,8 @@ def login(cls, email, password, on_2fa_callback, user_agent=None): r = _2fa_helper(session, code, r) # Sometimes Facebook tries to show the user a "Save Device" dialog - if "save-device" in r.url: + # was getting a different url for 'same device' page; not sure if this applies to everyone + if "checkpoint" in r.url: r = session.get("https://m.facebook.com/login/save-device/cancel/") if is_home(r.url):