aboutsummaryrefslogtreecommitdiffstats
path: root/slack
diff options
context:
space:
mode:
Diffstat (limited to 'slack')
-rw-r--r--slack/error.py6
-rw-r--r--slack/slack_api.py26
-rw-r--r--slack/slack_message.py27
-rw-r--r--slack/slack_user.py17
-rw-r--r--slack/slack_workspace.py25
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