aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mock_data/slack_users_info_bot.json53
-rw-r--r--mock_data/slack_users_info_person.json49
-rwxr-xr-xscripts/update_mocks.sh3
-rw-r--r--slack/slack_api.py3
-rw-r--r--slack/slack_user.py3
-rw-r--r--typings/slack_api/slack_users_info.pyi94
6 files changed, 204 insertions, 1 deletions
diff --git a/mock_data/slack_users_info_bot.json b/mock_data/slack_users_info_bot.json
new file mode 100644
index 0000000..2439dc9
--- /dev/null
+++ b/mock_data/slack_users_info_bot.json
@@ -0,0 +1,53 @@
+{
+ "ok": true,
+ "user": {
+ "id": "UU6635U31",
+ "team_id": "T0FC8BFQR",
+ "name": "polly",
+ "deleted": false,
+ "color": "e0a729",
+ "real_name": "Polly",
+ "tz": "America/Los_Angeles",
+ "tz_label": "Pacific Standard Time",
+ "tz_offset": -28800,
+ "profile": {
+ "title": "",
+ "phone": "",
+ "skype": "",
+ "real_name": "Polly",
+ "real_name_normalized": "Polly",
+ "display_name": "",
+ "display_name_normalized": "",
+ "fields": {},
+ "status_text": "",
+ "status_emoji": "",
+ "status_emoji_display_info": [],
+ "status_expiration": 0,
+ "avatar_hash": "ec326dfe553b",
+ "api_app_id": "A04E6JX41",
+ "always_active": true,
+ "image_original": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_original.png",
+ "is_custom_image": true,
+ "bot_id": "BTU6APY9F",
+ "image_24": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_24.png",
+ "image_32": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_32.png",
+ "image_48": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_48.png",
+ "image_72": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_72.png",
+ "image_192": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_192.png",
+ "image_512": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_512.png",
+ "image_1024": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_1024.png",
+ "status_text_canonical": "",
+ "team": "T0FC8BFQR"
+ },
+ "is_admin": false,
+ "is_owner": false,
+ "is_primary_owner": false,
+ "is_restricted": false,
+ "is_ultra_restricted": false,
+ "is_bot": true,
+ "is_app_user": false,
+ "updated": 1664912039,
+ "is_email_confirmed": false,
+ "who_can_share_contact_card": "EVERYONE"
+ }
+}
diff --git a/mock_data/slack_users_info_person.json b/mock_data/slack_users_info_person.json
new file mode 100644
index 0000000..14e80f8
--- /dev/null
+++ b/mock_data/slack_users_info_person.json
@@ -0,0 +1,49 @@
+{
+ "ok": true,
+ "user": {
+ "id": "U017V7T2D40",
+ "team_id": "T0FC8BFQR",
+ "name": "trygveaa_wee-slack-te",
+ "deleted": false,
+ "color": "684b6c",
+ "real_name": "Test 1",
+ "tz": "Europe/Amsterdam",
+ "tz_label": "Central European Time",
+ "tz_offset": 3600,
+ "profile": {
+ "title": "",
+ "phone": "",
+ "skype": "",
+ "real_name": "Test 1",
+ "real_name_normalized": "Test 1",
+ "display_name": "Test 1",
+ "display_name_normalized": "Test 1",
+ "fields": {},
+ "status_text": "",
+ "status_emoji": "",
+ "status_emoji_display_info": [],
+ "status_expiration": 0,
+ "avatar_hash": "g57ba37781eb",
+ "email": "trygveaa+wee-slack-test.1@gmail.com",
+ "image_24": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-24.png",
+ "image_32": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-32.png",
+ "image_48": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-48.png",
+ "image_72": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-72.png",
+ "image_192": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-192.png",
+ "image_512": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-512.png",
+ "status_text_canonical": "",
+ "team": "T0FC8BFQR"
+ },
+ "is_admin": false,
+ "is_owner": false,
+ "is_primary_owner": false,
+ "is_restricted": false,
+ "is_ultra_restricted": false,
+ "is_bot": false,
+ "is_app_user": false,
+ "updated": 1664912039,
+ "is_email_confirmed": true,
+ "has_2fa": false,
+ "who_can_share_contact_card": "EVERYONE"
+ }
+}
diff --git a/scripts/update_mocks.sh b/scripts/update_mocks.sh
index 5348796..7c029fb 100755
--- a/scripts/update_mocks.sh
+++ b/scripts/update_mocks.sh
@@ -20,3 +20,6 @@ curl_slack "$api_base/conversations.info?channel=GNLENA84B" | jq . > mock_data/s
curl_slack "$api_base/conversations.info?channel=C042VL9076F" | jq . > mock_data/slack_info_mpim_channel.json
curl_slack "$api_base/conversations.info?channel=GKHEJUM1N" | jq . > mock_data/slack_info_mpim_group.json
curl_slack "$api_base/conversations.info?channel=D9N2KD0V6" | jq . > mock_data/slack_info_im.json
+
+curl_slack "$api_base/users.info?user=U017V7T2D40" | jq . > mock_data/slack_users_info_person.json
+curl_slack "$api_base/users.info?user=UU6635U31" | jq . > mock_data/slack_users_info_bot.json
diff --git a/slack/slack_api.py b/slack/slack_api.py
index aeaf6be..ef522d0 100644
--- a/slack/slack_api.py
+++ b/slack/slack_api.py
@@ -10,6 +10,7 @@ from slack.shared import shared
if TYPE_CHECKING:
from slack_api.slack_conversations_info import SlackConversationsInfoResponse
from slack_api.slack_users_conversations import SlackUsersConversationsResponse
+ from slack_api.slack_users_info import SlackUsersInfoResponse
from slack.slack_conversation import SlackConversation
from slack.slack_user import SlackUser
@@ -78,5 +79,5 @@ class SlackApi:
pages,
)
- async def fetch_users_info(self, user: SlackUser) -> Any:
+ async def fetch_users_info(self, user: SlackUser) -> SlackUsersInfoResponse:
return await self._fetch("users.info", {"user": user.id})
diff --git a/slack/slack_user.py b/slack/slack_user.py
index 18c897f..6cb3897 100644
--- a/slack/slack_user.py
+++ b/slack/slack_user.py
@@ -18,4 +18,7 @@ class SlackUser:
async def init(self):
info = await self.api.fetch_users_info(self)
+ if info["ok"] is False:
+ # TODO: Handle error
+ return
self.name = info["user"]["name"]
diff --git a/typings/slack_api/slack_users_info.pyi b/typings/slack_api/slack_users_info.pyi
new file mode 100644
index 0000000..433255e
--- /dev/null
+++ b/typings/slack_api/slack_users_info.pyi
@@ -0,0 +1,94 @@
+from __future__ import annotations
+
+from typing import Dict, Generic, List, Literal, TypedDict, TypeVar, final
+
+T = TypeVar("T")
+
+class SlackProfileCommon(TypedDict):
+ title: str
+ phone: str
+ skype: str
+ real_name: str
+ real_name_normalized: str
+ display_name: str
+ display_name_normalized: str
+ fields: Dict # pyright: ignore [reportMissingTypeArgument]
+ status_text: str
+ status_emoji: str
+ status_emoji_display_info: List # pyright: ignore [reportMissingTypeArgument]
+ status_expiration: int
+ avatar_hash: str
+ image_24: str
+ image_32: str
+ image_48: str
+ image_72: str
+ image_192: str
+ image_512: str
+ status_text_canonical: str
+ team: str
+
+@final
+class SlackProfilePerson(SlackProfileCommon):
+ email: str
+
+@final
+class SlackProfileBot(SlackProfileCommon):
+ api_app_id: str
+ always_active: bool
+ image_original: str
+ is_custom_image: bool
+ bot_id: str
+ image_1024: str
+
+class SlackUsersInfoCommon(TypedDict):
+ id: str
+ team_id: str
+ name: str
+ deleted: bool
+ color: str
+ real_name: str
+ tz: str
+ tz_label: str
+ tz_offset: int
+ is_admin: bool
+ is_owner: bool
+ is_primary_owner: bool
+ is_restricted: bool
+ is_ultra_restricted: bool
+ is_app_user: bool
+ updated: int
+ is_email_confirmed: bool
+ who_can_share_contact_card: str
+
+@final
+class SlackUsersInfoPerson(SlackUsersInfoCommon):
+ profile: SlackProfilePerson
+ is_bot: Literal[False]
+ has_2fa: bool
+
+@final
+class SlackUsersInfoBot(SlackUsersInfoCommon):
+ profile: SlackProfileBot
+ is_bot: Literal[True]
+
+SlackUsersInfo = SlackUsersInfoPerson | SlackUsersInfoBot
+
+@final
+class SlackUsersInfoErrorResponse(TypedDict):
+ ok: Literal[False]
+ error: str
+
+@final
+class SlackUsersInfoSuccessResponse(TypedDict, Generic[T]):
+ ok: Literal[True]
+ user: T
+
+SlackUsersInfoPersonResponse = (
+ SlackUsersInfoSuccessResponse[SlackUsersInfoPerson] | SlackUsersInfoErrorResponse
+)
+SlackUsersInfoBotResponse = (
+ SlackUsersInfoSuccessResponse[SlackUsersInfoBot] | SlackUsersInfoErrorResponse
+)
+SlackUsersInfoResponse = (
+ SlackUsersInfoSuccessResponse[SlackUsersInfo] | SlackUsersInfoErrorResponse
+)