aboutsummaryrefslogtreecommitdiffstats
path: root/slack
diff options
context:
space:
mode:
authorTrygve Aaberge <trygveaa@gmail.com>2023-09-17 11:29:36 +0200
committerTrygve Aaberge <trygveaa@gmail.com>2024-02-18 11:32:54 +0100
commit2a9cad66efec738e68230d335540e6c9e7d9c7e8 (patch)
treeed6fe28a55d40ac0ff3a9f4f3acfced7b11e48fc /slack
parenta40da880a7889b5d207398daacc18e4c8caaed11 (diff)
downloadwee-slack-2a9cad66efec738e68230d335540e6c9e7d9c7e8.tar.gz
Fetch replies in conversation when display_thread_replies is on
Diffstat (limited to 'slack')
-rw-r--r--slack/slack_api.py15
-rw-r--r--slack/slack_conversation.py48
-rw-r--r--slack/slack_message.py4
3 files changed, 58 insertions, 9 deletions
diff --git a/slack/slack_api.py b/slack/slack_api.py
index 9627594..72c82e4 100644
--- a/slack/slack_api.py
+++ b/slack/slack_api.py
@@ -7,12 +7,14 @@ from urllib.parse import urlencode
from slack.error import SlackApiError
from slack.http import http_request
from slack.shared import shared
+from slack.slack_message import SlackMessage
if TYPE_CHECKING:
from slack_api.slack_bots_info import SlackBotInfoResponse, SlackBotsInfoResponse
from slack_api.slack_conversations_history import SlackConversationsHistoryResponse
from slack_api.slack_conversations_info import SlackConversationsInfoResponse
from slack_api.slack_conversations_members import SlackConversationsMembersResponse
+ from slack_api.slack_conversations_replies import SlackConversationsRepliesResponse
from slack_api.slack_rtm_connect import SlackRtmConnectResponse
from slack_api.slack_usergroups_info import SlackUsergroupsInfoResponse
from slack_api.slack_users_conversations import SlackUsersConversationsResponse
@@ -136,6 +138,19 @@ class SlackApi(SlackApiCommon):
raise SlackApiError(self.workspace, method, response, params)
return response
+ async def fetch_conversations_replies(self, parent_message: SlackMessage):
+ method = "conversations.replies"
+ params: Params = {
+ "channel": parent_message.conversation.id,
+ "ts": str(parent_message.ts),
+ }
+ response: SlackConversationsRepliesResponse = await self._fetch_list(
+ method, "messages", params
+ )
+ if response["ok"] is False:
+ raise SlackApiError(self.workspace, method, response, params)
+ return response
+
async def fetch_conversations_info(self, conversation_id: str):
method = "conversations.info"
params: Params = {"channel": conversation_id}
diff --git a/slack/slack_conversation.py b/slack/slack_conversation.py
index 359c810..6a24616 100644
--- a/slack/slack_conversation.py
+++ b/slack/slack_conversation.py
@@ -198,7 +198,7 @@ class SlackConversationMessageHashes(Dict[SlackTs, str]):
other_message = self._conversation.messages[ts_with_same_hash]
run_async(self._conversation.rerender_message(other_message))
- for reply in other_message.replies:
+ for reply in other_message.replies.values():
run_async(self._conversation.rerender_message(reply))
self._setitem(key, short_hash)
@@ -385,6 +385,27 @@ class SlackConversation:
self.workspace.users.initialize_items(self._members)
return self._members
+ async def fetch_replies(
+ self, message: SlackMessage
+ ) -> Optional[List[SlackMessage]]:
+ if not message.is_thread_parent:
+ return
+
+ replies_response = await self._api.fetch_conversations_replies(message)
+ replies = [
+ SlackMessage(self, reply) for reply in replies_response["messages"][1:]
+ ]
+
+ for reply in replies:
+ message.replies[reply.ts] = reply
+ self._messages[reply.ts] = reply
+
+ message.replies = OrderedDict(sorted(message.replies.items()))
+ self._messages = OrderedDict(sorted(self._messages.items()))
+
+ message.reply_history_filled = True
+ return replies
+
async def fill_history(self):
if self.history_filled or self.history_pending:
return
@@ -394,11 +415,23 @@ class SlackConversation:
history = await self._api.fetch_conversations_history(self)
- messages = [SlackMessage(self, message) for message in history["messages"]]
- for message in messages:
+ conversation_messages = [
+ SlackMessage(self, message) for message in history["messages"]
+ ]
+ for message in reversed(conversation_messages):
self._messages[message.ts] = message
- # TODO: Account for reply messages
+ if self.display_thread_replies():
+ await gather(
+ *(self.fetch_replies(message) for message in conversation_messages)
+ )
+
+ self._messages = OrderedDict(sorted(self._messages.items()))
+ messages = [
+ message
+ for message in self._messages.values()
+ if self.should_display_message(message)
+ ]
sender_user_ids = [m.sender_user_id for m in messages if m.sender_user_id]
self.workspace.users.initialize_items(sender_user_ids)
@@ -408,9 +441,8 @@ class SlackConversation:
await gather(*(message.render() for message in messages))
- for message in reversed(messages):
- if self.should_display_message(message):
- await self.print_message(message, backlog=True)
+ for message in messages:
+ await self.print_message(message, backlog=True)
self.history_filled = True
self.history_pending = False
@@ -459,7 +491,7 @@ class SlackConversation:
parent_message = message.parent_message
if parent_message:
- parent_message.replies.append(message)
+ parent_message.replies[message.ts] = message
if message.sender_user_id:
# TODO: thread buffers
diff --git a/slack/slack_message.py b/slack/slack_message.py
index 907dec9..0466559 100644
--- a/slack/slack_message.py
+++ b/slack/slack_message.py
@@ -1,6 +1,7 @@
from __future__ import annotations
import re
+from collections import OrderedDict
from datetime import date, datetime, timedelta
from enum import Enum
from typing import TYPE_CHECKING, List, Match, Optional, Tuple, Union
@@ -107,7 +108,8 @@ class SlackMessage:
self._rendered_message = None
self.conversation = conversation
self.ts = SlackTs(message_json["ts"])
- self.replies: List[SlackMessage] = []
+ self.replies: OrderedDict[SlackTs, SlackMessage] = OrderedDict()
+ self.reply_history_filled = False
self._deleted = False
@property