Add thread actions to ThreadABC
This commit is contained in:
@@ -728,112 +728,6 @@ class Client:
|
||||
data = {"message_id": mid}
|
||||
j = self._payload_post("/messaging/unsend_message/?dpr=1", data)
|
||||
|
||||
def forward_attachment(self, attachment_id, thread_id=None):
|
||||
"""Forward an attachment.
|
||||
|
||||
Args:
|
||||
attachment_id: Attachment ID to forward
|
||||
thread_id: User/Group ID to send to. See :ref:`intro_threads`
|
||||
|
||||
Raises:
|
||||
FBchatException: If request failed
|
||||
"""
|
||||
data = {
|
||||
"attachment_id": attachment_id,
|
||||
"recipient_map[{}]".format(
|
||||
_util.generate_offline_threading_id()
|
||||
): thread_id,
|
||||
}
|
||||
j = self._payload_post("/mercury/attachments/forward/", data)
|
||||
if not j.get("success"):
|
||||
raise FBchatFacebookError(
|
||||
"Failed forwarding attachment: {}".format(j["error"]),
|
||||
fb_error_message=j["error"],
|
||||
)
|
||||
|
||||
def change_thread_title(self, title, thread_id=None, thread_type=ThreadType.USER):
|
||||
"""Change title of a thread.
|
||||
|
||||
If this is executed on a user thread, this will change the nickname of that
|
||||
user, effectively changing the title.
|
||||
|
||||
Args:
|
||||
title: New group thread title
|
||||
thread_id: Group ID to change title of. See :ref:`intro_threads`
|
||||
thread_type (ThreadType): See :ref:`intro_threads`
|
||||
|
||||
Raises:
|
||||
FBchatException: If request failed
|
||||
"""
|
||||
if thread_type == ThreadType.USER:
|
||||
# The thread is a user, so we change the user's nickname
|
||||
return self.change_nickname(
|
||||
title, thread_id, thread_id=thread_id, thread_type=thread_type
|
||||
)
|
||||
|
||||
data = {"thread_name": title, "thread_id": thread_id}
|
||||
j = self._payload_post("/messaging/set_thread_name/?dpr=1", data)
|
||||
|
||||
def change_nickname(
|
||||
self, nickname, user_id, thread_id=None, thread_type=ThreadType.USER
|
||||
):
|
||||
"""Change the nickname of a user in a thread.
|
||||
|
||||
Args:
|
||||
nickname: New nickname
|
||||
user_id: User that will have their nickname changed
|
||||
thread_id: User/Group ID to change color of. See :ref:`intro_threads`
|
||||
thread_type (ThreadType): See :ref:`intro_threads`
|
||||
|
||||
Raises:
|
||||
FBchatException: If request failed
|
||||
"""
|
||||
data = {
|
||||
"nickname": nickname,
|
||||
"participant_id": user_id,
|
||||
"thread_or_other_fbid": thread_id,
|
||||
}
|
||||
j = self._payload_post(
|
||||
"/messaging/save_thread_nickname/?source=thread_settings&dpr=1", data
|
||||
)
|
||||
|
||||
def change_thread_color(self, color, thread_id=None):
|
||||
"""Change thread color.
|
||||
|
||||
Args:
|
||||
color (ThreadColor): New thread color
|
||||
thread_id: User/Group ID to change color of. See :ref:`intro_threads`
|
||||
|
||||
Raises:
|
||||
FBchatException: If request failed
|
||||
"""
|
||||
data = {
|
||||
"color_choice": color.value if color != ThreadColor.MESSENGER_BLUE else "",
|
||||
"thread_or_other_fbid": thread_id,
|
||||
}
|
||||
j = self._payload_post(
|
||||
"/messaging/save_thread_color/?source=thread_settings&dpr=1", data
|
||||
)
|
||||
|
||||
def change_thread_emoji(self, emoji, thread_id=None):
|
||||
"""Change thread color.
|
||||
|
||||
Note:
|
||||
While changing the emoji, the Facebook web client actually sends multiple
|
||||
different requests, though only this one is required to make the change.
|
||||
|
||||
Args:
|
||||
color: New thread emoji
|
||||
thread_id: User/Group ID to change emoji of. See :ref:`intro_threads`
|
||||
|
||||
Raises:
|
||||
FBchatException: If request failed
|
||||
"""
|
||||
data = {"emoji_choice": emoji, "thread_or_other_fbid": thread_id}
|
||||
j = self._payload_post(
|
||||
"/messaging/save_thread_emoji/?source=thread_settings&dpr=1", data
|
||||
)
|
||||
|
||||
def react_to_message(self, message_id, reaction):
|
||||
"""React to a message, or removes reaction.
|
||||
|
||||
@@ -855,32 +749,6 @@ class Client:
|
||||
j = self._payload_post("/webgraphql/mutation", data)
|
||||
_util.handle_graphql_errors(j)
|
||||
|
||||
def create_plan(self, plan, thread_id=None):
|
||||
"""Set a plan.
|
||||
|
||||
Args:
|
||||
plan (Plan): Plan to set
|
||||
thread_id: User/Group ID to send plan to. See :ref:`intro_threads`
|
||||
|
||||
Raises:
|
||||
FBchatException: If request failed
|
||||
"""
|
||||
data = {
|
||||
"event_type": "EVENT",
|
||||
"event_time": _util.datetime_to_seconds(plan.time),
|
||||
"title": plan.title,
|
||||
"thread_id": thread_id,
|
||||
"location_id": plan.location_id or "",
|
||||
"location_name": plan.location or "",
|
||||
"acontext": ACONTEXT,
|
||||
}
|
||||
j = self._payload_post("/ajax/eventreminder/create", data)
|
||||
if "error" in j:
|
||||
raise FBchatFacebookError(
|
||||
"Failed creating plan: {}".format(j["error"]),
|
||||
fb_error_message=j["error"],
|
||||
)
|
||||
|
||||
def edit_plan(self, plan, new_plan):
|
||||
"""Edit a plan.
|
||||
|
||||
@@ -931,33 +799,6 @@ class Client:
|
||||
}
|
||||
j = self._payload_post("/ajax/eventreminder/rsvp", data)
|
||||
|
||||
def create_poll(self, poll, thread_id=None):
|
||||
"""Create poll in a group thread.
|
||||
|
||||
Args:
|
||||
poll (Poll): Poll to create
|
||||
thread_id: User/Group ID to create poll in. See :ref:`intro_threads`
|
||||
|
||||
Raises:
|
||||
FBchatException: If request failed
|
||||
"""
|
||||
# We're using ordered dictionaries, because the Facebook endpoint that parses
|
||||
# the POST parameters is badly implemented, and deals with ordering the options
|
||||
# wrongly. If you can find a way to fix this for the endpoint, or if you find
|
||||
# another endpoint, please do suggest it ;)
|
||||
data = OrderedDict([("question_text", poll.title), ("target_id", thread_id)])
|
||||
|
||||
for i, option in enumerate(poll.options):
|
||||
data["option_text_array[{}]".format(i)] = option.text
|
||||
data["option_is_selected_array[{}]".format(i)] = str(int(option.vote))
|
||||
|
||||
j = self._payload_post("/messaging/group_polling/create_poll/?dpr=1", data)
|
||||
if j.get("status") != "success":
|
||||
raise FBchatFacebookError(
|
||||
"Failed creating poll: {}".format(j.get("errorTitle")),
|
||||
fb_error_message=j.get("errorMessage"),
|
||||
)
|
||||
|
||||
def update_poll_vote(self, poll_id, option_ids=[], new_options=[]):
|
||||
"""Update a poll vote.
|
||||
|
||||
@@ -986,25 +827,6 @@ class Client:
|
||||
fb_error_message=j.get("errorMessage"),
|
||||
)
|
||||
|
||||
def set_typing_status(self, status, thread_id=None, thread_type=None):
|
||||
"""Set users typing status in a thread.
|
||||
|
||||
Args:
|
||||
status (TypingStatus): Specify the typing status
|
||||
thread_id: User/Group ID to change status in. See :ref:`intro_threads`
|
||||
thread_type (ThreadType): See :ref:`intro_threads`
|
||||
|
||||
Raises:
|
||||
FBchatException: If request failed
|
||||
"""
|
||||
data = {
|
||||
"typ": status.value,
|
||||
"thread": thread_id,
|
||||
"to": thread_id if thread_type == ThreadType.USER else "",
|
||||
"source": "mercury-chat",
|
||||
}
|
||||
j = self._payload_post("/ajax/messaging/typ.php", data)
|
||||
|
||||
"""
|
||||
END SEND METHODS
|
||||
"""
|
||||
@@ -1146,21 +968,6 @@ class Client:
|
||||
)
|
||||
return True
|
||||
|
||||
def mark_as_spam(self, thread_id=None):
|
||||
"""Mark a thread as spam, and delete it.
|
||||
|
||||
Args:
|
||||
thread_id: User/Group ID to mark as spam. See :ref:`intro_threads`
|
||||
|
||||
Returns:
|
||||
True
|
||||
|
||||
Raises:
|
||||
FBchatException: If request failed
|
||||
"""
|
||||
j = self._payload_post("/ajax/mercury/mark_spam.php?dpr=1", {"id": thread_id})
|
||||
return True
|
||||
|
||||
def delete_messages(self, message_ids):
|
||||
"""Delete specified messages.
|
||||
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import abc
|
||||
import attr
|
||||
import datetime
|
||||
from ._core import attrs_default, Enum, Image
|
||||
from . import _util, _session
|
||||
from . import _util, _exception, _session
|
||||
from typing import MutableMapping, Any, Iterable, Tuple
|
||||
|
||||
|
||||
@@ -306,6 +307,144 @@ class ThreadABC(metaclass=abc.ABCMeta):
|
||||
yield Attachment(id=i["node"].get("legacy_attachment_id"))
|
||||
del j[self.id]["message_shared_media"]["edges"][0]
|
||||
|
||||
def set_nickname(self, user_id: str, nickname: str):
|
||||
"""Change the nickname of a user in the thread.
|
||||
|
||||
Args:
|
||||
user_id: User that will have their nickname changed
|
||||
nickname: New nickname
|
||||
"""
|
||||
data = {
|
||||
"nickname": nickname,
|
||||
"participant_id": user_id,
|
||||
"thread_or_other_fbid": self.id,
|
||||
}
|
||||
j = self.session._payload_post(
|
||||
"/messaging/save_thread_nickname/?source=thread_settings&dpr=1", data
|
||||
)
|
||||
|
||||
def set_color(self, color: ThreadColor):
|
||||
"""Change thread color.
|
||||
|
||||
Args:
|
||||
color: New thread color
|
||||
"""
|
||||
data = {
|
||||
"color_choice": color.value if color != ThreadColor.MESSENGER_BLUE else "",
|
||||
"thread_or_other_fbid": self.id,
|
||||
}
|
||||
j = self.session._payload_post(
|
||||
"/messaging/save_thread_color/?source=thread_settings&dpr=1", data
|
||||
)
|
||||
|
||||
def set_emoji(self, emoji: str):
|
||||
"""Change thread color.
|
||||
|
||||
Args:
|
||||
emoji: New thread emoji
|
||||
"""
|
||||
data = {"emoji_choice": emoji, "thread_or_other_fbid": self.id}
|
||||
# While changing the emoji, the Facebook web client actually sends multiple
|
||||
# different requests, though only this one is required to make the change.
|
||||
j = self.session._payload_post(
|
||||
"/messaging/save_thread_emoji/?source=thread_settings&dpr=1", data
|
||||
)
|
||||
|
||||
def forward_attachment(self, attachment_id):
|
||||
"""Forward an attachment.
|
||||
|
||||
Args:
|
||||
attachment_id: Attachment ID to forward
|
||||
"""
|
||||
data = {
|
||||
"attachment_id": attachment_id,
|
||||
"recipient_map[{}]".format(_util.generate_offline_threading_id()): self.id,
|
||||
}
|
||||
j = self.session._payload_post("/mercury/attachments/forward/", data)
|
||||
if not j.get("success"):
|
||||
raise _exception.FBchatFacebookError(
|
||||
"Failed forwarding attachment: {}".format(j["error"]),
|
||||
fb_error_message=j["error"],
|
||||
)
|
||||
|
||||
def _set_typing(self, typing):
|
||||
data = {
|
||||
"typ": "1" if typing else "0",
|
||||
"thread": self.id,
|
||||
# TODO: This
|
||||
"to": self.id if thread_type == ThreadType.USER else "",
|
||||
"source": "mercury-chat",
|
||||
}
|
||||
j = self.session._payload_post("/ajax/messaging/typ.php", data)
|
||||
|
||||
def start_typing(self):
|
||||
"""Set the current user to start typing in the thread."""
|
||||
self._set_typing(True)
|
||||
|
||||
def stop_typing(self):
|
||||
"""Set the current user to stop typing in the thread."""
|
||||
self._set_typing(False)
|
||||
|
||||
def create_plan(
|
||||
self,
|
||||
name: str,
|
||||
at: datetime.datetime,
|
||||
location_name: str = None,
|
||||
location_id: str = None,
|
||||
):
|
||||
"""Create a new plan.
|
||||
|
||||
# TODO: Arguments
|
||||
|
||||
Args:
|
||||
title: Name of the new plan
|
||||
at: When the plan is for
|
||||
"""
|
||||
data = {
|
||||
"event_type": "EVENT",
|
||||
"event_time": _util.datetime_to_seconds(at),
|
||||
"title": name,
|
||||
"thread_id": self.id,
|
||||
"location_id": location_id or "",
|
||||
"location_name": location or "",
|
||||
"acontext": ACONTEXT,
|
||||
}
|
||||
j = self.session._payload_post("/ajax/eventreminder/create", data)
|
||||
if "error" in j:
|
||||
raise _exception.FBchatFacebookError(
|
||||
"Failed creating plan: {}".format(j["error"]),
|
||||
fb_error_message=j["error"],
|
||||
)
|
||||
|
||||
def create_poll(self, question: str, options=Iterable[Tuple[str, bool]]):
|
||||
"""Create poll in a thread.
|
||||
|
||||
# TODO: Arguments
|
||||
"""
|
||||
# We're using ordered dictionaries, because the Facebook endpoint that parses
|
||||
# the POST parameters is badly implemented, and deals with ordering the options
|
||||
# wrongly. If you can find a way to fix this for the endpoint, or if you find
|
||||
# another endpoint, please do suggest it ;)
|
||||
data = OrderedDict([("question_text", question), ("target_id", self.id)])
|
||||
|
||||
for i, (text, vote) in enumerate(options):
|
||||
data["option_text_array[{}]".format(i)] = text
|
||||
data["option_is_selected_array[{}]".format(i)] = str(int(vote))
|
||||
|
||||
j = self.session._payload_post(
|
||||
"/messaging/group_polling/create_poll/?dpr=1", data
|
||||
)
|
||||
if j.get("status") != "success":
|
||||
raise _exception.FBchatFacebookError(
|
||||
"Failed creating poll: {}".format(j.get("errorTitle")),
|
||||
fb_error_message=j.get("errorMessage"),
|
||||
)
|
||||
|
||||
def mark_as_spam(self):
|
||||
"""Mark the thread as spam, and delete it."""
|
||||
data = {"id": self.id}
|
||||
j = self.session._payload_post("/ajax/mercury/mark_spam.php?dpr=1", data)
|
||||
|
||||
def _forced_fetch(self, message_id: str) -> dict:
|
||||
params = {
|
||||
"thread_and_message_id": {"thread_id": self.id, "message_id": message_id}
|
||||
|
Reference in New Issue
Block a user