Skip to content

Messages

Messages are the top-level objects you send to Slack. slackblocks provides several message types depending on the API surface you're targeting:

Class When to use it
Message Posting a normal message via chat.postMessage (the most common case).
WebhookMessage Sending to an Incoming Webhook URL.
MessageResponse Replying to a slash command or an interaction response_url.

All three implement __getitem__/keys(), so you can unpack them with **message straight into the Slack SDK. See Sending Messages for end-to-end examples.

Slack reference: https://api.slack.com/methods/chat.postMessage

Messages are the core unit of Slack messaging functionality. They can be built out using blocks, elements, objects, and rich text features.

See: https://api.slack.com/messaging

Message

A Slack message object that can be converted to a JSON string for use with the Slack message API.

Parameters:

Name Type Description Default
channel str

the Slack channel to send the message to, e.g. "#general".

required
text str | None

markdown text to send in the message. If blocks are provided then this is a fallback to display in notifications.

''
blocks list[Block] | Block | None

a list of Blocks to form the contents of the message instead of the contents of text.

None
attachments list[Attachment] | None

a list of Attachments that form the secondary contents of the message (deprecated).

None
thread_ts str | None

the timestamp ID of another unthreaded message that will become the parent message of this message (now a reply in a thread).

None
mrkdwn bool

if True the contents of text will be rendered as markdown rather than plain text.

True
unfurl_links bool | None

if True, links in the message will be automatically unfurled.

None
unfurl_media bool | None

if True, media from links (e.g. images) will automatically unfurl.

None

Throws: InvalidUsageException: in the event that the items passed to blocks are not valid Blocks.

Source code in slackblocks/messages.py
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
class Message(BaseMessage):
    """
    A Slack message object that can be converted to a JSON string for use with
    the Slack message API.

    Args:
        channel: the Slack channel to send the message to, e.g. "#general".
        text: markdown text to send in the message. If `blocks` are provided
            then this is a fallback to display in notifications.
        blocks: a list of [`Blocks`](/slackblocks/latest/reference/blocks) to form the contents
            of the message instead of the contents of `text`.
        attachments: a list of
            [`Attachments`](/slackblocks/latest/reference/attachments/#attachments.Attachment)
            that form the secondary contents of the message (deprecated).
        thread_ts: the timestamp ID of another unthreaded message that will
            become the parent message of this message (now a reply in a thread).
        mrkdwn: if `True` the contents of `text` will be rendered as markdown
            rather than plain text.
        unfurl_links: if `True`, links in the message will be automatically
            unfurled.
        unfurl_media: if `True`, media from links (e.g. images) will
            automatically unfurl.
    Throws:
        InvalidUsageException: in the event that the items passed to `blocks`
            are not valid [`Blocks`](/slackblocks/latest/reference/blocks).
    """

    def __init__(
        self,
        channel: str,
        text: str | None = "",
        blocks: list[Block] | Block | None = None,
        attachments: list[Attachment] | None = None,
        thread_ts: str | None = None,
        mrkdwn: bool = True,
        unfurl_links: bool | None = None,
        unfurl_media: bool | None = None,
    ) -> None:
        super().__init__(channel, text, blocks, attachments, thread_ts, mrkdwn)
        self.unfurl_links = unfurl_links
        self.unfurl_media = unfurl_media

    def _resolve(self) -> dict[str, Any]:
        return resolve(
            {
                **super()._resolve(),
                "unfurl_links": self.unfurl_links,
                "unfurl_media": self.unfurl_media,
            }
        )

MessageResponse

A required, immediate response that confirms your app received the payload.

Source code in slackblocks/messages.py
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
class MessageResponse(BaseMessage):
    """
    A required, immediate response that confirms your app received the payload.
    """

    def __init__(
        self,
        text: str | None = "",
        blocks: list[Block] | Block | None = None,
        attachments: list[Attachment] | None = None,
        thread_ts: str | None = None,
        mrkdwn: bool = True,
        replace_original: bool = False,
        ephemeral: bool = False,
    ) -> None:
        super().__init__(
            text=text,
            blocks=blocks,
            attachments=attachments,
            thread_ts=thread_ts,
            mrkdwn=mrkdwn,
        )
        self.replace_original = replace_original
        self.ephemeral = ephemeral

    def _resolve(self) -> dict[str, Any]:
        return resolve(
            {
                **super()._resolve(),
                "replace_original": self.replace_original,
                "response_type": "ephemeral" if self.ephemeral else None,
            }
        )

ResponseType

Types of messages that can be sent via WebhookMessage.

Source code in slackblocks/messages.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class ResponseType(Enum):
    """
    Types of messages that can be sent via `WebhookMessage`.
    """

    EPHEMERAL = "ephemeral"
    IN_CHANNEL = "in_channel"

    @staticmethod
    def get_value(value: ResponseType | str) -> str:
        if isinstance(value, ResponseType):
            return value.value
        if value not in [response_type.value for response_type in ResponseType]:
            raise TypeMismatchError("ResponseType must be either `ephemeral` or `in_channel`")
        return value

WebhookMessage

Messages sent via the Slack WebhookClient takes different arguments than those sent via the regular WebClient.

See: https://github.com/slackapi/python-slack-sdk/blob/7e71b73/slack_sdk/webhook/client.py#L28

Parameters:

Name Type Description Default
text str | None

markdown text to send in the message. If blocks are provided then this is a fallback to display in notifications.

None
attachments Attachment | list[Attachment] | None

a list of Attachments that form the secondary contents of the message (deprecated).

None
blocks Block | list[Block] | None

a list of Blocks to form the contents of the message instead of the contents of text.

None
response_type ResponseType | str | None

one of ResponseType.EPHEMERAL or ResponseType.IN_CHANNEL. Ephemeral messages are shown only to the requesting user whereas "in-channel" messages are shown to all channel participants.

None
replace_original bool | None

when True, the message triggering this response will be replaced by this message. Mutually exclusive with delete_original.

None
delete_original bool | None

when True, the original message triggering this response will be deleted, and any content of this message will be posted as a new message. Mutually exclusive with replace_original.

None
unfurl_links bool | None

if True, links in the message will be automatically unfurled.

None
unfurl_media bool | None

if True, media from links (e.g. images) will automatically unfurl.

None
metadata dict[str, Any] | None

additional metadata to attach to the message.

None
headers dict[str, str] | None

HTTP request headers to include with the message.

None
Throws

InvalidUsageError: when any of the passed fields fail validation.

Source code in slackblocks/messages.py
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
class WebhookMessage(_MessagePayloadMixin):
    """
    Messages sent via the Slack `WebhookClient` takes different arguments than
        those sent via the regular `WebClient`.

    See: <https://github.com/slackapi/python-slack-sdk/blob/7e71b73/slack_sdk/webhook/client.py#L28>

    Args:
        text: markdown text to send in the message. If `blocks` are provided
            then this is a fallback to display in notifications.
        attachments: a list of
            [`Attachments`](/slackblocks/latest/reference/attachments/#attachments.Attachment)
            that form the secondary contents of the message (deprecated).
        blocks: a list of [`Blocks`](/slackblocks/latest/reference/blocks) to form the contents
            of the message instead of the contents of `text`.
        response_type: one of `ResponseType.EPHEMERAL` or `ResponseType.IN_CHANNEL`.
            Ephemeral messages are shown only to the requesting user whereas
            "in-channel" messages are shown to all channel participants.
        replace_original: when `True`, the message triggering this response will be
            replaced by this message. Mutually exclusive with `delete_original`.
        delete_original: when `True`, the original message triggering this response
            will be deleted, and any content of this message will be posted as a
            new message. Mutually exclusive with `replace_original`.
        unfurl_links: if `True`, links in the message will be automatically
            unfurled.
        unfurl_media: if `True`, media from links (e.g. images) will
            automatically unfurl.
        metadata: additional metadata to attach to the message.
        headers: HTTP request headers to include with the message.

    Throws:
        InvalidUsageError: when any of the passed fields fail validation.
    """

    def __init__(
        self,
        text: str | None = None,
        attachments: Attachment | list[Attachment] | None = None,
        blocks: Block | list[Block] | None = None,
        response_type: ResponseType | str | None = None,
        replace_original: bool | None = None,
        delete_original: bool | None = None,
        unfurl_links: bool | None = None,
        unfurl_media: bool | None = None,
        metadata: dict[str, Any] | None = None,
        headers: dict[str, str] | None = None,
    ) -> None:
        self.text = text
        self.attachments: list[Attachment] | None = coerce_to_list(
            attachments, Attachment, allow_none=True
        )
        self.blocks: list[Block] | None = coerce_to_list(blocks, Block, allow_none=True)
        self.response_type = (
            ResponseType.get_value(response_type) if response_type is not None else None
        )
        self.replace_original = replace_original
        self.delete_original = delete_original
        self.unfurl_links = unfurl_links
        self.unfurl_media = unfurl_media
        self.metadata = metadata
        self.headers = headers

    def _resolve(self) -> dict[str, Any]:
        return resolve(
            {
                "text": self.text,
                "attachments": [att for att in self.attachments if att is not None]
                if self.attachments is not None
                else None,
                "blocks": [block for block in self.blocks if block is not None]
                if self.blocks is not None
                else None,
                "response_type": self.response_type,
                "replace_original": self.replace_original,
                "delete_original": self.delete_original,
                "unfurl_links": self.unfurl_links,
                "unfurl_media": self.unfurl_media,
                "metadata": self.metadata,
                "headers": self.headers,
            }
        )

_MessagePayloadMixin

Shared serialization helpers used by both BaseMessage and WebhookMessage.

Both expose the same interface (to_dict(), json(), __repr__, __getitem__, keys()) so that **msg unpacking works with the Slack Web/Webhook clients. Concrete subclasses must implement _resolve.

Source code in slackblocks/messages.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
class _MessagePayloadMixin:
    """Shared serialization helpers used by both BaseMessage and
    WebhookMessage.

    Both expose the same interface (``to_dict()``, ``json()``, ``__repr__``,
    ``__getitem__``, ``keys()``) so that ``**msg`` unpacking works with the
    Slack Web/Webhook clients. Concrete subclasses must implement
    ``_resolve``."""

    def _resolve(self) -> dict[str, Any]:  # pragma: no cover - overridden
        raise NotImplementedError

    def to_dict(self) -> dict[str, Any]:
        return self._resolve()

    def json(self) -> str:
        return dumps(self._resolve(), indent=4)

    def __repr__(self) -> str:
        return self.json()

    def __getitem__(self, item):
        return self._resolve()[item]

    def keys(self) -> list[str]:
        return list(self._resolve().keys())