Skip to content

Rich Text

Rich Text elements can be used to enhance text-based messages with code, list, quotations and formatted text (including options not available in traditional markdown like strikethrough).

These formatting elements can only be used within a RichTextBlock.

See: https://api.slack.com/reference/block-kit/blocks#rich_text.

Rich Text Elements (Primitives)

Rich text elements are the primitive elements used to populate the rich text object "containers", which are then fed into the RichTextBlock.

RichText

The core unit of the rich text API. Allows for the formatting of text with visual styles like bolding, italics and strikethroughs. Combined with higher-level containers like RichTextSection, RichText can be used to create complicated and deeply nested rich text within Slack messages.

Parameters:

Name Type Description Default
text str

the text content to render.

required
bold Optional[bool]

whether to render the given text in bold font.

None
italic Optional[bool]

whether to render the given text in italics.

None
strike Optional[bool]

whether to render the given text with a "strikethrough".

None
code Optional[bool]

whether to render the given text as an inline code snippet (monospaced).

None
Source code in slackblocks/rich_text/elements.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
class RichText(RichTextElement):
    """
    The core unit of the rich text API. Allows for the formatting of text
        with visual styles like bolding, italics and strikethroughs.
        Combined with higher-level containers like `RichTextSection`,
        `RichText` can be used to create complicated and deeply nested
        rich text within Slack messages.

    Args:
        text: the text content to render.
        bold: whether to render the given text in bold font.
        italic: whether to render the given text in italics.
        strike: whether to render the given text with a "strikethrough".
        code: whether to render the given text as an inline code snippet
            (monospaced).
    """

    def __init__(
        self,
        text: str,
        bold: Optional[bool] = None,
        italic: Optional[bool] = None,
        strike: Optional[bool] = None,
        code: Optional[bool] = None,
    ) -> None:
        super().__init__(type_=RichTextElementType.TEXT)
        self.text = text
        self.bold = bold
        self.italic = italic
        self.strike = strike
        self.code = code

    def _resolve(self) -> Dict[str, Any]:
        rich_text = super()._resolve()
        rich_text["text"] = self.text
        style = {}
        if self.bold is not None:
            style["bold"] = self.bold
        if self.italic is not None:
            style["italic"] = self.italic
        if self.strike is not None:
            style["strike"] = self.strike
        if self.code is not None:
            style["code"] = self.code
        if style:
            rich_text["style"] = style
        return rich_text

RichTextChannel

Rich text rendering of a Slack channel (e.g. #general).

See: https://api.slack.com/reference/block-kit/blocks#channel-element-type

Parameters:

Name Type Description Default
channel_id str

the ID of the channel to render. You can get this from the channel settings or the URL (if using Slack in the browser).

required
bold Optional[bool]

whether to render the given channel in bold font.

None
italic Optional[bool]

whether to render the given channel in italics.

None
strike Optional[bool]

whether to render the given channel with a "strikethrough".

None
highlight Optional[bool]

whether to give the channel a distinct highlight when rendered.

None
client_highlight Optional[bool]

???

None
unlink Optional[bool]

whether to remove the link to the channel from the channel when rendered.

None
Source code in slackblocks/rich_text/elements.py
 97
 98
 99
100
101
102
103
104
105
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
class RichTextChannel(RichTextElement):
    """
    Rich text rendering of a Slack channel (e.g. #general).

    See: <https://api.slack.com/reference/block-kit/blocks#channel-element-type>

    Args:
        channel_id: the ID of the channel to render. You can get this from
            the channel settings or the URL (if using Slack in the browser).
        bold: whether to render the given channel in bold font.
        italic: whether to render the given channel in italics.
        strike: whether to render the given channel with a "strikethrough".
        highlight: whether to give the channel a distinct highlight when rendered.
        client_highlight: ???
        unlink: whether to remove the link to the channel from the channel when
            rendered.
    """

    def __init__(
        self,
        channel_id: str,
        bold: Optional[bool] = None,
        italic: Optional[bool] = None,
        strike: Optional[bool] = None,
        highlight: Optional[bool] = None,
        client_highlight: Optional[bool] = None,
        unlink: Optional[bool] = None,
    ) -> None:
        super().__init__(RichTextElementType.CHANNEL)
        self.channel_id = channel_id
        self.bold = bold
        self.italic = italic
        self.strike = strike
        self.highlight = highlight
        self.client_highlight = client_highlight
        self.unlink = unlink

    def _resolve(self) -> Dict[str, Any]:
        channel = super()._resolve()
        channel["channel_id"] = self.channel_id
        style = {}
        if self.bold is not None:
            style["bold"] = self.bold
        if self.italic is not None:
            style["italic"] = self.italic
        if self.strike is not None:
            style["strike"] = self.strike
        if self.highlight is not None:
            style["highlight"] = self.highlight
        if self.client_highlight is not None:
            style["client_highlight"] = self.client_highlight
        if self.unlink is not None:
            style["unlink"] = self.unlink
        if style:
            channel["style"] = style
        return channel

RichTextEmoji

A rich text element for displaying an emoji.

The emoji can either be one built in to Slack or a custom workspace emoji.

See: https://api.slack.com/reference/block-kit/blocks#emoji-element-type

Parameters:

Name Type Description Default
name str

the unique name of the emoji to represent e.g. "wave".

required
Throws

InvalidUsageError: if the emoji name provided is empty.

Source code in slackblocks/rich_text/elements.py
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
class RichTextEmoji(RichTextElement):
    """
    A rich text element for displaying an emoji.

    The emoji can either be one built in to Slack or a custom workspace emoji.

    See: <https://api.slack.com/reference/block-kit/blocks#emoji-element-type>

    Args:
        name: the unique name of the emoji to represent e.g. "wave".

    Throws:
        InvalidUsageError: if the emoji `name` provided is empty.
    """

    def __init__(self, name: str) -> None:
        super().__init__(RichTextElementType.EMOJI)
        self.name = validate_string(name, field_name="name", min_length=1)

    def _resolve(self) -> Dict[str, Any]:
        emoji = super()._resolve()
        emoji["name"] = self.name
        return emoji

A rich text primitive to display links in text.

See: https://api.slack.com/reference/block-kit/blocks#link-element-type

Parameters:

Name Type Description Default
url str

the url which the link will point to.

required
text Optional[str]

the text to render with the link. If not provided, the raw URL will be used.

None
unsafe Optional[bool]

whether the link is "safe".

None
bold Optional[bool]

whether to render the given text in bold font.

None
italic Optional[bool]

whether to render the given text in italics.

None
strike Optional[bool]

whether to render the given text with a "strikethrough".

None
code Optional[bool]

whether to render the given text as an inline code snippet (monospaced).

None
Source code in slackblocks/rich_text/elements.py
180
181
182
183
184
185
186
187
188
189
190
191
192
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
class RichTextLink(RichTextElement):
    """
    A rich text primitive to display links in text.

    See: <https://api.slack.com/reference/block-kit/blocks#link-element-type>

    Args:
        url: the url which the link will point to.
        text: the text to render with the link. If not provided, the raw URL
            will be used.
        unsafe: whether the link is "safe".
        bold: whether to render the given text in bold font.
        italic: whether to render the given text in italics.
        strike: whether to render the given text with a "strikethrough".
        code: whether to render the given text as an inline code snippet
            (monospaced).
    """

    def __init__(
        self,
        url: str,
        text: Optional[str] = None,
        unsafe: Optional[bool] = None,
        bold: Optional[bool] = None,
        italic: Optional[bool] = None,
        strike: Optional[bool] = None,
        code: Optional[bool] = None,
    ) -> None:
        super().__init__(type_=RichTextElementType.LINK)
        self.url = url
        self.text = text
        self.unsafe = unsafe
        self.bold = bold
        self.italic = italic
        self.strike = strike
        self.code = code

    def _resolve(self) -> Dict[str, Any]:
        link = super()._resolve()
        link["url"] = self.url
        if self.text is not None:
            link["text"] = self.text
        if self.unsafe is not None:
            link["unsafe"] = self.unsafe
        style = {}
        if self.bold is not None:
            style["bold"] = self.bold
        if self.italic is not None:
            style["italic"] = self.italic
        if self.strike is not None:
            style["strike"] = self.strike
        if self.code is not None:
            style["code"] = self.code
        if style:
            link["style"] = style
        return link

RichTextUser

Rich text element for representing users in RichTextBlocks.

See: https://api.slack.com/reference/block-kit/blocks#user-element-type.

Parameters:

Name Type Description Default
user_id str

the Slack ID of the user in question, you can get these from users' profiles or Slack client requests.

required
bold Optional[bool]

whether to render the given user in bold font.

None
italic Optional[bool]

whether to render the given user in italics.

None
strike Optional[bool]

whether to render the given user with a "strikethrough".

None
highlight Optional[bool]

whether to give the user a distinct highlight when rendered.

None
client_highlight Optional[bool]

???

None
unlink Optional[bool]

whether to remove the link to the user from the channel when rendered.

None
Source code in slackblocks/rich_text/elements.py
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
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
class RichTextUser(RichTextElement):
    """
    Rich text element for representing users in
        [`RichTextBlocks`](reference/blocks/#blocks.RichTextBlock).

    See: <https://api.slack.com/reference/block-kit/blocks#user-element-type>.

    Args:
        user_id: the Slack ID of the user in question, you can get these
            from users' profiles or Slack client requests.
        bold: whether to render the given user in bold font.
        italic: whether to render the given user in italics.
        strike: whether to render the given user with a "strikethrough".
        highlight: whether to give the user a distinct highlight when rendered.
        client_highlight: ???
        unlink: whether to remove the link to the user from the channel when
            rendered.
    """

    def __init__(
        self,
        user_id: str,
        bold: Optional[bool] = None,
        italic: Optional[bool] = None,
        strike: Optional[bool] = None,
        highlight: Optional[bool] = None,
        client_highlight: Optional[bool] = None,
        unlink: Optional[bool] = None,
    ) -> None:
        super().__init__(RichTextElementType.USER)
        self.user_id = user_id
        self.bold = bold
        self.italic = italic
        self.strike = strike
        self.highlight = highlight
        self.client_highlight = client_highlight
        self.unlink = unlink

    def _resolve(self) -> Dict[str, Any]:
        user = super()._resolve()
        user["user_id"] = self.user_id
        style = {}
        if self.bold is not None:
            style["bold"] = self.bold
        if self.italic is not None:
            style["italic"] = self.italic
        if self.strike is not None:
            style["strike"] = self.strike
        if self.highlight is not None:
            style["highlight"] = self.highlight
        if self.client_highlight is not None:
            style["client_highlight"] = self.client_highlight
        if self.unlink is not None:
            style["unlink"] = self.unlink
        if style:
            user["style"] = style
        return user

RichTextUserGroup

Rich text element for representing groups of users in RichTextBlocks`.

See: https://api.slack.com/reference/block-kit/blocks#user-element-type.

Parameters:

Name Type Description Default
user_group_id str

the Slack ID of the user group being represented.

required
bold Optional[bool]

whether to render the given user in bold font.

None
italic Optional[bool]

whether to render the given user in italics.

None
strike Optional[bool]

whether to render the given user with a "strikethrough".

None
highlight Optional[bool]

whether to give the user a distinct highlight when rendered.

None
client_highlight Optional[bool]

???

None
unlink Optional[bool]

whether to remove the link to the user from the channel when rendered.

None
Source code in slackblocks/rich_text/elements.py
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
class RichTextUserGroup(RichTextElement):
    """
    Rich text element for representing groups of users in
        [`RichTextBlocks`](reference/blocks/#blocks.RichTextBlock)`.

    See: <https://api.slack.com/reference/block-kit/blocks#user-element-type>.

    Args:
        user_group_id: the Slack ID of the user group being represented.
        bold: whether to render the given user in bold font.
        italic: whether to render the given user in italics.
        strike: whether to render the given user with a "strikethrough".
        highlight: whether to give the user a distinct highlight when rendered.
        client_highlight: ???
        unlink: whether to remove the link to the user from the channel when
            rendered.
    """

    def __init__(
        self,
        user_group_id: str,
        bold: Optional[bool] = None,
        italic: Optional[bool] = None,
        strike: Optional[bool] = None,
        highlight: Optional[bool] = None,
        client_highlight: Optional[bool] = None,
        unlink: Optional[bool] = None,
    ) -> None:
        super().__init__(RichTextElementType.USER_GROUP)
        self.user_group_id = user_group_id
        self.bold = bold
        self.italic = italic
        self.strike = strike
        self.highlight = highlight
        self.client_highlight = client_highlight
        self.unlink = unlink

    def _resolve(self) -> Dict[str, Any]:
        user_group = super()._resolve()
        user_group["user_group_id"] = self.user_group_id
        style = {}
        if self.bold is not None:
            style["bold"] = self.bold
        if self.italic is not None:
            style["italic"] = self.italic
        if self.strike is not None:
            style["strike"] = self.strike
        if self.highlight is not None:
            style["highlight"] = self.highlight
        if self.client_highlight is not None:
            style["client_highlight"] = self.client_highlight
        if self.unlink is not None:
            style["unlink"] = self.unlink
        if style:
            user_group["style"] = style
        return user_group

Rich Text Objects (Containers)

Rich text objects are containers for rich text elements.

These obejects form the contents of the RichTextBlock.

ListType

An Enum that lists the available types of rich text lists.

  • ListType.BULLET: an unorderd (bulleted) list.
  • ListType.ORDERED: an ordered (numbered) list.
Source code in slackblocks/rich_text/objects.py
33
34
35
36
37
38
39
40
41
42
43
44
45
class ListType(Enum):
    """
    An `Enum` that lists the available types of rich text lists.

    - `ListType.BULLET`: an unorderd (bulleted) list.
    - `ListType.ORDERED`: an ordered (numbered) list.
    """

    BULLET = "bullet"
    ORDERED = "ordered"

    def all() -> List[str]:
        return [list_type.value for list_type in ListType]

RichTextCodeBlock

A rich text element for representing blocks of code in RichTextBlocks.

This is roughly equivalent to the triple-backtick ```code``` syntax in markdown.

See: https://api.slack.com/reference/block-kit/blocks#rich_text_preformatted.

Parameters:

Name Type Description Default
elements Union[RichTextElement, List[RichTextElement]]

one or more rich text primitive objexts (e.g. RichText).

required
border Optional[int]

the thickness (in pixels) of the border around the code block.

None
Throws

InvalidUsageError: if any of the items in elements aren't valid rich text elements.

Source code in slackblocks/rich_text/objects.py
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
191
192
193
194
195
196
197
198
199
200
201
202
class RichTextCodeBlock(RichTextObject):
    """
    A rich text element for representing blocks of code in
        [`RichTextBlocks`](reference/blocks/#blocks.RichTextBlock).

    This is roughly equivalent to the triple-backtick \`\`\``code`\`\`\` syntax in markdown.

    See: <https://api.slack.com/reference/block-kit/blocks#rich_text_preformatted>.

    Args:
        elements: one or more rich text primitive objexts
            (e.g. [`RichText`](/reference/rich_text/#rich_text.RichText)).
        border: the thickness (in pixels) of the border around the code block.

    Throws:
        InvalidUsageError: if any of the items in `elements` aren't valid rich
            text elements.
    """

    def __init__(
        self,
        elements: Union[RichTextElement, List[RichTextElement]],
        border: Optional[int] = None,
    ) -> None:
        super().__init__(type_=RichTextObjectType.PREFORMATTED)
        self.elements = coerce_to_list(
            elements,
            (
                RichText,
                RichTextChannel,
                RichTextEmoji,
                RichTextLink,
                RichTextUser,
                RichTextUserGroup,
            ),
        )
        self.border = border

    def _resolve(self) -> Dict[str, Any]:
        preformatted = super()._resolve()
        preformatted["elements"] = [element._resolve() for element in self.elements]
        if self.border is not None:
            preformatted["border"] = self.border
        return preformatted

RichTextList

Renders to a HTML list containing rich text elements.

See: https://api.slack.com/reference/block-kit/blocks#rich_text_list.

Parameters:

Name Type Description Default
style Union[str, ListType]

one of ListType.BULLET or ListType.ORDERED.

required
elements Union[RichTextSection, List[RichTextSection]]

a list of (possibly nested) RichTextSection elements. Each object in this list will be rendered as a list item.

required
indent Optional[int]

indent (in pixels) of each list item.

None
offset Optional[int]

offset (in pixels) of each list item.

0
border Optional[int]

thickness (in pixels) of the (optional) border around the list.

0
Throws

InvalidUsageError: if style is not a valid ListType or any of the items in elements isn't a valid RichTextSection.

Source code in slackblocks/rich_text/objects.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
156
class RichTextList(RichTextObject):
    """
    Renders to a HTML list containing rich text elements.

    See: <https://api.slack.com/reference/block-kit/blocks#rich_text_list>.

    Args:
        style: one of `ListType.BULLET` or `ListType.ORDERED`.
        elements: a list of (possibly nested) `RichTextSection` elements.
            Each object in this list will be rendered as a list item.
        indent: indent (in pixels) of each list item.
        offset: offset (in pixels) of each list item.
        border: thickness (in pixels) of the (optional) border around the list.

    Throws:
        InvalidUsageError: if style is not a valid `ListType` or any of the
            items in `elements` isn't a valid `RichTextSection`.
    """

    def __init__(
        self,
        style: Union[str, ListType],
        elements: Union[RichTextSection, List[RichTextSection]],
        indent: Optional[int] = None,
        offset: Optional[int] = 0,
        border: Optional[int] = 0,
    ) -> None:
        super().__init__(type_=RichTextObjectType.LIST)
        if isinstance(style, str):
            if style in ListType.all():
                self.style = style
            else:
                raise InvalidUsageError(f"`style` must be one of [{ListType.all()}]")
        elif isinstance(style, ListType):
            self.style = style.value
        self.elements = coerce_to_list(elements, RichTextSection, min_size=1)
        self.indent = validate_int(indent, allow_none=True)
        self.offset = validate_int(offset, allow_none=True)
        self.border = validate_int(border, allow_none=True)

    def _resolve(self) -> Dict[str, Any]:
        rich_text_list = super()._resolve()
        rich_text_list["elements"] = [element._resolve() for element in self.elements]
        rich_text_list["style"] = self.style
        if self.indent is not None:
            rich_text_list["indent"] = self.indent
        if self.offset is not None:
            rich_text_list["offset"] = self.offset
        if self.border is not None:
            rich_text_list["border"] = self.border
        return rich_text_list

RichTextQuote

A rich text object for representing a block quote.

Block quotes are presented with a vertical bar to the left hand side of the text.

See: https://api.slack.com/reference/block-kit/blocks#rich_text_quote

Parameters:

Name Type Description Default
elements Union[RichTextElement, List[RichTextElement]]

one or more rich text primitive objexts (e.g. RichText).

required
border Optional[int]

the thickness (in pixels) of the border around the code block.

None
Source code in slackblocks/rich_text/objects.py
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
class RichTextQuote(RichTextObject):
    """
    A rich text object for representing a block quote.

    Block quotes are presented with a vertical bar to the left hand side of
        the text.

    See: <https://api.slack.com/reference/block-kit/blocks#rich_text_quote>

    Args:
        elements: one or more rich text primitive objexts
            (e.g. [`RichText`](/reference/rich_text/#rich_text.RichText)).
        border: the thickness (in pixels) of the border around the code block.
    """

    def __init__(
        self,
        elements: Union[RichTextElement, List[RichTextElement]],
        border: Optional[int] = None,
    ) -> None:
        super().__init__(RichTextObjectType.QUOTE)
        self.elements = coerce_to_list(
            elements,
            (
                RichText,
                RichTextChannel,
                RichTextEmoji,
                RichTextLink,
                RichTextUser,
                RichTextUserGroup,
            ),
        )
        self.border = border

    def _resolve(self) -> Dict[str, Any]:
        quote = super()._resolve()
        quote["elements"] = [element._resolve() for element in self.elements]
        if self.border is not None:
            quote["border"] = self.border
        return quote

RichTextSection

The most basic rich text container object, which takes rich text elements and renders them when RichTextSection is passed to a RichTextBlock.

See: https://api.slack.com/reference/block-kit/blocks#rich_text_section.

Parameters:

Name Type Description Default
elements Union[RichTextElement, List[RichTextElement]]

one or more rich text elements that will form the content of the section. e.g. RichText, RichTextLink.

required
Throws

InvalidUsageError: if any of the items passed to elements isn't a valid RichTextObject.

Source code in slackblocks/rich_text/objects.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
class RichTextSection(RichTextObject):
    """
    The most basic rich text container object, which takes rich text elements
        and renders them when `RichTextSection` is passed to a
        [`RichTextBlock`](/reference/blocks/#blocks.RichTextBlock).

    See: <https://api.slack.com/reference/block-kit/blocks#rich_text_section>.

    Args:
        elements: one or more rich text elements that will form the content of the section.
            e.g. `RichText`, `RichTextLink`.

    Throws:
        InvalidUsageError: if any of the items passed to `elements` isn't a valid
            `RichTextObject`.
    """

    def __init__(self, elements: Union[RichTextElement, List[RichTextElement]]) -> None:
        super().__init__(type_=RichTextObjectType.SECTION)
        self.elements = coerce_to_list(
            elements,
            class_=(
                RichTextChannel,
                RichTextEmoji,
                RichTextLink,
                RichText,
                RichTextUser,
                RichTextUserGroup,
            ),
            min_size=1,
        )

    def _resolve(self) -> Dict[str, Any]:
        section = super()._resolve()
        section["elements"] = [element._resolve() for element in self.elements]
        return section