diff --git a/slack_sdk/models/messages/chunk.py b/slack_sdk/models/messages/chunk.py index 657d95ae4..a7dfc4de4 100644 --- a/slack_sdk/models/messages/chunk.py +++ b/slack_sdk/models/messages/chunk.py @@ -3,6 +3,7 @@ from slack_sdk.models import show_unknown_key_warning from slack_sdk.models.basic_objects import JsonObject +from slack_sdk.models.blocks import Block from slack_sdk.models.blocks.block_elements import UrlSourceElement @@ -32,7 +33,9 @@ def parse(cls, chunk: Union[Dict, "Chunk"]) -> Optional["Chunk"]: else: if "type" in chunk: type = chunk["type"] - if type == MarkdownTextChunk.type: + if type == BlocksChunk.type: + return BlocksChunk(**chunk) + elif type == MarkdownTextChunk.type: return MarkdownTextChunk(**chunk) elif type == PlanUpdateChunk.type: return PlanUpdateChunk(**chunk) @@ -132,3 +135,26 @@ def __init__( self.details = details self.output = output self.sources = sources + + +class BlocksChunk(Chunk): + type = "blocks" + + @property + def attributes(self) -> Set[str]: # type: ignore[override] + return super().attributes.union({"blocks"}) + + def __init__( + self, + *, + blocks: Sequence[Union[Dict, Block]], + **others: Dict, + ): + """Used for passing an array of blocks within a streaming message. + + https://docs.slack.dev/messaging/sending-and-scheduling-messages#text-streaming + """ + super().__init__(type=self.type) + show_unknown_key_warning(self, others) + + self.blocks = blocks diff --git a/tests/slack_sdk/models/test_chunks.py b/tests/slack_sdk/models/test_chunks.py index 78845b307..dd31d467f 100644 --- a/tests/slack_sdk/models/test_chunks.py +++ b/tests/slack_sdk/models/test_chunks.py @@ -1,7 +1,8 @@ import unittest +from slack_sdk.models.blocks import PlainTextObject, SectionBlock from slack_sdk.models.blocks.block_elements import UrlSourceElement -from slack_sdk.models.messages.chunk import MarkdownTextChunk, PlanUpdateChunk, TaskUpdateChunk +from slack_sdk.models.messages.chunk import BlocksChunk, Chunk, MarkdownTextChunk, PlanUpdateChunk, TaskUpdateChunk class MarkdownTextChunkTests(unittest.TestCase): @@ -89,3 +90,46 @@ def test_json(self): ], }, ) + + +class BlocksChunkTests(unittest.TestCase): + def test_json_with_dicts(self): + self.assertDictEqual( + BlocksChunk( + blocks=[ + {"type": "section", "text": {"type": "plain_text", "text": "Hello"}}, + ] + ).to_dict(), + { + "type": "blocks", + "blocks": [ + {"type": "section", "text": {"type": "plain_text", "text": "Hello"}}, + ], + }, + ) + + def test_json_with_block_objects(self): + self.assertDictEqual( + BlocksChunk( + blocks=[ + SectionBlock(text=PlainTextObject(text="Hello")), + ] + ).to_dict(), + { + "type": "blocks", + "blocks": [ + {"type": "section", "text": {"type": "plain_text", "text": "Hello"}}, + ], + }, + ) + + def test_parse(self): + chunk = Chunk.parse( + { + "type": "blocks", + "blocks": [{"type": "section", "text": {"type": "plain_text", "text": "Hello"}}], + } + ) + self.assertIsInstance(chunk, BlocksChunk) + self.assertEqual(chunk.type, "blocks") + self.assertEqual(len(chunk.blocks), 1)