diff options
Diffstat (limited to 'slack')
-rw-r--r-- | slack/error.py | 6 | ||||
-rw-r--r-- | slack/slack_api.py | 26 | ||||
-rw-r--r-- | slack/slack_message.py | 27 | ||||
-rw-r--r-- | slack/slack_user.py | 17 | ||||
-rw-r--r-- | slack/slack_workspace.py | 25 |
5 files changed, 89 insertions, 12 deletions
diff --git a/slack/error.py b/slack/error.py index 17427f7..d69fbf9 100644 --- a/slack/error.py +++ b/slack/error.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Dict, Mapping, Union +from typing import TYPE_CHECKING, Dict, Mapping, Sequence, Union if TYPE_CHECKING: from slack_api.slack_error import SlackErrorResponse @@ -31,7 +31,9 @@ class SlackApiError(Exception): workspace: SlackWorkspace, method: str, response: SlackErrorResponse, - params: Mapping[str, Union[str, int, bool]] = {}, + params: Mapping[ + str, Union[str, int, bool, Sequence[str], Sequence[int], Sequence[bool]] + ] = {}, ): super().__init__() self.workspace = workspace diff --git a/slack/slack_api.py b/slack/slack_api.py index 44e1477..eb04ce2 100644 --- a/slack/slack_api.py +++ b/slack/slack_api.py @@ -1,7 +1,7 @@ from __future__ import annotations import json -from typing import TYPE_CHECKING, Iterable, Mapping, Union +from typing import TYPE_CHECKING, Iterable, Mapping, Sequence, Union from urllib.parse import urlencode from slack.error import SlackApiError @@ -13,14 +13,19 @@ if TYPE_CHECKING: from slack_api.slack_conversations_history import SlackConversationsHistoryResponse from slack_api.slack_conversations_info import SlackConversationsInfoResponse from slack_api.slack_rtm_connect import SlackRtmConnectResponse + from slack_api.slack_usergroups_info import SlackUsergroupsInfoResponse from slack_api.slack_users_conversations import SlackUsersConversationsResponse from slack_api.slack_users_info import SlackUserInfoResponse, SlackUsersInfoResponse + from slack_edgeapi.slack_usergroups_info import SlackEdgeUsergroupsInfoResponse from slack_edgeapi.slack_users_search import SlackUsersSearchResponse from slack.slack_conversation import SlackConversation from slack.slack_workspace import SlackWorkspace Params = Mapping[str, Union[str, int, bool]] +EdgeParams = Mapping[ + str, Union[str, int, bool, Sequence[str], Sequence[int], Sequence[bool]] +] class SlackApi: @@ -61,7 +66,7 @@ class SlackApi: return response return response - async def _fetch_edgeapi(self, method: str, params: Params = {}): + async def _fetch_edgeapi(self, method: str, params: EdgeParams = {}): enterprise_id_part = ( f"{self.workspace.enterprise_id}/" if self.workspace.enterprise_id else "" ) @@ -154,6 +159,23 @@ class SlackApi: raise SlackApiError(self.workspace, method, response, params) return response + async def fetch_usergroups_list(self): + method = "usergroups.list" + response: SlackUsergroupsInfoResponse = await self._fetch(method) + if response["ok"] is False: + raise SlackApiError(self.workspace, method, response) + return response + + async def fetch_usergroups_info(self, usergroup_ids: Sequence[str]): + method = "usergroups/info" + params = {"ids": usergroup_ids} + response: SlackEdgeUsergroupsInfoResponse = await self._fetch_edgeapi( + method, params + ) + if response["ok"] is False: + raise SlackApiError(self.workspace, method, response, params) + return response + async def fetch_users_search(self, query: str): method = "users/search" params = { diff --git a/slack/slack_message.py b/slack/slack_message.py index 66b9a70..1cbce43 100644 --- a/slack/slack_message.py +++ b/slack/slack_message.py @@ -4,7 +4,7 @@ import re from typing import TYPE_CHECKING, List, Match, Optional from slack.shared import shared -from slack.slack_user import SlackUser, format_bot_nick +from slack.slack_user import SlackUser, SlackUsergroup, format_bot_nick from slack.task import gather from slack.util import with_color @@ -57,9 +57,9 @@ class SlackMessage: user_ids: List[str] = [ match["user"] for match in mention_matches if match["user"] ] - # usergroup_ids: List[str] = [ - # match["usergroup"] for match in mention_matches if match["usergroup"] - # ] + usergroup_ids: List[str] = [ + match["usergroup"] for match in mention_matches if match["usergroup"] + ] users_list = await gather( *(self.workspace.users[user_id] for user_id in user_ids), @@ -67,6 +67,15 @@ class SlackMessage: ) users = dict(zip(user_ids, users_list)) + usergroups_list = await gather( + *( + self.workspace.usergroups[usergroup_id] + for usergroup_id in usergroup_ids + ), + return_exceptions=True, + ) + usergroups = dict(zip(usergroup_ids, usergroups_list)) + def unfurl_ref(match: Match[str]): if match["user"]: return unfurl_user(match["user"]) @@ -86,6 +95,14 @@ class SlackMessage: ) def unfurl_usergroup(usergroup_id: str): - return f"@{usergroup_id}" + usergroup = usergroups[usergroup_id] + return ( + with_color( + shared.config.color.usergroup_mention_color.value, + "@" + usergroup.handle(), + ) + if isinstance(usergroup, SlackUsergroup) + else f"@{usergroup_id}" + ) return re_mention.sub(unfurl_ref, message) diff --git a/slack/slack_user.py b/slack/slack_user.py index 7b28869..8b9888d 100644 --- a/slack/slack_user.py +++ b/slack/slack_user.py @@ -9,6 +9,7 @@ from slack.util import with_color if TYPE_CHECKING: from slack_api.slack_bots_info import SlackBotInfo + from slack_api.slack_usergroups_info import SlackUsergroupInfo from slack_api.slack_users_info import SlackUserInfo from slack.slack_workspace import SlackWorkspace @@ -87,3 +88,19 @@ class SlackBot: def nick(self, colorize: bool = False) -> str: return format_bot_nick(self._info["name"], colorize) + + +class SlackUsergroup: + def __init__(self, workspace: SlackWorkspace, info: SlackUsergroupInfo): + self.workspace = workspace + self._info = info + + @classmethod + async def create(cls, workspace: SlackWorkspace, id: str): + info_response = await workspace.api.fetch_usergroups_info([id]) + # TODO: Handle failed ids + usergroup_info = info_response["results"][0] + return cls(workspace, usergroup_info) + + def handle(self) -> str: + return self._info["handle"] diff --git a/slack/slack_workspace.py b/slack/slack_workspace.py index f044f8d..217becf 100644 --- a/slack/slack_workspace.py +++ b/slack/slack_workspace.py @@ -14,19 +14,23 @@ from slack.proxy import Proxy from slack.shared import shared from slack.slack_api import SlackApi from slack.slack_conversation import SlackConversation -from slack.slack_user import SlackBot, SlackUser +from slack.slack_user import SlackBot, SlackUser, SlackUsergroup from slack.task import Future, create_task from slack.util import get_callback_name if TYPE_CHECKING: from slack_api.slack_bots_info import SlackBotInfo + from slack_api.slack_usergroups_info import SlackUsergroupInfo from slack_api.slack_users_info import SlackUserInfo else: SlackBotInfo = Any + SlackUsergroupInfo = Any SlackUserInfo = Any -SlackItemClass = TypeVar("SlackItemClass", SlackUser, SlackBot) -SlackItemInfo = TypeVar("SlackItemInfo", SlackUserInfo, SlackBotInfo) +SlackItemClass = TypeVar("SlackItemClass", SlackUser, SlackBot, SlackUsergroup) +SlackItemInfo = TypeVar( + "SlackItemInfo", SlackUserInfo, SlackBotInfo, SlackUsergroupInfo +) class SlackItem( @@ -98,6 +102,20 @@ class SlackBots(SlackItem[SlackBot, SlackBotInfo]): return self._item_class(self.workspace, item_info) +class SlackUsergroups(SlackItem[SlackUsergroup, SlackUsergroupInfo]): + def __init__(self, workspace: SlackWorkspace): + super().__init__(workspace, SlackUsergroup) + + async def _fetch_items_info( + self, item_ids: Iterable[str] + ) -> Dict[str, SlackUsergroupInfo]: + response = await self.workspace.api.fetch_usergroups_info(list(item_ids)) + return {info["id"]: info for info in response["results"]} + + def _create_item_from_info(self, item_info: SlackUsergroupInfo) -> SlackUsergroup: + return self._item_class(self.workspace, item_info) + + class SlackWorkspace: def __init__(self, name: str): self.name = name @@ -106,6 +124,7 @@ class SlackWorkspace: self._is_connected = False self.users = SlackUsers(self) self.bots = SlackBots(self) + self.usergroups = SlackUsergroups(self) self.conversations: Dict[str, SlackConversation] = {} @property |