Sync to maraid/fbchat
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
@@ -125,20 +125,12 @@ class Message:
|
||||
def react(self, reaction: Optional[str]):
|
||||
"""React to the message, or removes reaction.
|
||||
|
||||
Currently, you can use "❤", "😍", "😆", "😮", "😢", "😠", "👍" or "👎". It
|
||||
should be possible to add support for more, but we haven't figured that out yet.
|
||||
|
||||
Args:
|
||||
reaction: Reaction emoji to use, or if ``None``, removes reaction.
|
||||
|
||||
Example:
|
||||
>>> message.react("😍")
|
||||
"""
|
||||
if reaction and reaction not in SENDABLE_REACTIONS:
|
||||
raise ValueError(
|
||||
"Invalid reaction! Please use one of: {}".format(SENDABLE_REACTIONS)
|
||||
)
|
||||
|
||||
data = {
|
||||
"action": "ADD_REACTION" if reaction else "REMOVE_REACTION",
|
||||
"client_mutation_id": "1",
|
||||
|
@@ -16,8 +16,10 @@ from typing import Optional, Mapping, Callable, Any
|
||||
|
||||
|
||||
SERVER_JS_DEFINE_REGEX = re.compile(
|
||||
r'(?:"ServerJS".{,100}\.handle\({.*"define":)|(?:require\("ServerJSDefine"\)\)?\.handleDefines\()'
|
||||
)
|
||||
r'(?:"ServerJS".{,100}\.handle\({.*"define":)'
|
||||
r'|(?:ServerJS.{,100}\.handleWithCustomApplyEach\(ScheduledApplyEach,{.*"define":)'
|
||||
r'|(?:require\("ServerJSDefine"\)\)?\.handleDefines\()'
|
||||
r'|(?:"require":\[\["ScheduledServerJS".{,100}"define":)')
|
||||
SERVER_JS_DEFINE_JSON_DECODER = json.JSONDecoder()
|
||||
|
||||
|
||||
@@ -36,8 +38,6 @@ def parse_server_js_define(html: str) -> Mapping[str, Any]:
|
||||
raise _exception.ParseError("Could not find any ServerJSDefine", data=html)
|
||||
if len(define_splits) < 2:
|
||||
raise _exception.ParseError("Could not find enough ServerJSDefine", data=html)
|
||||
if len(define_splits) > 2:
|
||||
raise _exception.ParseError("Found too many ServerJSDefine", data=define_splits)
|
||||
# Parse entries (should be two)
|
||||
for entry in define_splits:
|
||||
try:
|
||||
@@ -311,6 +311,21 @@ class Session:
|
||||
data=data,
|
||||
allow_redirects=False,
|
||||
cookies=login_cookies(_util.now()),
|
||||
headers={
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36",
|
||||
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
|
||||
"accept-language": "en-HU,en;q=0.9,hu-HU;q=0.8,hu;q=0.7,en-US;q=0.6",
|
||||
"cache-control": "max-age=0",
|
||||
"origin": "https://www.messenger.com",
|
||||
"referer": "https://www.messenger.com/login/",
|
||||
"sec-ch-ua": '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
|
||||
"sec-ch-ua-mobile": "?0",
|
||||
"sec-fetch-dest": "document",
|
||||
"sec-fetch-mode": "navigate",
|
||||
"sec-fetch-site": "same-origin",
|
||||
"sec-fetch-user": "?1",
|
||||
"upgrade-insecure-requests": "1"
|
||||
}
|
||||
)
|
||||
except requests.RequestException as e:
|
||||
_exception.handle_requests_error(e)
|
||||
@@ -411,7 +426,7 @@ class Session:
|
||||
|
||||
# Make a request to the main page to retrieve ServerJSDefine entries
|
||||
try:
|
||||
r = session.get(prefix_url("/"), allow_redirects=False)
|
||||
r = session.get(prefix_url("/"), allow_redirects=True)
|
||||
except requests.RequestException as e:
|
||||
_exception.handle_requests_error(e)
|
||||
_exception.handle_http_error(r.status_code)
|
||||
@@ -532,3 +547,10 @@ class Session:
|
||||
return message_ids[0]
|
||||
except (KeyError, IndexError, TypeError) as e:
|
||||
raise _exception.ParseError("No message IDs could be found", data=j) from e
|
||||
|
||||
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"]
|
||||
|
@@ -105,6 +105,7 @@ class ThreadABC(metaclass=abc.ABCMeta):
|
||||
mentions: Iterable["_models.Mention"] = None,
|
||||
files: Iterable[Tuple[str, str]] = None,
|
||||
reply_to_id: str = None,
|
||||
uri: str = None
|
||||
) -> str:
|
||||
"""Send a message to the thread.
|
||||
|
||||
@@ -114,6 +115,7 @@ class ThreadABC(metaclass=abc.ABCMeta):
|
||||
files: Optional tuples, each containing an uploaded file's ID and mimetype.
|
||||
See `ThreadABC.send_files` for an example.
|
||||
reply_to_id: Optional message to reply to
|
||||
uri: Uri to formulate a sharable attachment with
|
||||
|
||||
Example:
|
||||
Send a message with a mention to a thread.
|
||||
@@ -139,6 +141,9 @@ class ThreadABC(metaclass=abc.ABCMeta):
|
||||
if files:
|
||||
data["has_attachment"] = True
|
||||
|
||||
if uri:
|
||||
data.update(self._generate_shareable_attachment(uri))
|
||||
|
||||
for i, (file_id, mimetype) in enumerate(files or ()):
|
||||
data["{}s[{}]".format(_util.mimetype_to_key(mimetype), i)] = file_id
|
||||
|
||||
@@ -236,6 +241,52 @@ class ThreadABC(metaclass=abc.ABCMeta):
|
||||
"""
|
||||
return self.send_text(text=None, files=files)
|
||||
|
||||
def send_uri(self, uri: str, **kwargs):
|
||||
"""Send a uri preview to a thread.
|
||||
Args:
|
||||
uri: uri to preview
|
||||
"""
|
||||
if kwargs.get('text') is None:
|
||||
kwargs['text'] = None
|
||||
self.send_text(uri=uri, **kwargs)
|
||||
|
||||
def _generate_shareable_attachment(self, uri):
|
||||
"""Send a uri preview to a thread.
|
||||
Args:
|
||||
uri: uri to preview
|
||||
Returns:
|
||||
:ref:`Message ID <intro_message_ids>` of the sent message
|
||||
Raises:
|
||||
FBchatException: If request failed
|
||||
"""
|
||||
url_data = self.session._uri_share_data({"uri": uri})
|
||||
data = self._to_send_data()
|
||||
data["action_type"] = "ma-type:user-generated-message"
|
||||
data["shareable_attachment[share_type]"] = url_data["share_type"]
|
||||
|
||||
# Most uri params will come back as dict
|
||||
if isinstance(url_data["share_params"], dict):
|
||||
data["has_attachment"] = True
|
||||
for key in url_data["share_params"]:
|
||||
if isinstance(url_data["share_params"][key], dict):
|
||||
for key2 in url_data["share_params"][key]:
|
||||
data[
|
||||
"shareable_attachment[share_params][{}][{}]".format(
|
||||
key, key2
|
||||
)
|
||||
] = url_data["share_params"][key][key2]
|
||||
else:
|
||||
data[
|
||||
"shareable_attachment[share_params][{}]".format(key)
|
||||
] = url_data["share_params"][key]
|
||||
|
||||
# Some (such as facebook profile pages) will just be a list
|
||||
else:
|
||||
data["has_attachment"] = False
|
||||
for index, val in enumerate(url_data["share_params"]):
|
||||
data["shareable_attachment[share_params][{}]".format(index)] = val
|
||||
return data
|
||||
|
||||
# xmd = {"quick_replies": []}
|
||||
# for quick_reply in quick_replies:
|
||||
# # TODO: Move this to `_quick_reply.py`
|
||||
|
Reference in New Issue
Block a user