Skip to content

Commit 268d7eb

Browse files
seratchfilmaj
andauthored
Add message metadata support (#1207)
Co-authored-by: Fil Maj <[email protected]>
1 parent 9fb0df9 commit 268d7eb

File tree

7 files changed

+246
-1
lines changed

7 files changed

+246
-1
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import logging
2+
import os
3+
import time
4+
import unittest
5+
6+
from integration_tests.env_variable_names import SLACK_SDK_TEST_BOT_TOKEN
7+
from slack_sdk.models.metadata import Metadata
8+
from slack_sdk.web import WebClient
9+
10+
11+
class TestWebClient(unittest.TestCase):
12+
13+
def setUp(self):
14+
self.logger = logging.getLogger(__name__)
15+
self.bot_token = os.environ[SLACK_SDK_TEST_BOT_TOKEN]
16+
17+
def tearDown(self):
18+
pass
19+
20+
def test_publishing_message_metadata(self):
21+
client: WebClient = WebClient(token=self.bot_token)
22+
new_message = client.chat_postMessage(
23+
channel='#random',
24+
text="message with metadata",
25+
metadata={
26+
"event_type": "procurement-task",
27+
"event_payload": {
28+
"id": "11111",
29+
"amount": 5000,
30+
"tags": ["foo", "bar", "baz"]
31+
},
32+
}
33+
)
34+
self.assertIsNone(new_message.get("error"))
35+
self.assertIsNotNone(new_message.get("message").get("metadata"))
36+
37+
history = client.conversations_history(
38+
channel=new_message.get("channel"),
39+
limit=1,
40+
include_all_metadata=True,
41+
)
42+
self.assertIsNone(history.get("error"))
43+
self.assertIsNotNone(history.get("messages")[0].get("metadata"))
44+
45+
modification = client.chat_update(
46+
channel=new_message.get("channel"),
47+
ts=new_message.get("ts"),
48+
text="message with metadata (modified)",
49+
metadata={
50+
"event_type": "procurement-task",
51+
"event_payload": {
52+
"id": "11111",
53+
"amount": 6000,
54+
},
55+
}
56+
)
57+
self.assertIsNone(modification.get("error"))
58+
self.assertIsNotNone(modification.get("message").get("metadata"))
59+
60+
scheduled = client.chat_scheduleMessage(
61+
channel=new_message.get("channel"),
62+
post_at=int(time.time()) + 30,
63+
text="message with metadata (scheduled)",
64+
metadata={
65+
"event_type": "procurement-task",
66+
"event_payload": {
67+
"id": "11111",
68+
"amount": 10,
69+
},
70+
}
71+
)
72+
self.assertIsNone(scheduled.get("error"))
73+
self.assertIsNotNone(scheduled.get("message").get("metadata"))
74+
75+
def test_publishing_message_metadata_using_models(self):
76+
client: WebClient = WebClient(token=self.bot_token)
77+
new_message = client.chat_postMessage(
78+
channel='#random',
79+
text="message with metadata",
80+
metadata=Metadata(
81+
event_type="procurement-task",
82+
event_payload={
83+
"id": "11111",
84+
"amount": 5000,
85+
"tags": ["foo", "bar", "baz"]
86+
}
87+
)
88+
)
89+
self.assertIsNone(new_message.get("error"))
90+
self.assertIsNotNone(new_message.get("message").get("metadata"))
91+
92+
history = client.conversations_history(
93+
channel=new_message.get("channel"),
94+
limit=1,
95+
include_all_metadata=True,
96+
)
97+
self.assertIsNone(history.get("error"))
98+
self.assertIsNotNone(history.get("messages")[0].get("metadata"))
99+
100+
modification = client.chat_update(
101+
channel=new_message.get("channel"),
102+
ts=new_message.get("ts"),
103+
text="message with metadata (modified)",
104+
metadata=Metadata(
105+
event_type="procurement-task",
106+
event_payload={
107+
"id": "11111",
108+
"amount": 6000,
109+
}
110+
)
111+
)
112+
self.assertIsNone(modification.get("error"))
113+
self.assertIsNotNone(modification.get("message").get("metadata"))
114+
115+
scheduled = client.chat_scheduleMessage(
116+
channel=new_message.get("channel"),
117+
post_at=int(time.time()) + 30,
118+
text="message with metadata (scheduled)",
119+
metadata=Metadata(
120+
event_type="procurement-task",
121+
event_payload={
122+
"id": "11111",
123+
"amount": 10,
124+
}
125+
)
126+
)
127+
self.assertIsNone(scheduled.get("error"))
128+
self.assertIsNotNone(scheduled.get("message").get("metadata"))
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from typing import Dict, Any
2+
from slack_sdk.models.basic_objects import JsonObject
3+
4+
5+
class Metadata(JsonObject):
6+
"""Message metadata
7+
8+
https://api.slack.com/metadata
9+
"""
10+
11+
attributes = {
12+
"event_type",
13+
"event_payload",
14+
}
15+
16+
def __init__(
17+
self,
18+
event_type: str,
19+
event_payload: Dict[str, Any],
20+
**kwargs,
21+
):
22+
self.event_type = event_type
23+
self.event_payload = event_payload
24+
self.additional_attributes = kwargs
25+
26+
def __str__(self):
27+
return str(self.get_non_null_attributes())
28+
29+
def __repr__(self):
30+
return self.__str__()

slack_sdk/web/async_client.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
)
2525
from ..models.attachments import Attachment
2626
from ..models.blocks import Block
27+
from ..models.metadata import Metadata
2728

2829

2930
class AsyncWebClient(AsyncBaseClient):
@@ -2098,6 +2099,7 @@ async def chat_postMessage(
20982099
link_names: Optional[bool] = None,
20992100
username: Optional[str] = None,
21002101
parse: Optional[str] = None, # none, full
2102+
metadata: Optional[Union[Dict, Metadata]] = None,
21012103
**kwargs,
21022104
) -> AsyncSlackResponse:
21032105
"""Sends a message to a channel.
@@ -2122,6 +2124,7 @@ async def chat_postMessage(
21222124
"link_names": link_names,
21232125
"username": username,
21242126
"parse": parse,
2127+
"metadata": metadata,
21252128
}
21262129
)
21272130
_parse_web_class_objects(kwargs)
@@ -2145,6 +2148,7 @@ async def chat_scheduleMessage(
21452148
unfurl_links: Optional[bool] = None,
21462149
unfurl_media: Optional[bool] = None,
21472150
link_names: Optional[bool] = None,
2151+
metadata: Optional[Union[Dict, Metadata]] = None,
21482152
**kwargs,
21492153
) -> AsyncSlackResponse:
21502154
"""Schedules a message.
@@ -2164,6 +2168,7 @@ async def chat_scheduleMessage(
21642168
"unfurl_links": unfurl_links,
21652169
"unfurl_media": unfurl_media,
21662170
"link_names": link_names,
2171+
"metadata": metadata,
21672172
}
21682173
)
21692174
_parse_web_class_objects(kwargs)
@@ -2215,6 +2220,7 @@ async def chat_update(
22152220
link_names: Optional[bool] = None,
22162221
parse: Optional[str] = None, # none, full
22172222
reply_broadcast: Optional[bool] = None,
2223+
metadata: Optional[Union[Dict, Metadata]] = None,
22182224
**kwargs,
22192225
) -> AsyncSlackResponse:
22202226
"""Updates a message in a channel.
@@ -2231,6 +2237,7 @@ async def chat_update(
22312237
"link_names": link_names,
22322238
"parse": parse,
22332239
"reply_broadcast": reply_broadcast,
2240+
"metadata": metadata,
22342241
}
22352242
)
22362243
if isinstance(file_ids, (list, Tuple)):
@@ -2375,6 +2382,7 @@ async def conversations_history(
23752382
channel: str,
23762383
cursor: Optional[str] = None,
23772384
inclusive: Optional[bool] = None,
2385+
include_all_metadata: Optional[bool] = None,
23782386
latest: Optional[str] = None,
23792387
limit: Optional[int] = None,
23802388
oldest: Optional[str] = None,
@@ -2388,6 +2396,7 @@ async def conversations_history(
23882396
"channel": channel,
23892397
"cursor": cursor,
23902398
"inclusive": inclusive,
2399+
"include_all_metadata": include_all_metadata,
23912400
"limit": limit,
23922401
"latest": latest,
23932402
"oldest": oldest,

slack_sdk/web/client.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
)
1616
from ..models.attachments import Attachment
1717
from ..models.blocks import Block
18+
from ..models.metadata import Metadata
1819

1920

2021
class WebClient(BaseClient):
@@ -2047,6 +2048,7 @@ def chat_postMessage(
20472048
link_names: Optional[bool] = None,
20482049
username: Optional[str] = None,
20492050
parse: Optional[str] = None, # none, full
2051+
metadata: Optional[Union[Dict, Metadata]] = None,
20502052
**kwargs,
20512053
) -> SlackResponse:
20522054
"""Sends a message to a channel.
@@ -2071,6 +2073,7 @@ def chat_postMessage(
20712073
"link_names": link_names,
20722074
"username": username,
20732075
"parse": parse,
2076+
"metadata": metadata,
20742077
}
20752078
)
20762079
_parse_web_class_objects(kwargs)
@@ -2094,6 +2097,7 @@ def chat_scheduleMessage(
20942097
unfurl_links: Optional[bool] = None,
20952098
unfurl_media: Optional[bool] = None,
20962099
link_names: Optional[bool] = None,
2100+
metadata: Optional[Union[Dict, Metadata]] = None,
20972101
**kwargs,
20982102
) -> SlackResponse:
20992103
"""Schedules a message.
@@ -2113,6 +2117,7 @@ def chat_scheduleMessage(
21132117
"unfurl_links": unfurl_links,
21142118
"unfurl_media": unfurl_media,
21152119
"link_names": link_names,
2120+
"metadata": metadata,
21162121
}
21172122
)
21182123
_parse_web_class_objects(kwargs)
@@ -2164,6 +2169,7 @@ def chat_update(
21642169
link_names: Optional[bool] = None,
21652170
parse: Optional[str] = None, # none, full
21662171
reply_broadcast: Optional[bool] = None,
2172+
metadata: Optional[Union[Dict, Metadata]] = None,
21672173
**kwargs,
21682174
) -> SlackResponse:
21692175
"""Updates a message in a channel.
@@ -2180,6 +2186,7 @@ def chat_update(
21802186
"link_names": link_names,
21812187
"parse": parse,
21822188
"reply_broadcast": reply_broadcast,
2189+
"metadata": metadata,
21832190
}
21842191
)
21852192
if isinstance(file_ids, (list, Tuple)):
@@ -2324,6 +2331,7 @@ def conversations_history(
23242331
channel: str,
23252332
cursor: Optional[str] = None,
23262333
inclusive: Optional[bool] = None,
2334+
include_all_metadata: Optional[bool] = None,
23272335
latest: Optional[str] = None,
23282336
limit: Optional[int] = None,
23292337
oldest: Optional[str] = None,
@@ -2337,6 +2345,7 @@ def conversations_history(
23372345
"channel": channel,
23382346
"cursor": cursor,
23392347
"inclusive": inclusive,
2348+
"include_all_metadata": include_all_metadata,
23402349
"limit": limit,
23412350
"latest": latest,
23422351
"oldest": oldest,

slack_sdk/web/internal_utils.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from slack_sdk.errors import SlackRequestError
1212
from slack_sdk.models.attachments import Attachment
1313
from slack_sdk.models.blocks import Block
14+
from slack_sdk.models.metadata import Metadata
1415

1516

1617
def convert_bool_to_0_or_1(
@@ -180,11 +181,13 @@ def _build_req_args(
180181

181182

182183
def _parse_web_class_objects(kwargs) -> None:
183-
def to_dict(obj: Union[Dict, Block, Attachment]):
184+
def to_dict(obj: Union[Dict, Block, Attachment, Metadata]):
184185
if isinstance(obj, Block):
185186
return obj.to_dict()
186187
if isinstance(obj, Attachment):
187188
return obj.to_dict()
189+
if isinstance(obj, Metadata):
190+
return obj.to_dict()
188191
return obj
189192

190193
blocks = kwargs.get("blocks", None)
@@ -197,6 +200,10 @@ def to_dict(obj: Union[Dict, Block, Attachment]):
197200
dict_attachments = [to_dict(a) for a in attachments]
198201
kwargs.update({"attachments": dict_attachments})
199202

203+
metadata = kwargs.get("metadata", None)
204+
if metadata is not None and isinstance(metadata, Metadata):
205+
kwargs.update({"metadata": to_dict(metadata)})
206+
200207

201208
def _update_call_participants(
202209
kwargs, users: Union[str, Sequence[Dict[str, str]]]

0 commit comments

Comments
 (0)