Add forwarding attachments (#420)
- Add ability to forward attachments and `Message.forwarded` attribute - Improve error handling for a lot of client methods, including, but not limited to: - `fetchAllUsers` - `searchForMessageIDs` - `search` - `fetchThreadInfo` and siblings - `fetchUnread` - `fetchUnseen` - `fetchPollOptions` - `fetchPlanInfo` - `send` and siblings - File uploads
This commit is contained in:
committed by
Mads Marquart
parent
61502ed32a
commit
70faa86e34
@@ -1707,6 +1707,23 @@ class Client(object):
|
||||
thread_type=thread_type,
|
||||
)
|
||||
|
||||
def forwardAttachment(self, attachment_id, thread_id=None):
|
||||
"""
|
||||
Forwards an attachment
|
||||
|
||||
:param attachment_id: Attachment ID to forward
|
||||
:param thread_id: User/Group ID to send to. See :ref:`intro_threads`
|
||||
:raises: FBchatException if request failed
|
||||
"""
|
||||
thread_id, thread_type = self._getThread(thread_id, None)
|
||||
data = {
|
||||
"attachment_id": attachment_id,
|
||||
"recipient_map[{}]".format(generateOfflineThreadingID()): thread_id,
|
||||
}
|
||||
j = self._post(
|
||||
self.req_url.FORWARD_ATTACHMENT, data, fix_request=True, as_json=True
|
||||
)
|
||||
|
||||
def createGroup(self, message, user_ids):
|
||||
"""
|
||||
Creates a group with the given ids
|
||||
|
@@ -90,6 +90,8 @@ class Message(object):
|
||||
reply_to_id = attr.ib(None)
|
||||
#: Replied message
|
||||
replied_to = attr.ib(None, init=False)
|
||||
#: Whether the message was forwarded
|
||||
forwarded = attr.ib(False, init=False)
|
||||
|
||||
@classmethod
|
||||
def formatMentions(cls, text, *args, **kwargs):
|
||||
@@ -144,12 +146,19 @@ class Message(object):
|
||||
message = cls(text=result, mentions=mentions)
|
||||
return message
|
||||
|
||||
@staticmethod
|
||||
def _get_forwarded_from_tags(tags):
|
||||
if tags is None:
|
||||
return False
|
||||
return any(map(lambda tag: "forward" in tag or "copy" in tag, tags))
|
||||
|
||||
@classmethod
|
||||
def _from_graphql(cls, data):
|
||||
if data.get("message_sender") is None:
|
||||
data["message_sender"] = {}
|
||||
if data.get("message") is None:
|
||||
data["message"] = {}
|
||||
tags = data.get("tags_list")
|
||||
rtn = cls(
|
||||
text=data["message"].get("text"),
|
||||
mentions=[
|
||||
@@ -160,7 +169,8 @@ class Message(object):
|
||||
)
|
||||
for m in data["message"].get("ranges") or ()
|
||||
],
|
||||
emoji_size=EmojiSize._from_tags(data.get("tags_list")),
|
||||
emoji_size=EmojiSize._from_tags(tags),
|
||||
forwarded=cls._get_forwarded_from_tags(tags),
|
||||
sticker=_sticker.Sticker._from_graphql(data.get("sticker")),
|
||||
)
|
||||
rtn.uid = str(data["message_id"])
|
||||
@@ -203,13 +213,15 @@ class Message(object):
|
||||
|
||||
@classmethod
|
||||
def _from_reply(cls, data):
|
||||
tags = data["messageMetadata"].get("tags")
|
||||
rtn = cls(
|
||||
text=data.get("body"),
|
||||
mentions=[
|
||||
Mention(m.get("i"), offset=m.get("o"), length=m.get("l"))
|
||||
for m in json.loads(data.get("data", {}).get("prng", "[]"))
|
||||
],
|
||||
emoji_size=EmojiSize._from_tags(data["messageMetadata"].get("tags")),
|
||||
emoji_size=EmojiSize._from_tags(tags),
|
||||
forwarded=cls._get_forwarded_from_tags(tags),
|
||||
)
|
||||
metadata = data.get("messageMetadata", {})
|
||||
rtn.uid = metadata.get("messageId")
|
||||
@@ -311,6 +323,7 @@ class Message(object):
|
||||
)
|
||||
|
||||
rtn.emoji_size = EmojiSize._from_tags(tags)
|
||||
rtn.forwarded = cls._get_forwarded_from_tags(tags)
|
||||
|
||||
return rtn
|
||||
|
||||
|
@@ -114,6 +114,7 @@ class ReqUrl(object):
|
||||
SEARCH_MESSAGES = "https://www.facebook.com/ajax/mercury/search_snippets.php?dpr=1"
|
||||
MARK_SPAM = "https://www.facebook.com/ajax/mercury/mark_spam.php?dpr=1"
|
||||
UNSEND = "https://www.facebook.com/messaging/unsend_message/?dpr=1"
|
||||
FORWARD_ATTACHMENT = "https://www.facebook.com/mercury/attachments/forward/"
|
||||
|
||||
pull_channel = 0
|
||||
|
||||
@@ -192,29 +193,35 @@ def generateOfflineThreadingID():
|
||||
|
||||
|
||||
def check_json(j):
|
||||
if j.get("error") is None:
|
||||
return
|
||||
if "errorDescription" in j:
|
||||
# 'errorDescription' is in the users own language!
|
||||
if j.get("payload") and j["payload"].get("error"):
|
||||
raise FBchatFacebookError(
|
||||
"Error #{} when sending request: {}".format(
|
||||
j["error"], j["errorDescription"]
|
||||
),
|
||||
fb_error_code=j["error"],
|
||||
fb_error_message=j["errorDescription"],
|
||||
)
|
||||
elif "debug_info" in j["error"] and "code" in j["error"]:
|
||||
raise FBchatFacebookError(
|
||||
"Error #{} when sending request: {}".format(
|
||||
j["error"]["code"], repr(j["error"]["debug_info"])
|
||||
),
|
||||
fb_error_code=j["error"]["code"],
|
||||
fb_error_message=j["error"]["debug_info"],
|
||||
)
|
||||
else:
|
||||
raise FBchatFacebookError(
|
||||
"Error {} when sending request".format(j["error"]), fb_error_code=j["error"]
|
||||
"Error when sending request: {}".format(j["payload"]["error"]),
|
||||
fb_error_code=None,
|
||||
fb_error_message=j["payload"]["error"],
|
||||
)
|
||||
elif j.get("error"):
|
||||
if "errorDescription" in j:
|
||||
# 'errorDescription' is in the users own language!
|
||||
raise FBchatFacebookError(
|
||||
"Error #{} when sending request: {}".format(
|
||||
j["error"], j["errorDescription"]
|
||||
),
|
||||
fb_error_code=j["error"],
|
||||
fb_error_message=j["errorDescription"],
|
||||
)
|
||||
elif "debug_info" in j["error"] and "code" in j["error"]:
|
||||
raise FBchatFacebookError(
|
||||
"Error #{} when sending request: {}".format(
|
||||
j["error"]["code"], repr(j["error"]["debug_info"])
|
||||
),
|
||||
fb_error_code=j["error"]["code"],
|
||||
fb_error_message=j["error"]["debug_info"],
|
||||
)
|
||||
else:
|
||||
raise FBchatFacebookError(
|
||||
"Error {} when sending request".format(j["error"]),
|
||||
fb_error_code=j["error"],
|
||||
)
|
||||
|
||||
|
||||
def check_request(r, as_json=True):
|
||||
|
Reference in New Issue
Block a user