From 2f3fa57090a01b2cf2020ee90cc3f542d1893ebe Mon Sep 17 00:00:00 2001 From: Trygve Aaberge Date: Sun, 4 Feb 2024 15:20:11 +0100 Subject: Add command `/slack join` For now this only supports known channels, which currently typically means they have to be referenced in a channel with history loaded. --- slack/commands.py | 52 ++++++++++++++++++++++++++ slack/slack_api.py | 9 +++++ typings/slack_api/slack_conversations_join.pyi | 18 +++++++++ 3 files changed, 79 insertions(+) create mode 100644 typings/slack_api/slack_conversations_join.pyi diff --git a/slack/commands.py b/slack/commands.py index 70eb8aa..6bc1fdb 100644 --- a/slack/commands.py +++ b/slack/commands.py @@ -323,6 +323,58 @@ def command_slack_query(buffer: str, args: List[str], options: Options): run_async(create_conversation_for_users(slack_buffer.workspace, users)) +async def conversation_join( + workspace: SlackWorkspace, conversation_id: str, switch: bool +): + await workspace.api.conversations_join(conversation_id) + conversation = await workspace.conversations[conversation_id] + await conversation.open_buffer(switch=switch) + + +@weechat_command("", min_args=1) +def command_slack_join(buffer: str, args: List[str], options: Options): + slack_buffer = shared.buffers.get(buffer) + + workspace_name = options.get("workspace") + if workspace_name is True: + print_error("No workspace specified") + return + + workspace = ( + shared.workspaces.get(workspace_name) + if workspace_name + else slack_buffer.workspace + if slack_buffer is not None + else None + ) + + if workspace is None: + if workspace_name: + print_error(f'Workspace "{workspace_name}" not found') + else: + print_error( + "Must be run from a slack buffer unless a workspace is specified" + ) + return + + conversation_name = args[0] + all_conversations = get_resolved_futures(workspace.conversations.values()) + for conversation in all_conversations: + if ( + conversation.name_with_prefix("short_name_without_padding") + == conversation_name + or conversation.name() == conversation_name + ): + run_async( + conversation_join( + workspace, conversation.id, switch=not options.get("noswitch") + ) + ) + return + + print_error(f'Conversation "{conversation_name}" not found') + + @weechat_command("%(threads)", min_args=1) def command_slack_thread(buffer: str, args: List[str], options: Options): slack_buffer = shared.buffers.get(buffer) diff --git a/slack/slack_api.py b/slack/slack_api.py index 4ffb425..8d49e55 100644 --- a/slack/slack_api.py +++ b/slack/slack_api.py @@ -26,6 +26,7 @@ if TYPE_CHECKING: from slack_api.slack_common import SlackGenericResponse from slack_api.slack_conversations_history import SlackConversationsHistoryResponse from slack_api.slack_conversations_info import SlackConversationsInfoResponse + from slack_api.slack_conversations_join import SlackConversationsJoinResponse from slack_api.slack_conversations_members import SlackConversationsMembersResponse from slack_api.slack_conversations_open import SlackConversationsOpenResponse from slack_api.slack_conversations_replies import SlackConversationsRepliesResponse @@ -360,6 +361,14 @@ class SlackApi(SlackApiCommon): raise SlackApiError(self.workspace, method, response, params) return response + async def conversations_join(self, conversation_id: str): + method = "conversations.join" + params: Params = {"channel": conversation_id} + response: SlackConversationsJoinResponse = await self._fetch(method, params) + if response["ok"] is False: + raise SlackApiError(self.workspace, method, response, params) + return response + async def conversations_close(self, conversation: SlackConversation): method = "conversations.close" params: Params = {"channel": conversation.id} diff --git a/typings/slack_api/slack_conversations_join.pyi b/typings/slack_api/slack_conversations_join.pyi new file mode 100644 index 0000000..8d30898 --- /dev/null +++ b/typings/slack_api/slack_conversations_join.pyi @@ -0,0 +1,18 @@ +from __future__ import annotations + +from slack_api.slack_common import SlackErrorResponse +from typing_extensions import Literal, TypedDict, final + +@final +class SlackConversationsJoinChannel(TypedDict): + id: str + # incomplete + +@final +class SlackConversationsJoinSuccessResponse(TypedDict): + ok: Literal[True] + channel: SlackConversationsJoinChannel + +SlackConversationsJoinResponse = ( + SlackConversationsJoinSuccessResponse | SlackErrorResponse +) -- cgit