Skip to content

Commit 70faa86

Browse files
kapi2289madsmtm
authored andcommitted
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
1 parent 61502ed commit 70faa86

File tree

3 files changed

+60
-23
lines changed

3 files changed

+60
-23
lines changed

fbchat/_client.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,6 +1707,23 @@ def sendLocalImage(
17071707
thread_type=thread_type,
17081708
)
17091709

1710+
def forwardAttachment(self, attachment_id, thread_id=None):
1711+
"""
1712+
Forwards an attachment
1713+
1714+
:param attachment_id: Attachment ID to forward
1715+
:param thread_id: User/Group ID to send to. See :ref:`intro_threads`
1716+
:raises: FBchatException if request failed
1717+
"""
1718+
thread_id, thread_type = self._getThread(thread_id, None)
1719+
data = {
1720+
"attachment_id": attachment_id,
1721+
"recipient_map[{}]".format(generateOfflineThreadingID()): thread_id,
1722+
}
1723+
j = self._post(
1724+
self.req_url.FORWARD_ATTACHMENT, data, fix_request=True, as_json=True
1725+
)
1726+
17101727
def createGroup(self, message, user_ids):
17111728
"""
17121729
Creates a group with the given ids

fbchat/_message.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class Message(object):
9090
reply_to_id = attr.ib(None)
9191
#: Replied message
9292
replied_to = attr.ib(None, init=False)
93+
#: Whether the message was forwarded
94+
forwarded = attr.ib(False, init=False)
9395

9496
@classmethod
9597
def formatMentions(cls, text, *args, **kwargs):
@@ -144,12 +146,19 @@ def formatMentions(cls, text, *args, **kwargs):
144146
message = cls(text=result, mentions=mentions)
145147
return message
146148

149+
@staticmethod
150+
def _get_forwarded_from_tags(tags):
151+
if tags is None:
152+
return False
153+
return any(map(lambda tag: "forward" in tag or "copy" in tag, tags))
154+
147155
@classmethod
148156
def _from_graphql(cls, data):
149157
if data.get("message_sender") is None:
150158
data["message_sender"] = {}
151159
if data.get("message") is None:
152160
data["message"] = {}
161+
tags = data.get("tags_list")
153162
rtn = cls(
154163
text=data["message"].get("text"),
155164
mentions=[
@@ -160,7 +169,8 @@ def _from_graphql(cls, data):
160169
)
161170
for m in data["message"].get("ranges") or ()
162171
],
163-
emoji_size=EmojiSize._from_tags(data.get("tags_list")),
172+
emoji_size=EmojiSize._from_tags(tags),
173+
forwarded=cls._get_forwarded_from_tags(tags),
164174
sticker=_sticker.Sticker._from_graphql(data.get("sticker")),
165175
)
166176
rtn.uid = str(data["message_id"])
@@ -203,13 +213,15 @@ def _from_graphql(cls, data):
203213

204214
@classmethod
205215
def _from_reply(cls, data):
216+
tags = data["messageMetadata"].get("tags")
206217
rtn = cls(
207218
text=data.get("body"),
208219
mentions=[
209220
Mention(m.get("i"), offset=m.get("o"), length=m.get("l"))
210221
for m in json.loads(data.get("data", {}).get("prng", "[]"))
211222
],
212-
emoji_size=EmojiSize._from_tags(data["messageMetadata"].get("tags")),
223+
emoji_size=EmojiSize._from_tags(tags),
224+
forwarded=cls._get_forwarded_from_tags(tags),
213225
)
214226
metadata = data.get("messageMetadata", {})
215227
rtn.uid = metadata.get("messageId")
@@ -311,6 +323,7 @@ def _from_pull(cls, data, mid=None, tags=None, author=None, timestamp=None):
311323
)
312324

313325
rtn.emoji_size = EmojiSize._from_tags(tags)
326+
rtn.forwarded = cls._get_forwarded_from_tags(tags)
314327

315328
return rtn
316329

fbchat/_util.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class ReqUrl(object):
114114
SEARCH_MESSAGES = "https://www.facebook.com/ajax/mercury/search_snippets.php?dpr=1"
115115
MARK_SPAM = "https://www.facebook.com/ajax/mercury/mark_spam.php?dpr=1"
116116
UNSEND = "https://www.facebook.com/messaging/unsend_message/?dpr=1"
117+
FORWARD_ATTACHMENT = "https://www.facebook.com/mercury/attachments/forward/"
117118

118119
pull_channel = 0
119120

@@ -192,29 +193,35 @@ def generateOfflineThreadingID():
192193

193194

194195
def check_json(j):
195-
if j.get("error") is None:
196-
return
197-
if "errorDescription" in j:
198-
# 'errorDescription' is in the users own language!
196+
if j.get("payload") and j["payload"].get("error"):
199197
raise FBchatFacebookError(
200-
"Error #{} when sending request: {}".format(
201-
j["error"], j["errorDescription"]
202-
),
203-
fb_error_code=j["error"],
204-
fb_error_message=j["errorDescription"],
205-
)
206-
elif "debug_info" in j["error"] and "code" in j["error"]:
207-
raise FBchatFacebookError(
208-
"Error #{} when sending request: {}".format(
209-
j["error"]["code"], repr(j["error"]["debug_info"])
210-
),
211-
fb_error_code=j["error"]["code"],
212-
fb_error_message=j["error"]["debug_info"],
213-
)
214-
else:
215-
raise FBchatFacebookError(
216-
"Error {} when sending request".format(j["error"]), fb_error_code=j["error"]
198+
"Error when sending request: {}".format(j["payload"]["error"]),
199+
fb_error_code=None,
200+
fb_error_message=j["payload"]["error"],
217201
)
202+
elif j.get("error"):
203+
if "errorDescription" in j:
204+
# 'errorDescription' is in the users own language!
205+
raise FBchatFacebookError(
206+
"Error #{} when sending request: {}".format(
207+
j["error"], j["errorDescription"]
208+
),
209+
fb_error_code=j["error"],
210+
fb_error_message=j["errorDescription"],
211+
)
212+
elif "debug_info" in j["error"] and "code" in j["error"]:
213+
raise FBchatFacebookError(
214+
"Error #{} when sending request: {}".format(
215+
j["error"]["code"], repr(j["error"]["debug_info"])
216+
),
217+
fb_error_code=j["error"]["code"],
218+
fb_error_message=j["error"]["debug_info"],
219+
)
220+
else:
221+
raise FBchatFacebookError(
222+
"Error {} when sending request".format(j["error"]),
223+
fb_error_code=j["error"],
224+
)
218225

219226

220227
def check_request(r, as_json=True):

0 commit comments

Comments
 (0)