Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add message metadata support #1207

Merged
merged 2 commits into from
May 3, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions integration_tests/web/test_message_metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import logging
import os
import time
import unittest

from integration_tests.env_variable_names import SLACK_SDK_TEST_BOT_TOKEN
from slack_sdk.models.metadata import Metadata
from slack_sdk.web import WebClient


class TestWebClient(unittest.TestCase):

def setUp(self):
self.logger = logging.getLogger(__name__)
self.bot_token = os.environ[SLACK_SDK_TEST_BOT_TOKEN]

def tearDown(self):
pass

def test_publishing_message_metadata(self):
client: WebClient = WebClient(token=self.bot_token)
new_message = client.chat_postMessage(
channel='#random',
text="message with metadata",
metadata={
"event_type": "procurement-task",
"event_payload": {
"id": "11111",
"amount": 5000,
"tags": ["foo", "bar", "baz"]
},
}
)
self.assertIsNone(new_message.get("error"))
self.assertIsNotNone(new_message.get("message").get("metadata"))

history = client.conversations_history(
channel=new_message.get("channel"),
limit=1,
include_all_metadata=True,
)
self.assertIsNone(history.get("error"))
self.assertIsNotNone(history.get("messages")[0].get("metadata"))

modification = client.chat_update(
channel=new_message.get("channel"),
ts=new_message.get("ts"),
text="message with metadata (modified)",
metadata={
"event_type": "procurement-task",
"event_payload": {
"id": "11111",
"amount": 6000,
},
}
)
self.assertIsNone(modification.get("error"))
self.assertIsNotNone(modification.get("message").get("metadata"))

scheduled = client.chat_scheduleMessage(
channel=new_message.get("channel"),
post_at=int(time.time()) + 30,
text="message with metadata (scheduled)",
metadata={
"event_type": "procurement-task",
"event_payload": {
"id": "11111",
"amount": 10,
},
}
)
self.assertIsNone(scheduled.get("error"))
self.assertIsNotNone(scheduled.get("message").get("metadata"))

def test_publishing_message_metadata_using_models(self):
client: WebClient = WebClient(token=self.bot_token)
new_message = client.chat_postMessage(
channel='#random',
text="message with metadata",
metadata=Metadata(
event_type="procurement-task",
event_payload={
"id": "11111",
"amount": 5000,
"tags": ["foo", "bar", "baz"]
}
)
)
self.assertIsNone(new_message.get("error"))
self.assertIsNotNone(new_message.get("message").get("metadata"))

history = client.conversations_history(
channel=new_message.get("channel"),
limit=1,
include_all_metadata=True,
)
self.assertIsNone(history.get("error"))
self.assertIsNotNone(history.get("messages")[0].get("metadata"))

modification = client.chat_update(
channel=new_message.get("channel"),
ts=new_message.get("ts"),
text="message with metadata (modified)",
metadata=Metadata(
event_type="procurement-task",
event_payload={
"id": "11111",
"amount": 6000,
}
)
)
self.assertIsNone(modification.get("error"))
self.assertIsNotNone(modification.get("message").get("metadata"))

scheduled = client.chat_scheduleMessage(
channel=new_message.get("channel"),
post_at=int(time.time()) + 30,
text="message with metadata (scheduled)",
metadata=Metadata(
event_type="procurement-task",
event_payload={
"id": "11111",
"amount": 10,
}
)
)
self.assertIsNone(scheduled.get("error"))
self.assertIsNotNone(scheduled.get("message").get("metadata"))
30 changes: 30 additions & 0 deletions slack_sdk/models/metadata/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from typing import Dict, Any
from slack_sdk.models.basic_objects import JsonObject


class Metadata(JsonObject):
"""Message metadata

https://api.slack.com/metadta
seratch marked this conversation as resolved.
Show resolved Hide resolved
"""

attributes = {
"event_type",
"event_payload",
}

def __init__(
self,
event_type: str,
event_payload: Dict[str, Any],
**kwargs,
):
self.event_type = event_type
self.event_payload = event_payload
self.additional_attributes = kwargs

def __str__(self):
return str(self.get_non_null_attributes())

def __repr__(self):
return self.__str__()
9 changes: 9 additions & 0 deletions slack_sdk/web/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
)
from ..models.attachments import Attachment
from ..models.blocks import Block
from ..models.metadata import Metadata


class AsyncWebClient(AsyncBaseClient):
Expand Down Expand Up @@ -2098,6 +2099,7 @@ async def chat_postMessage(
link_names: Optional[bool] = None,
username: Optional[str] = None,
parse: Optional[str] = None, # none, full
metadata: Optional[Union[Dict, Metadata]] = None,
**kwargs,
) -> AsyncSlackResponse:
"""Sends a message to a channel.
Expand All @@ -2122,6 +2124,7 @@ async def chat_postMessage(
"link_names": link_names,
"username": username,
"parse": parse,
"metadata": metadata,
}
)
_parse_web_class_objects(kwargs)
Expand All @@ -2145,6 +2148,7 @@ async def chat_scheduleMessage(
unfurl_links: Optional[bool] = None,
unfurl_media: Optional[bool] = None,
link_names: Optional[bool] = None,
metadata: Optional[Union[Dict, Metadata]] = None,
**kwargs,
) -> AsyncSlackResponse:
"""Schedules a message.
Expand All @@ -2164,6 +2168,7 @@ async def chat_scheduleMessage(
"unfurl_links": unfurl_links,
"unfurl_media": unfurl_media,
"link_names": link_names,
"metadata": metadata,
}
)
_parse_web_class_objects(kwargs)
Expand Down Expand Up @@ -2215,6 +2220,7 @@ async def chat_update(
link_names: Optional[bool] = None,
parse: Optional[str] = None, # none, full
reply_broadcast: Optional[bool] = None,
metadata: Optional[Union[Dict, Metadata]] = None,
**kwargs,
) -> AsyncSlackResponse:
"""Updates a message in a channel.
Expand All @@ -2231,6 +2237,7 @@ async def chat_update(
"link_names": link_names,
"parse": parse,
"reply_broadcast": reply_broadcast,
"metadata": metadata,
}
)
if isinstance(file_ids, (list, Tuple)):
Expand Down Expand Up @@ -2375,6 +2382,7 @@ async def conversations_history(
channel: str,
cursor: Optional[str] = None,
inclusive: Optional[bool] = None,
include_all_metadata: Optional[bool] = None,
latest: Optional[str] = None,
limit: Optional[int] = None,
oldest: Optional[str] = None,
Expand All @@ -2388,6 +2396,7 @@ async def conversations_history(
"channel": channel,
"cursor": cursor,
"inclusive": inclusive,
"include_all_metadata": include_all_metadata,
"limit": limit,
"latest": latest,
"oldest": oldest,
Expand Down
9 changes: 9 additions & 0 deletions slack_sdk/web/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
)
from ..models.attachments import Attachment
from ..models.blocks import Block
from ..models.metadata import Metadata


class WebClient(BaseClient):
Expand Down Expand Up @@ -2047,6 +2048,7 @@ def chat_postMessage(
link_names: Optional[bool] = None,
username: Optional[str] = None,
parse: Optional[str] = None, # none, full
metadata: Optional[Union[Dict, Metadata]] = None,
**kwargs,
) -> SlackResponse:
"""Sends a message to a channel.
Expand All @@ -2071,6 +2073,7 @@ def chat_postMessage(
"link_names": link_names,
"username": username,
"parse": parse,
"metadata": metadata,
}
)
_parse_web_class_objects(kwargs)
Expand All @@ -2094,6 +2097,7 @@ def chat_scheduleMessage(
unfurl_links: Optional[bool] = None,
unfurl_media: Optional[bool] = None,
link_names: Optional[bool] = None,
metadata: Optional[Union[Dict, Metadata]] = None,
**kwargs,
) -> SlackResponse:
"""Schedules a message.
Expand All @@ -2113,6 +2117,7 @@ def chat_scheduleMessage(
"unfurl_links": unfurl_links,
"unfurl_media": unfurl_media,
"link_names": link_names,
"metadata": metadata,
}
)
_parse_web_class_objects(kwargs)
Expand Down Expand Up @@ -2164,6 +2169,7 @@ def chat_update(
link_names: Optional[bool] = None,
parse: Optional[str] = None, # none, full
reply_broadcast: Optional[bool] = None,
metadata: Optional[Union[Dict, Metadata]] = None,
**kwargs,
) -> SlackResponse:
"""Updates a message in a channel.
Expand All @@ -2180,6 +2186,7 @@ def chat_update(
"link_names": link_names,
"parse": parse,
"reply_broadcast": reply_broadcast,
"metadata": metadata,
}
)
if isinstance(file_ids, (list, Tuple)):
Expand Down Expand Up @@ -2324,6 +2331,7 @@ def conversations_history(
channel: str,
cursor: Optional[str] = None,
inclusive: Optional[bool] = None,
include_all_metadata: Optional[bool] = None,
latest: Optional[str] = None,
limit: Optional[int] = None,
oldest: Optional[str] = None,
Expand All @@ -2337,6 +2345,7 @@ def conversations_history(
"channel": channel,
"cursor": cursor,
"inclusive": inclusive,
"include_all_metadata": include_all_metadata,
"limit": limit,
"latest": latest,
"oldest": oldest,
Expand Down
9 changes: 8 additions & 1 deletion slack_sdk/web/internal_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from slack_sdk.errors import SlackRequestError
from slack_sdk.models.attachments import Attachment
from slack_sdk.models.blocks import Block
from slack_sdk.models.metadata import Metadata


def convert_bool_to_0_or_1(
Expand Down Expand Up @@ -180,11 +181,13 @@ def _build_req_args(


def _parse_web_class_objects(kwargs) -> None:
def to_dict(obj: Union[Dict, Block, Attachment]):
def to_dict(obj: Union[Dict, Block, Attachment, Metadata]):
if isinstance(obj, Block):
return obj.to_dict()
if isinstance(obj, Attachment):
return obj.to_dict()
if isinstance(obj, Metadata):
return obj.to_dict()
return obj

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

metadata = kwargs.get("metadata", None)
if metadata is not None and isinstance(metadata, Metadata):
kwargs.update({"metadata": to_dict(metadata)})


def _update_call_participants(
kwargs, users: Union[str, Sequence[Dict[str, str]]]
Expand Down
Loading