diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..db99e6e9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +docs/reference/**/*.html linguist-generated=true diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 841cb37e..523b32e1 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -28,6 +28,7 @@ jobs: env: CI_LARGE_SOCKET_MODE_PAYLOAD_TESTING_DISABLED: "1" FORCE_COLOR: "1" + LATEST_PYTHON_VERSION: "3.13" steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: @@ -53,6 +54,14 @@ jobs: pip install "SQLAlchemy>=1.4,<2" PYTHONPATH=$PWD:$PYTHONPATH pytest tests/slack_sdk/oauth/installation_store/test_sqlalchemy.py PYTHONPATH=$PWD:$PYTHONPATH pytest tests/slack_sdk/oauth/state_store/test_sqlalchemy.py + - name: Confirm expected autogenerated reference exists + if: startsWith(matrix.python-version, env.LATEST_PYTHON_VERSION) + run: | + python -m venv .venv + source .venv/bin/activate + bash ./scripts/generate_api_docs.sh + git diff + git diff --quiet - name: Upload test results to Codecov if: ${{ !cancelled() }} uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1.1.1 @@ -62,7 +71,7 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} verbose: true - name: Upload test coverage to Codecov (only with latest supported version) - if: startsWith(matrix.python-version, '3.13') + if: startsWith(matrix.python-version, env.LATEST_PYTHON_VERSION) uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 with: token: ${{ secrets.CODECOV_TOKEN }} diff --git a/docs/reference/index.html b/docs/reference/index.html index 8b9b9e3f..9b6a27e0 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -1856,7 +1856,7 @@
-def admin_users_list(self,
*,
team_id: str,
include_deactivated_user_workspaces: bool | None = None,
is_active: bool | None = None,
cursor: str | None = None,
limit: int | None = None,
**kwargs) ‑> SlackResponse
+def admin_users_list(self,
*,
team_id: str | None = None,
include_deactivated_user_workspaces: bool | None = None,
is_active: bool | None = None,
cursor: str | None = None,
limit: int | None = None,
**kwargs) ‑> SlackResponse
 def admin_users_list(
     self,
     *,
-    team_id: str,
+    team_id: Optional[str] = None,
     include_deactivated_user_workspaces: Optional[bool] = None,
     is_active: Optional[bool] = None,
     cursor: Optional[str] = None,
@@ -9866,7 +9940,7 @@ Methods
 https://api.slack.com/methods/chat.meMessage
 
-def chat_postEphemeral(self,
*,
channel: str,
user: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
**kwargs) ‑> SlackResponse
+def chat_postEphemeral(self,
*,
channel: str,
user: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
-def chat_postMessage(self,
*,
channel: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
container_id: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
mrkdwn: bool | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> SlackResponse
+def chat_postMessage(self,
*,
channel: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
container_id: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
mrkdwn: bool | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
-def chat_scheduleMessage(self,
*,
channel: str,
post_at: str | int,
text: str,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
link_names: bool | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> SlackResponse
+def chat_scheduleMessage(self,
*,
channel: str,
post_at: str | int,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
link_names: bool | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
-def chat_update(self,
*,
channel: str,
ts: str,
text: str | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
as_user: bool | None = None,
file_ids: str | Sequence[str] | None = None,
link_names: bool | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> SlackResponse
+def chat_update(self,
*,
channel: str,
ts: str,
text: str | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
as_user: bool | None = None,
file_ids: str | Sequence[str] | None = None,
link_names: bool | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
+def workflows_featured_add(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_add(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """Add featured workflows to a channel.
+    https://api.slack.com/methods/workflows.featured.add
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.add", params=kwargs)Add featured workflows to a channel. +https://api.slack.com/methods/workflows.featured.add
+def workflows_featured_list(self, *, channel_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_list(
+    self,
+    *,
+    channel_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """List the featured workflows for specified channels.
+    https://api.slack.com/methods/workflows.featured.list
+    """
+    if isinstance(channel_ids, (list, tuple)):
+        kwargs.update({"channel_ids": ",".join(channel_ids)})
+    else:
+        kwargs.update({"channel_ids": channel_ids})
+    return self.api_call("workflows.featured.list", params=kwargs)List the featured workflows for specified channels. +https://api.slack.com/methods/workflows.featured.list
+def workflows_featured_remove(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_remove(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """Remove featured workflows from a channel.
+    https://api.slack.com/methods/workflows.featured.remove
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.remove", params=kwargs)Remove featured workflows from a channel. +https://api.slack.com/methods/workflows.featured.remove
+def workflows_featured_set(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_set(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """Set featured workflows for a channel.
+    https://api.slack.com/methods/workflows.featured.set
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.set", params=kwargs)Set featured workflows for a channel. +https://api.slack.com/methods/workflows.featured.set
 def workflows_stepCompleted(self, *, workflow_step_execute_id: str, outputs: dict | None = None, **kwargs) ‑> SlackResponse
 WebClient
 views_publishviews_pushviews_updateworkflows_featured_addworkflows_featured_listworkflows_featured_removeworkflows_featured_setworkflows_stepCompletedworkflows_stepFailedworkflows_updateStepClasses
 Expand source code
 
 class ConfirmObject(JsonObject):
-    attributes = {}  # type: ignore[assignment] # no attributes because to_dict has unique implementations
+    attributes: Set[str] = set()
 
     title_max_length = 100
     text_max_length = 300
@@ -164,7 +164,7 @@ Ancestors
 
 Class variables
 
-- var attributes
+- var attributes : Set[str]
- 
 The type of the None singleton. 
@@ -546,7 +546,7 @@Inherited members
     different required formats in different situations
     """
 
-    attributes = {}  # type: ignore[assignment] # no attributes because to_dict has unique implementations
+    attributes: Set[str] = set()
     logger = logging.getLogger(__name__)
 
     label_max_length = 75
@@ -719,7 +719,7 @@ Ancestors
 
 Class variables
 
-- var attributes
+- var attributes : Set[str]
- 
 The type of the None singleton. 
@@ -828,7 +828,7 @@Inherited members
     different required formats in different situations
     """
 
-    attributes = {}  # type: ignore[assignment] # no attributes because to_dict has unique implementations
+    attributes: Set[str] = set()
     label_max_length = 75
     options_max_length = 100
     logger = logging.getLogger(__name__)
@@ -932,7 +932,7 @@ Ancestors
 
 Class variables
 
-- var attributes
+- var attributes : Set[str]
- 
 The type of the None singleton. 
diff --git a/docs/reference/models/blocks/blocks.html b/docs/reference/models/blocks/blocks.html
index a995554f..efb2e41a 100644
--- a/docs/reference/models/blocks/blocks.html
+++ b/docs/reference/models/blocks/blocks.html
@@ -228,6 +228,8 @@Inherited members
                     return CallBlock(**block)
                 elif type == HeaderBlock.type:
                     return HeaderBlock(**block)
+                elif type == MarkdownBlock.type:
+                    return MarkdownBlock(**block)
                 elif type == VideoBlock.type:
                     return VideoBlock(**block)
                 elif type == RichTextBlock.type:
@@ -261,6 +263,7 @@ Subclasses
 
HeaderBlock 
 ImageBlock 
 InputBlock 
+MarkdownBlock 
 RichTextBlock 
 SectionBlock 
 VideoBlock 
@@ -1098,6 +1101,113 @@ Inherited members
 
 
 
+
+class MarkdownBlock
+(*, text: str, block_id: str | None = None, **others: dict)
+
+
+
+Expand source code
+
+class MarkdownBlock(Block):
+    type = "markdown"
+    text_max_length = 12000
+
+    @property
+    def attributes(self) -> Set[str]:  # type: ignore[override]
+        return super().attributes.union({"text"})
+
+    def __init__(
+        self,
+        *,
+        text: str,
+        block_id: Optional[str] = None,
+        **others: dict,
+    ):
+        """Displays formatted markdown.
+        https://docs.slack.dev/reference/block-kit/blocks/markdown-block/
+
+        Args:
+            block_id: A string acting as a unique identifier for a block. If not specified, one will be generated.
+                Maximum length for this field is 255 characters.
+                block_id should be unique for each message and each iteration of a message.
+                If a message is updated, use a new block_id.
+            text (required): The standard markdown-formatted text. Limit 12,000 characters max.
+        """
+        super().__init__(type=self.type, block_id=block_id)
+        show_unknown_key_warning(self, others)
+
+        self.text = text
+
+    @JsonValidator("text attribute must be specified")
+    def _validate_text(self):
+        return self.text != ""
+
+    @JsonValidator(f"text attribute cannot exceed {text_max_length} characters")
+    def _validate_alt_text_length(self):
+        return len(self.text) <= self.text_max_length
+
+Blocks are a series of components that can be combined
+to create visually rich and compellingly interactive messages.
+https://api.slack.com/reference/block-kit/blocks
+Displays formatted markdown.
+https://docs.slack.dev/reference/block-kit/blocks/markdown-block/
+Args
+
+- block_id
+- A string acting as a unique identifier for a block. If not specified, one will be generated.
+Maximum length for this field is 255 characters.
+block_id should be unique for each message and each iteration of a message.
+If a message is updated, use a new block_id.+
- text:- required
+- The standard markdown-formatted text. Limit 12,000 characters max.+
+Ancestors
+
+- Block+
- JsonObject+
- BaseObject+
+Class variables
+
+- var text_max_length
+- 
+The type of the None singleton. +
+- var type
+- 
+The type of the None singleton. +
+
+Instance variables
+
+- prop attributes : Set[str]
+- 
+
+
+Expand source code
++@property
+def attributes(self) -> Set[str]:  # type: ignore[override]
+    return super().attributes.union({"text"})
 +
+Build an unordered collection of unique elements. +
+
+Inherited members
+
+- Block:
+
+
+
+ 
 
 class RichTextBlock
 (*,
elements: Sequence[dict | RichTextElement],
block_id: str | None = None,
**others: dict)
@@ -1652,6 +1762,14 @@ MarkdownBlock
+
+
+
 RichTextBlock
 
 - attributes
diff --git a/docs/reference/models/blocks/index.html b/docs/reference/models/blocks/index.html
index d3327ac9..7a69ec6e 100644
--- a/docs/reference/models/blocks/index.html
+++ b/docs/reference/models/blocks/index.html
@@ -250,6 +250,8 @@Inherited members
                     return CallBlock(**block)
                 elif type == HeaderBlock.type:
                     return HeaderBlock(**block)
+                elif type == MarkdownBlock.type:
+                    return MarkdownBlock(**block)
                 elif type == VideoBlock.type:
                     return VideoBlock(**block)
                 elif type == RichTextBlock.type:
@@ -283,6 +285,7 @@ Subclasses
 - HeaderBlock
- ImageBlock
- InputBlock+
- MarkdownBlock
- RichTextBlock
- SectionBlock
- VideoBlock@@ -1130,7 +1133,7 @@
Inherited members
 Expand source code
 
 
class ConfirmObject(JsonObject):
-    attributes = {}  # type: ignore[assignment] # no attributes because to_dict has unique implementations
+    attributes: Set[str] = set()
 
     title_max_length = 100
     text_max_length = 300
@@ -1238,7 +1241,7 @@ Ancestors
 
 Class variables
 
-- var attributes
+- var attributes : Set[str]
- 
 The type of the None singleton. 
@@ -3579,6 +3582,113 @@Inherited members
 
 
 
 
+
+class MarkdownBlock
+(*, text: str, block_id: str | None = None, **others: dict)
+
+
+
+Expand source code
+
+class MarkdownBlock(Block):
+    type = "markdown"
+    text_max_length = 12000
+
+    @property
+    def attributes(self) -> Set[str]:  # type: ignore[override]
+        return super().attributes.union({"text"})
+
+    def __init__(
+        self,
+        *,
+        text: str,
+        block_id: Optional[str] = None,
+        **others: dict,
+    ):
+        """Displays formatted markdown.
+        https://docs.slack.dev/reference/block-kit/blocks/markdown-block/
+
+        Args:
+            block_id: A string acting as a unique identifier for a block. If not specified, one will be generated.
+                Maximum length for this field is 255 characters.
+                block_id should be unique for each message and each iteration of a message.
+                If a message is updated, use a new block_id.
+            text (required): The standard markdown-formatted text. Limit 12,000 characters max.
+        """
+        super().__init__(type=self.type, block_id=block_id)
+        show_unknown_key_warning(self, others)
+
+        self.text = text
+
+    @JsonValidator("text attribute must be specified")
+    def _validate_text(self):
+        return self.text != ""
+
+    @JsonValidator(f"text attribute cannot exceed {text_max_length} characters")
+    def _validate_alt_text_length(self):
+        return len(self.text) <= self.text_max_length
+
+Blocks are a series of components that can be combined
+to create visually rich and compellingly interactive messages.
+https://api.slack.com/reference/block-kit/blocks
+Displays formatted markdown.
+https://docs.slack.dev/reference/block-kit/blocks/markdown-block/
+Args
+
+- block_id
+- A string acting as a unique identifier for a block. If not specified, one will be generated.
+Maximum length for this field is 255 characters.
+block_id should be unique for each message and each iteration of a message.
+If a message is updated, use a new block_id.+
- text:- required
+- The standard markdown-formatted text. Limit 12,000 characters max.+
+Ancestors
+
+- Block+
- JsonObject+
- BaseObject+
+Class variables
+
+- var text_max_length
+- 
+The type of the None singleton. +
+- var type
+- 
+The type of the None singleton. +
+
+Instance variables
+
+- prop attributes : Set[str]
+- 
+
+
+Expand source code
++@property
+def attributes(self) -> Set[str]:  # type: ignore[override]
+    return super().attributes.union({"text"})
 +
+Build an unordered collection of unique elements. +
+
+Inherited members
+
+- Block:
+
+
+
+ 
 
 class MarkdownTextObject
 (*, text: str, verbatim: bool | None = None)
@@ -3936,7 +4046,7 @@ Inherited members
     different required formats in different situations
     """
 
-    attributes = {}  # type: ignore[assignment] # no attributes because to_dict has unique implementations
+    attributes: Set[str] = set()
     logger = logging.getLogger(__name__)
 
     label_max_length = 75
@@ -4109,7 +4219,7 @@ Ancestors
 
 Class variables
 
-- var attributes
+- var attributes : Set[str]
- 
 The type of the None singleton. 
@@ -4218,7 +4328,7 @@Inherited members
     different required formats in different situations
     """
 
-    attributes = {}  # type: ignore[assignment] # no attributes because to_dict has unique implementations
+    attributes: Set[str] = set()
     label_max_length = 75
     options_max_length = 100
     logger = logging.getLogger(__name__)
@@ -4322,7 +4432,7 @@ Ancestors
 
 Class variables
 
-- var attributes
+- var attributes : Set[str]
- 
 The type of the None singleton. 
@@ -7465,6 +7575,14 @@LinkButtonElement
 
 
+MarkdownBlock
+
+ 
+
 MarkdownTextObject
 
 - attributes
diff --git a/docs/reference/models/dialoags.html b/docs/reference/models/dialoags.html
index 2657bdbe..d850bd9c 100644
--- a/docs/reference/models/dialoags.html
+++ b/docs/reference/models/dialoags.html
@@ -247,7 +247,7 @@Inherited members
 Expand source code
 
 
class DialogBuilder(JsonObject):
-    attributes = {}  # type: ignore[assignment] # no attributes because to_dict has unique implementation
+    attributes: Set[str] = set()
 
     _callback_id: Optional[str]
     _elements: List[Union[DialogTextComponent, AbstractDialogSelector]]
@@ -687,7 +687,7 @@ Ancestors
 
 Class variables
 
-- var attributes
+- var attributes : Set[str]
- 
 The type of the None singleton. 
diff --git a/docs/reference/models/dialogs/index.html b/docs/reference/models/dialogs/index.html
index d077673e..85cc3757 100644
--- a/docs/reference/models/dialogs/index.html
+++ b/docs/reference/models/dialogs/index.html
@@ -247,7 +247,7 @@Inherited members
 Expand source code
 
 class DialogBuilder(JsonObject):
-    attributes = {}  # type: ignore[assignment] # no attributes because to_dict has unique implementation
+    attributes: Set[str] = set()
 
     _callback_id: Optional[str]
     _elements: List[Union[DialogTextComponent, AbstractDialogSelector]]
@@ -687,7 +687,7 @@ Ancestors
 
 Class variables
 
-- var attributes
+- var attributes : Set[str]
- 
 The type of the None singleton. 
diff --git a/docs/reference/oauth/installation_store/async_cacheable_installation_store.html b/docs/reference/oauth/installation_store/async_cacheable_installation_store.html
index 100c62c4..a3820517 100644
--- a/docs/reference/oauth/installation_store/async_cacheable_installation_store.html
+++ b/docs/reference/oauth/installation_store/async_cacheable_installation_store.html
@@ -74,7 +74,7 @@Classes
     def logger(self) -> Logger:
         return self.underlying.logger
 
-    async def async_save(self, installation: Installation):  # type: ignore[explicit-override]
+    async def async_save(self, installation: Installation):
         # Invalidate cache data for update operations
         key = f"{installation.enterprise_id or ''}-{installation.team_id or ''}"
         if key in self.cached_bots:
@@ -84,14 +84,14 @@ Classes
             self.cached_installations.pop(key)
         return await self.underlying.async_save(installation)
 
-    async def async_save_bot(self, bot: Bot):  # type: ignore[explicit-override]
+    async def async_save_bot(self, bot: Bot):
         # Invalidate cache data for update operations
         key = f"{bot.enterprise_id or ''}-{bot.team_id or ''}"
         if key in self.cached_bots:
             self.cached_bots.pop(key)
         return await self.underlying.async_save_bot(bot)
 
-    async def async_find_bot(  # type: ignore[explicit-override]
+    async def async_find_bot(
         self,
         *,
         enterprise_id: Optional[str],
@@ -112,7 +112,7 @@ Classes
             self.cached_bots[key] = bot
         return bot
 
-    async def async_find_installation(  # type: ignore[explicit-override]
+    async def async_find_installation(
         self,
         *,
         enterprise_id: Optional[str],
diff --git a/docs/reference/oauth/installation_store/cacheable_installation_store.html b/docs/reference/oauth/installation_store/cacheable_installation_store.html
index 5e2802f1..54bb7662 100644
--- a/docs/reference/oauth/installation_store/cacheable_installation_store.html
+++ b/docs/reference/oauth/installation_store/cacheable_installation_store.html
@@ -74,7 +74,7 @@ Classes
     def logger(self) -> Logger:
         return self.underlying.logger
 
-    def save(self, installation: Installation):  # type: ignore[explicit-override]
+    def save(self, installation: Installation):
         # Invalidate cache data for update operations
         key = f"{installation.enterprise_id or ''}-{installation.team_id or ''}"
         if key in self.cached_bots:
@@ -85,14 +85,14 @@ Classes
 
         return self.underlying.save(installation)
 
-    def save_bot(self, bot: Bot):  # type: ignore[explicit-override]
+    def save_bot(self, bot: Bot):
         # Invalidate cache data for update operations
         key = f"{bot.enterprise_id or ''}-{bot.team_id or ''}"
         if key in self.cached_bots:
             self.cached_bots.pop(key)
         return self.underlying.save_bot(bot)
 
-    def find_bot(  # type: ignore[explicit-override]
+    def find_bot(
         self,
         *,
         enterprise_id: Optional[str],
@@ -113,7 +113,7 @@ Classes
             self.cached_bots[key] = bot
         return bot
 
-    def find_installation(  # type: ignore[explicit-override]
+    def find_installation(
         self,
         *,
         enterprise_id: Optional[str],
diff --git a/docs/reference/oauth/installation_store/file/index.html b/docs/reference/oauth/installation_store/file/index.html
index 7658ddd9..b972a9ea 100644
--- a/docs/reference/oauth/installation_store/file/index.html
+++ b/docs/reference/oauth/installation_store/file/index.html
@@ -48,7 +48,7 @@ Classes
 
 - 
 class FileInstallationStore
-(*,
 base_dir: str = '/Users/eden.zimbelman/.bolt-app-installation',
 historical_data_enabled: bool = True,
 client_id: str | None = None,
 logger: logging.Logger = <Logger slack_sdk.oauth.installation_store.file (WARNING)>)
+(*,
 base_dir: str = '/home/runner/.bolt-app-installation',
 historical_data_enabled: bool = True,
 client_id: str | None = None,
 logger: logging.Logger = <Logger slack_sdk.oauth.installation_store.file (WARNING)>)
- 
 
diff --git a/docs/reference/oauth/installation_store/index.html b/docs/reference/oauth/installation_store/index.html
index 5865522c..0335c693 100644
--- a/docs/reference/oauth/installation_store/index.html
+++ b/docs/reference/oauth/installation_store/index.html
@@ -327,7 +327,7 @@ Methods
- 
 class FileInstallationStore
-(*,
 base_dir: str = '/Users/eden.zimbelman/.bolt-app-installation',
 historical_data_enabled: bool = True,
 client_id: str | None = None,
 logger: logging.Logger = <Logger slack_sdk.oauth.installation_store.file (WARNING)>)
+(*,
 base_dir: str = '/home/runner/.bolt-app-installation',
 historical_data_enabled: bool = True,
 client_id: str | None = None,
 logger: logging.Logger = <Logger slack_sdk.oauth.installation_store.file (WARNING)>)
- 
 
diff --git a/docs/reference/oauth/state_store/file/index.html b/docs/reference/oauth/state_store/file/index.html
index 33ac16d8..8adf695a 100644
--- a/docs/reference/oauth/state_store/file/index.html
+++ b/docs/reference/oauth/state_store/file/index.html
@@ -48,7 +48,7 @@ Classes
 - 
 class FileOAuthStateStore
-(*,
 expiration_seconds: int,
 base_dir: str = '/Users/eden.zimbelman/.bolt-app-oauth-state',
 client_id: str | None = None,
 logger: logging.Logger = <Logger slack_sdk.oauth.state_store.file (WARNING)>)
+(*,
 expiration_seconds: int,
 base_dir: str = '/home/runner/.bolt-app-oauth-state',
 client_id: str | None = None,
 logger: logging.Logger = <Logger slack_sdk.oauth.state_store.file (WARNING)>)
- 
 
diff --git a/docs/reference/oauth/state_store/index.html b/docs/reference/oauth/state_store/index.html
index efb7d1cf..363fe78d 100644
--- a/docs/reference/oauth/state_store/index.html
+++ b/docs/reference/oauth/state_store/index.html
@@ -77,7 +77,7 @@ Classes
 - 
 class FileOAuthStateStore
-(*,
 expiration_seconds: int,
 base_dir: str = '/Users/eden.zimbelman/.bolt-app-oauth-state',
 client_id: str | None = None,
 logger: logging.Logger = <Logger slack_sdk.oauth.state_store.file (WARNING)>)
+(*,
 expiration_seconds: int,
 base_dir: str = '/home/runner/.bolt-app-oauth-state',
 client_id: str | None = None,
 logger: logging.Logger = <Logger slack_sdk.oauth.state_store.file (WARNING)>)
- 
 
diff --git a/docs/reference/socket_mode/client.html b/docs/reference/socket_mode/client.html
index dda047bd..3c8c615f 100644
--- a/docs/reference/socket_mode/client.html
+++ b/docs/reference/socket_mode/client.html
@@ -167,7 +167,7 @@ Classesfor listener in self.message_listeners:
                 try:
-                    listener(self, message, raw_message)  # type: ignore[call-arg, arg-type]
+                    listener(self, message, raw_message)  # type: ignore[call-arg, arg-type, misc]
                 except Exception as e:
                     self.logger.exception(f"Failed to run a message listener: {e}")
 
@@ -431,7 +431,7 @@Methodsfor listener in self.message_listeners:
             try:
-                listener(self, message, raw_message)  # type: ignore[call-arg, arg-type]
+                listener(self, message, raw_message)  # type: ignore[call-arg, arg-type, misc]
             except Exception as e:
                 self.logger.exception(f"Failed to run a message listener: {e}")
 
diff --git a/docs/reference/socket_mode/websocket_client/index.html b/docs/reference/socket_mode/websocket_client/index.html
index 20a1f0ac..6cce0c78 100644
--- a/docs/reference/socket_mode/websocket_client/index.html
+++ b/docs/reference/socket_mode/websocket_client/index.html
@@ -91,7 +91,7 @@Classesauto_reconnect_enabled: bool
     default_auto_reconnect_enabled: bool
 
-    close: bool  # type: ignore[assignment]
+    closed: bool
     connect_operation_lock: Lock
 
     on_open_listeners: List[Callable[[WebSocketApp], None]]
@@ -258,7 +258,7 @@Classes)
                     raise e
 
-    def close(self) -> None:  # type: ignore[explicit-override, no-redef]
+    def close(self) -> None:
         self.closed = True
         self.auto_reconnect_enabled = False
         self.disconnect()
@@ -384,7 +384,7 @@Methods
 Expand source code
 -def close(self) -> None:  # type: ignore[explicit-override, no-redef]
+def close(self) -> None:
     self.closed = True
     self.auto_reconnect_enabled = False
     self.disconnect()
diff --git a/docs/reference/web/async_client.html b/docs/reference/web/async_client.html
index 86403ce5..1ad20c35 100644
--- a/docs/reference/web/async_client.html
+++ b/docs/reference/web/async_client.html
@@ -1752,7 +1752,7 @@ Classesasync def admin_users_list(
         self,
         *,
-        team_id: str,
+        team_id: Optional[str] = None,
         include_deactivated_user_workspaces: Optional[bool] = None,
         is_active: Optional[bool] = None,
         cursor: Optional[str] = None,
@@ -2717,6 +2717,7 @@Classeslink_names: Optional[bool] = None,
         username: Optional[str] = None,
         parse: Optional[str] = None,
+        markdown_text: Optional[str] = None,
         **kwargs,
     ) -> AsyncSlackResponse:
         """Sends an ephemeral message to a user in a channel.
@@ -2736,11 +2737,12 @@Classes"link_names": link_names,
                 "username": username,
                 "parse": parse,
+                "markdown_text": markdown_text,
             }
         )
         _parse_web_class_objects(kwargs)
         kwargs = _remove_none_values(kwargs)
-        _warn_if_text_or_attachment_fallback_is_missing("chat.postEphemeral", kwargs)
+        _warn_if_message_text_content_is_missing("chat.postEphemeral", kwargs)
         # NOTE: intentionally using json over params for the API methods using blocks/attachments
         return await self.api_call("chat.postEphemeral", json=kwargs)
 
@@ -2764,6 +2766,7 @@Classesusername: Optional[str] = None,
         parse: Optional[str] = None,  # none, full
         metadata: Optional[Union[Dict, Metadata]] = None,
+        markdown_text: Optional[str] = None,
         **kwargs,
     ) -> AsyncSlackResponse:
         """Sends a message to a channel.
@@ -2788,11 +2791,12 @@Classes"username": username,
                 "parse": parse,
                 "metadata": metadata,
+                "markdown_text": markdown_text,
             }
         )
         _parse_web_class_objects(kwargs)
         kwargs = _remove_none_values(kwargs)
-        _warn_if_text_or_attachment_fallback_is_missing("chat.postMessage", kwargs)
+        _warn_if_message_text_content_is_missing("chat.postMessage", kwargs)
         # NOTE: intentionally using json over params for the API methods using blocks/attachments
         return await self.api_call("chat.postMessage", json=kwargs)
 
@@ -2801,7 +2805,7 @@Classes*,
         channel: str,
         post_at: Union[str, int],
-        text: str,
+        text: Optional[str] = None,
         as_user: Optional[bool] = None,
         attachments: Optional[Union[str, Sequence[Union[Dict, Attachment]]]] = None,
         blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None,
@@ -2812,6 +2816,7 @@Classesunfurl_media: Optional[bool] = None,
         link_names: Optional[bool] = None,
         metadata: Optional[Union[Dict, Metadata]] = None,
+        markdown_text: Optional[str] = None,
         **kwargs,
     ) -> AsyncSlackResponse:
         """Schedules a message.
@@ -2832,11 +2837,12 @@Classes"unfurl_media": unfurl_media,
                 "link_names": link_names,
                 "metadata": metadata,
+                "markdown_text": markdown_text,
             }
         )
         _parse_web_class_objects(kwargs)
         kwargs = _remove_none_values(kwargs)
-        _warn_if_text_or_attachment_fallback_is_missing("chat.scheduleMessage", kwargs)
+        _warn_if_message_text_content_is_missing("chat.scheduleMessage", kwargs)
         # NOTE: intentionally using json over params for the API methods using blocks/attachments
         return await self.api_call("chat.scheduleMessage", json=kwargs)
 
@@ -2889,6 +2895,7 @@Classesparse: Optional[str] = None,  # none, full
         reply_broadcast: Optional[bool] = None,
         metadata: Optional[Union[Dict, Metadata]] = None,
+        markdown_text: Optional[str] = None,
         **kwargs,
     ) -> AsyncSlackResponse:
         """Updates a message in a channel.
@@ -2906,6 +2913,7 @@Classes"parse": parse,
                 "reply_broadcast": reply_broadcast,
                 "metadata": metadata,
+                "markdown_text": markdown_text,
             }
         )
         if isinstance(file_ids, (list, tuple)):
@@ -2914,7 +2922,7 @@Classeskwargs.update({"file_ids": file_ids})
         _parse_web_class_objects(kwargs)
         kwargs = _remove_none_values(kwargs)
-        _warn_if_text_or_attachment_fallback_is_missing("chat.update", kwargs)
+        _warn_if_message_text_content_is_missing("chat.update", kwargs)
         # NOTE: intentionally using json over params for API methods using blocks/attachments
         return await self.api_call("chat.update", json=kwargs)
 
@@ -5438,6 +5446,72 @@Classes# NOTE: Intentionally using json for the "view" parameter
         return await self.api_call("views.publish", json=kwargs)
 
+    async def workflows_featured_add(
+        self,
+        *,
+        channel_id: str,
+        trigger_ids: Union[str, Sequence[str]],
+        **kwargs,
+    ) -> AsyncSlackResponse:
+        """Add featured workflows to a channel.
+        https://api.slack.com/methods/workflows.featured.add
+        """
+        kwargs.update({"channel_id": channel_id})
+        if isinstance(trigger_ids, (list, tuple)):
+            kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+        else:
+            kwargs.update({"trigger_ids": trigger_ids})
+        return await self.api_call("workflows.featured.add", params=kwargs)
+
+    async def workflows_featured_list(
+        self,
+        *,
+        channel_ids: Union[str, Sequence[str]],
+        **kwargs,
+    ) -> AsyncSlackResponse:
+        """List the featured workflows for specified channels.
+        https://api.slack.com/methods/workflows.featured.list
+        """
+        if isinstance(channel_ids, (list, tuple)):
+            kwargs.update({"channel_ids": ",".join(channel_ids)})
+        else:
+            kwargs.update({"channel_ids": channel_ids})
+        return await self.api_call("workflows.featured.list", params=kwargs)
+
+    async def workflows_featured_remove(
+        self,
+        *,
+        channel_id: str,
+        trigger_ids: Union[str, Sequence[str]],
+        **kwargs,
+    ) -> AsyncSlackResponse:
+        """Remove featured workflows from a channel.
+        https://api.slack.com/methods/workflows.featured.remove
+        """
+        kwargs.update({"channel_id": channel_id})
+        if isinstance(trigger_ids, (list, tuple)):
+            kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+        else:
+            kwargs.update({"trigger_ids": trigger_ids})
+        return await self.api_call("workflows.featured.remove", params=kwargs)
+
+    async def workflows_featured_set(
+        self,
+        *,
+        channel_id: str,
+        trigger_ids: Union[str, Sequence[str]],
+        **kwargs,
+    ) -> AsyncSlackResponse:
+        """Set featured workflows for a channel.
+        https://api.slack.com/methods/workflows.featured.set
+        """
+        kwargs.update({"channel_id": channel_id})
+        if isinstance(trigger_ids, (list, tuple)):
+            kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+        else:
+            kwargs.update({"trigger_ids": trigger_ids})
+        return await self.api_call("workflows.featured.set", params=kwargs)
+
     async def workflows_stepCompleted(
         self,
         *,
@@ -7915,7 +7989,7 @@Methodshttps://api.slack.com/methods/admin.users.invite
 
 
- 
-async def admin_users_list(self,
 *,
 team_id: str,
 include_deactivated_user_workspaces: bool | None = None,
 is_active: bool | None = None,
 cursor: str | None = None,
 limit: int | None = None,
 **kwargs) ‑> AsyncSlackResponse
+async def admin_users_list(self,
 *,
 team_id: str | None = None,
 include_deactivated_user_workspaces: bool | None = None,
 is_active: bool | None = None,
 cursor: str | None = None,
 limit: int | None = None,
 **kwargs) ‑> AsyncSlackResponse
- 
 
@@ -7925,7 +7999,7 @@ Methodsasync def admin_users_list(
     self,
     *,
-    team_id: str,
+    team_id: Optional[str] = None,
     include_deactivated_user_workspaces: Optional[bool] = None,
     is_active: Optional[bool] = None,
     cursor: Optional[str] = None,
@@ -9762,7 +9836,7 @@ Methodshttps://api.slack.com/methods/chat.meMessage
 
- 
-async def chat_postEphemeral(self,
 *,
 channel: str,
 user: str,
 text: str | None = None,
 as_user: bool | None = None,
 attachments: str | Sequence[Dict | Attachment] | None = None,
 blocks: str | Sequence[Dict | Block] | None = None,
 thread_ts: str | None = None,
 icon_emoji: str | None = None,
 icon_url: str | None = None,
 link_names: bool | None = None,
 username: str | None = None,
 parse: str | None = None,
 **kwargs) ‑> AsyncSlackResponse
+async def chat_postEphemeral(self,
 *,
 channel: str,
 user: str,
 text: str | None = None,
 as_user: bool | None = None,
 attachments: str | Sequence[Dict | Attachment] | None = None,
 blocks: str | Sequence[Dict | Block] | None = None,
 thread_ts: str | None = None,
 icon_emoji: str | None = None,
 icon_url: str | None = None,
 link_names: bool | None = None,
 username: str | None = None,
 parse: str | None = None,
 markdown_text: str | None = None,
 **kwargs) ‑> AsyncSlackResponse
- 
 
@@ -9784,6 +9858,7 @@ Methodslink_names: Optional[bool] = None,
     username: Optional[str] = None,
     parse: Optional[str] = None,
+    markdown_text: Optional[str] = None,
     **kwargs,
 ) -> AsyncSlackResponse:
     """Sends an ephemeral message to a user in a channel.
@@ -9803,11 +9878,12 @@Methods"link_names": link_names,
             "username": username,
             "parse": parse,
+            "markdown_text": markdown_text,
         }
     )
     _parse_web_class_objects(kwargs)
     kwargs = _remove_none_values(kwargs)
-    _warn_if_text_or_attachment_fallback_is_missing("chat.postEphemeral", kwargs)
+    _warn_if_message_text_content_is_missing("chat.postEphemeral", kwargs)
     # NOTE: intentionally using json over params for the API methods using blocks/attachments
     return await self.api_call("chat.postEphemeral", json=kwargs)
 
 
 
@@ -9815,7 +9891,7 @@ Methods
 https://api.slack.com/methods/chat.postEphemeral
 
 - 
-async def chat_postMessage(self,
 *,
 channel: str,
 text: str | None = None,
 as_user: bool | None = None,
 attachments: str | Sequence[Dict | Attachment] | None = None,
 blocks: str | Sequence[Dict | Block] | None = None,
 thread_ts: str | None = None,
 reply_broadcast: bool | None = None,
 unfurl_links: bool | None = None,
 unfurl_media: bool | None = None,
 container_id: str | None = None,
 icon_emoji: str | None = None,
 icon_url: str | None = None,
 mrkdwn: bool | None = None,
 link_names: bool | None = None,
 username: str | None = None,
 parse: str | None = None,
 metadata: Dict | Metadata | None = None,
 **kwargs) ‑> AsyncSlackResponse
+async def chat_postMessage(self,
 *,
 channel: str,
 text: str | None = None,
 as_user: bool | None = None,
 attachments: str | Sequence[Dict | Attachment] | None = None,
 blocks: str | Sequence[Dict | Block] | None = None,
 thread_ts: str | None = None,
 reply_broadcast: bool | None = None,
 unfurl_links: bool | None = None,
 unfurl_media: bool | None = None,
 container_id: str | None = None,
 icon_emoji: str | None = None,
 icon_url: str | None = None,
 mrkdwn: bool | None = None,
 link_names: bool | None = None,
 username: str | None = None,
 parse: str | None = None,
 metadata: Dict | Metadata | None = None,
 markdown_text: str | None = None,
 **kwargs) ‑> AsyncSlackResponse
- 
 
@@ -9842,6 +9918,7 @@ Methodsusername: Optional[str] = None,
     parse: Optional[str] = None,  # none, full
     metadata: Optional[Union[Dict, Metadata]] = None,
+    markdown_text: Optional[str] = None,
     **kwargs,
 ) -> AsyncSlackResponse:
     """Sends a message to a channel.
@@ -9866,11 +9943,12 @@Methods"username": username,
             "parse": parse,
             "metadata": metadata,
+            "markdown_text": markdown_text,
         }
     )
     _parse_web_class_objects(kwargs)
     kwargs = _remove_none_values(kwargs)
-    _warn_if_text_or_attachment_fallback_is_missing("chat.postMessage", kwargs)
+    _warn_if_message_text_content_is_missing("chat.postMessage", kwargs)
     # NOTE: intentionally using json over params for the API methods using blocks/attachments
     return await self.api_call("chat.postMessage", json=kwargs)
 
@@ -9878,7 +9956,7 @@ Methods
 https://api.slack.com/methods/chat.postMessage
 
 
-async def chat_scheduleMessage(self,
*,
channel: str,
post_at: str | int,
text: str,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
link_names: bool | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> AsyncSlackResponse
+async def chat_scheduleMessage(self,
*,
channel: str,
post_at: str | int,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
link_names: bool | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> AsyncSlackResponse
 
 
@@ -9890,7 +9968,7 @@ Methods
     *,
     channel: str,
     post_at: Union[str, int],
-    text: str,
+    text: Optional[str] = None,
     as_user: Optional[bool] = None,
     attachments: Optional[Union[str, Sequence[Union[Dict, Attachment]]]] = None,
     blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None,
@@ -9901,6 +9979,7 @@ Methods
     unfurl_media: Optional[bool] = None,
     link_names: Optional[bool] = None,
     metadata: Optional[Union[Dict, Metadata]] = None,
+    markdown_text: Optional[str] = None,
     **kwargs,
 ) -> AsyncSlackResponse:
     """Schedules a message.
@@ -9921,11 +10000,12 @@ Methods
             "unfurl_media": unfurl_media,
             "link_names": link_names,
             "metadata": metadata,
+            "markdown_text": markdown_text,
         }
     )
     _parse_web_class_objects(kwargs)
     kwargs = _remove_none_values(kwargs)
-    _warn_if_text_or_attachment_fallback_is_missing("chat.scheduleMessage", kwargs)
+    _warn_if_message_text_content_is_missing("chat.scheduleMessage", kwargs)
     # NOTE: intentionally using json over params for the API methods using blocks/attachments
     return await self.api_call("chat.scheduleMessage", json=kwargs)  
 
@@ -10016,7 +10096,7 @@ Methods
 https://api.slack.com/methods/chat.unfurl
 
 
-async def chat_update(self,
*,
channel: str,
ts: str,
text: str | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
as_user: bool | None = None,
file_ids: str | Sequence[str] | None = None,
link_names: bool | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> AsyncSlackResponse
+async def chat_update(self,
*,
channel: str,
ts: str,
text: str | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
as_user: bool | None = None,
file_ids: str | Sequence[str] | None = None,
link_names: bool | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> AsyncSlackResponse
 
 
@@ -10037,6 +10117,7 @@ Methods
     parse: Optional[str] = None,  # none, full
     reply_broadcast: Optional[bool] = None,
     metadata: Optional[Union[Dict, Metadata]] = None,
+    markdown_text: Optional[str] = None,
     **kwargs,
 ) -> AsyncSlackResponse:
     """Updates a message in a channel.
@@ -10054,6 +10135,7 @@ Methods
             "parse": parse,
             "reply_broadcast": reply_broadcast,
             "metadata": metadata,
+            "markdown_text": markdown_text,
         }
     )
     if isinstance(file_ids, (list, tuple)):
@@ -10062,7 +10144,7 @@ Methods
         kwargs.update({"file_ids": file_ids})
     _parse_web_class_objects(kwargs)
     kwargs = _remove_none_values(kwargs)
-    _warn_if_text_or_attachment_fallback_is_missing("chat.update", kwargs)
+    _warn_if_message_text_content_is_missing("chat.update", kwargs)
     # NOTE: intentionally using json over params for API methods using blocks/attachments
     return await self.api_call("chat.update", json=kwargs) 
 
@@ -14090,6 +14172,116 @@ 
+async def workflows_featured_add(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> AsyncSlackResponse
+async def workflows_featured_add(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> AsyncSlackResponse:
+    """Add featured workflows to a channel.
+    https://api.slack.com/methods/workflows.featured.add
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return await self.api_call("workflows.featured.add", params=kwargs)Add featured workflows to a channel. +https://api.slack.com/methods/workflows.featured.add
+async def workflows_featured_list(self, *, channel_ids: str | Sequence[str], **kwargs) ‑> AsyncSlackResponse
+async def workflows_featured_list(
+    self,
+    *,
+    channel_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> AsyncSlackResponse:
+    """List the featured workflows for specified channels.
+    https://api.slack.com/methods/workflows.featured.list
+    """
+    if isinstance(channel_ids, (list, tuple)):
+        kwargs.update({"channel_ids": ",".join(channel_ids)})
+    else:
+        kwargs.update({"channel_ids": channel_ids})
+    return await self.api_call("workflows.featured.list", params=kwargs)List the featured workflows for specified channels. +https://api.slack.com/methods/workflows.featured.list
+async def workflows_featured_remove(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> AsyncSlackResponse
+async def workflows_featured_remove(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> AsyncSlackResponse:
+    """Remove featured workflows from a channel.
+    https://api.slack.com/methods/workflows.featured.remove
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return await self.api_call("workflows.featured.remove", params=kwargs)Remove featured workflows from a channel. +https://api.slack.com/methods/workflows.featured.remove
+async def workflows_featured_set(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> AsyncSlackResponse
+async def workflows_featured_set(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> AsyncSlackResponse:
+    """Set featured workflows for a channel.
+    https://api.slack.com/methods/workflows.featured.set
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return await self.api_call("workflows.featured.set", params=kwargs)Set featured workflows for a channel. +https://api.slack.com/methods/workflows.featured.set
 async def workflows_stepCompleted(self, *, workflow_step_execute_id: str, outputs: dict | None = None, **kwargs) ‑> AsyncSlackResponse
 views_publish
 views_pushviews_updateworkflows_featured_addworkflows_featured_listworkflows_featured_removeworkflows_featured_setworkflows_stepCompletedworkflows_stepFailedworkflows_updateStep
-def admin_users_list(self,
*,
team_id: str,
include_deactivated_user_workspaces: bool | None = None,
is_active: bool | None = None,
cursor: str | None = None,
limit: int | None = None,
**kwargs) ‑> SlackResponse
+def admin_users_list(self,
*,
team_id: str | None = None,
include_deactivated_user_workspaces: bool | None = None,
is_active: bool | None = None,
cursor: str | None = None,
limit: int | None = None,
**kwargs) ‑> SlackResponse
 def admin_users_list(
     self,
     *,
-    team_id: str,
+    team_id: Optional[str] = None,
     include_deactivated_user_workspaces: Optional[bool] = None,
     is_active: Optional[bool] = None,
     cursor: Optional[str] = None,
@@ -9762,7 +9836,7 @@ Methods
 https://api.slack.com/methods/chat.meMessage
 
-def chat_postEphemeral(self,
*,
channel: str,
user: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
**kwargs) ‑> SlackResponse
+def chat_postEphemeral(self,
*,
channel: str,
user: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
-def chat_postMessage(self,
*,
channel: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
container_id: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
mrkdwn: bool | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> SlackResponse
+def chat_postMessage(self,
*,
channel: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
container_id: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
mrkdwn: bool | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
-def chat_scheduleMessage(self,
*,
channel: str,
post_at: str | int,
text: str,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
link_names: bool | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> SlackResponse
+def chat_scheduleMessage(self,
*,
channel: str,
post_at: str | int,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
link_names: bool | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
-def chat_update(self,
*,
channel: str,
ts: str,
text: str | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
as_user: bool | None = None,
file_ids: str | Sequence[str] | None = None,
link_names: bool | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> SlackResponse
+def chat_update(self,
*,
channel: str,
ts: str,
text: str | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
as_user: bool | None = None,
file_ids: str | Sequence[str] | None = None,
link_names: bool | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
+def workflows_featured_add(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_add(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """Add featured workflows to a channel.
+    https://api.slack.com/methods/workflows.featured.add
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.add", params=kwargs)Add featured workflows to a channel. +https://api.slack.com/methods/workflows.featured.add
+def workflows_featured_list(self, *, channel_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_list(
+    self,
+    *,
+    channel_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """List the featured workflows for specified channels.
+    https://api.slack.com/methods/workflows.featured.list
+    """
+    if isinstance(channel_ids, (list, tuple)):
+        kwargs.update({"channel_ids": ",".join(channel_ids)})
+    else:
+        kwargs.update({"channel_ids": channel_ids})
+    return self.api_call("workflows.featured.list", params=kwargs)List the featured workflows for specified channels. +https://api.slack.com/methods/workflows.featured.list
+def workflows_featured_remove(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_remove(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """Remove featured workflows from a channel.
+    https://api.slack.com/methods/workflows.featured.remove
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.remove", params=kwargs)Remove featured workflows from a channel. +https://api.slack.com/methods/workflows.featured.remove
+def workflows_featured_set(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_set(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """Set featured workflows for a channel.
+    https://api.slack.com/methods/workflows.featured.set
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.set", params=kwargs)Set featured workflows for a channel. +https://api.slack.com/methods/workflows.featured.set
 def workflows_stepCompleted(self, *, workflow_step_execute_id: str, outputs: dict | None = None, **kwargs) ‑> SlackResponse
 views_publish
 views_pushviews_updateworkflows_featured_addworkflows_featured_listworkflows_featured_removeworkflows_featured_setworkflows_stepCompletedworkflows_stepFailedworkflows_updateStep
-def admin_users_list(self,
*,
team_id: str,
include_deactivated_user_workspaces: bool | None = None,
is_active: bool | None = None,
cursor: str | None = None,
limit: int | None = None,
**kwargs) ‑> SlackResponse
+def admin_users_list(self,
*,
team_id: str | None = None,
include_deactivated_user_workspaces: bool | None = None,
is_active: bool | None = None,
cursor: str | None = None,
limit: int | None = None,
**kwargs) ‑> SlackResponse
 def admin_users_list(
     self,
     *,
-    team_id: str,
+    team_id: Optional[str] = None,
     include_deactivated_user_workspaces: Optional[bool] = None,
     is_active: Optional[bool] = None,
     cursor: Optional[str] = None,
@@ -10123,7 +10197,7 @@ Methods
 https://api.slack.com/methods/chat.meMessage
 
-def chat_postEphemeral(self,
*,
channel: str,
user: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
**kwargs) ‑> SlackResponse
+def chat_postEphemeral(self,
*,
channel: str,
user: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
-def chat_postMessage(self,
*,
channel: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
container_id: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
mrkdwn: bool | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> SlackResponse
+def chat_postMessage(self,
*,
channel: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
container_id: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
mrkdwn: bool | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
-def chat_scheduleMessage(self,
*,
channel: str,
post_at: str | int,
text: str,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
link_names: bool | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> SlackResponse
+def chat_scheduleMessage(self,
*,
channel: str,
post_at: str | int,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
link_names: bool | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
-def chat_update(self,
*,
channel: str,
ts: str,
text: str | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
as_user: bool | None = None,
file_ids: str | Sequence[str] | None = None,
link_names: bool | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> SlackResponse
+def chat_update(self,
*,
channel: str,
ts: str,
text: str | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
as_user: bool | None = None,
file_ids: str | Sequence[str] | None = None,
link_names: bool | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
 
+def workflows_featured_add(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_add(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """Add featured workflows to a channel.
+    https://api.slack.com/methods/workflows.featured.add
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.add", params=kwargs)Add featured workflows to a channel. +https://api.slack.com/methods/workflows.featured.add
+def workflows_featured_list(self, *, channel_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_list(
+    self,
+    *,
+    channel_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """List the featured workflows for specified channels.
+    https://api.slack.com/methods/workflows.featured.list
+    """
+    if isinstance(channel_ids, (list, tuple)):
+        kwargs.update({"channel_ids": ",".join(channel_ids)})
+    else:
+        kwargs.update({"channel_ids": channel_ids})
+    return self.api_call("workflows.featured.list", params=kwargs)List the featured workflows for specified channels. +https://api.slack.com/methods/workflows.featured.list
+def workflows_featured_remove(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_remove(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """Remove featured workflows from a channel.
+    https://api.slack.com/methods/workflows.featured.remove
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.remove", params=kwargs)Remove featured workflows from a channel. +https://api.slack.com/methods/workflows.featured.remove
+def workflows_featured_set(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> SlackResponse
+def workflows_featured_set(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> SlackResponse:
+    """Set featured workflows for a channel.
+    https://api.slack.com/methods/workflows.featured.set
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.set", params=kwargs)Set featured workflows for a channel. +https://api.slack.com/methods/workflows.featured.set
 def workflows_stepCompleted(self, *, workflow_step_execute_id: str, outputs: dict | None = None, **kwargs) ‑> SlackResponse
 Web
 views_publishviews_pushviews_updateworkflows_featured_addworkflows_featured_listworkflows_featured_removeworkflows_featured_setworkflows_stepCompletedworkflows_stepFailedworkflows_updateStepReturns
 
     Returns:
         The user agent string.
-        e.g. 'Python/3.6.7 slackclient/2.0.0 Darwin/17.7.0'
+        e.g. 'Python/3.7.17 slackclient/2.0.0 Darwin/17.7.0'
     """
     # __name__ returns all classes, we only want the client
     client = "{0}/{1}".format("slackclient", version.__version__)
@@ -110,7 +110,7 @@ Returns
 Python version and OS version.
 Returns
 The user agent string.
-e.g. 'Python/3.6.7 slackclient/2.0.0 Darwin/17.7.0'
+e.g. 'Python/3.7.17 slackclient/2.0.0 Darwin/17.7.0'
 
 
 
diff --git a/docs/reference/web/legacy_client.html b/docs/reference/web/legacy_client.html
index 63cbfc7f..8dccc2f3 100644
--- a/docs/reference/web/legacy_client.html
+++ b/docs/reference/web/legacy_client.html
@@ -1751,7 +1751,7 @@ Classes
     def admin_users_list(
         self,
         *,
-        team_id: str,
+        team_id: Optional[str] = None,
         include_deactivated_user_workspaces: Optional[bool] = None,
         is_active: Optional[bool] = None,
         cursor: Optional[str] = None,
@@ -2716,6 +2716,7 @@ Classes
         link_names: Optional[bool] = None,
         username: Optional[str] = None,
         parse: Optional[str] = None,
+        markdown_text: Optional[str] = None,
         **kwargs,
     ) -> Union[Future, SlackResponse]:
         """Sends an ephemeral message to a user in a channel.
@@ -2735,11 +2736,12 @@ Classes
                 "link_names": link_names,
                 "username": username,
                 "parse": parse,
+                "markdown_text": markdown_text,
             }
         )
         _parse_web_class_objects(kwargs)
         kwargs = _remove_none_values(kwargs)
-        _warn_if_text_or_attachment_fallback_is_missing("chat.postEphemeral", kwargs)
+        _warn_if_message_text_content_is_missing("chat.postEphemeral", kwargs)
         # NOTE: intentionally using json over params for the API methods using blocks/attachments
         return self.api_call("chat.postEphemeral", json=kwargs)
 
@@ -2763,6 +2765,7 @@ Classes
         username: Optional[str] = None,
         parse: Optional[str] = None,  # none, full
         metadata: Optional[Union[Dict, Metadata]] = None,
+        markdown_text: Optional[str] = None,
         **kwargs,
     ) -> Union[Future, SlackResponse]:
         """Sends a message to a channel.
@@ -2787,11 +2790,12 @@ Classes
                 "username": username,
                 "parse": parse,
                 "metadata": metadata,
+                "markdown_text": markdown_text,
             }
         )
         _parse_web_class_objects(kwargs)
         kwargs = _remove_none_values(kwargs)
-        _warn_if_text_or_attachment_fallback_is_missing("chat.postMessage", kwargs)
+        _warn_if_message_text_content_is_missing("chat.postMessage", kwargs)
         # NOTE: intentionally using json over params for the API methods using blocks/attachments
         return self.api_call("chat.postMessage", json=kwargs)
 
@@ -2800,7 +2804,7 @@ Classes
         *,
         channel: str,
         post_at: Union[str, int],
-        text: str,
+        text: Optional[str] = None,
         as_user: Optional[bool] = None,
         attachments: Optional[Union[str, Sequence[Union[Dict, Attachment]]]] = None,
         blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None,
@@ -2811,6 +2815,7 @@ Classes
         unfurl_media: Optional[bool] = None,
         link_names: Optional[bool] = None,
         metadata: Optional[Union[Dict, Metadata]] = None,
+        markdown_text: Optional[str] = None,
         **kwargs,
     ) -> Union[Future, SlackResponse]:
         """Schedules a message.
@@ -2831,11 +2836,12 @@ Classes
                 "unfurl_media": unfurl_media,
                 "link_names": link_names,
                 "metadata": metadata,
+                "markdown_text": markdown_text,
             }
         )
         _parse_web_class_objects(kwargs)
         kwargs = _remove_none_values(kwargs)
-        _warn_if_text_or_attachment_fallback_is_missing("chat.scheduleMessage", kwargs)
+        _warn_if_message_text_content_is_missing("chat.scheduleMessage", kwargs)
         # NOTE: intentionally using json over params for the API methods using blocks/attachments
         return self.api_call("chat.scheduleMessage", json=kwargs)
 
@@ -2888,6 +2894,7 @@ Classes
         parse: Optional[str] = None,  # none, full
         reply_broadcast: Optional[bool] = None,
         metadata: Optional[Union[Dict, Metadata]] = None,
+        markdown_text: Optional[str] = None,
         **kwargs,
     ) -> Union[Future, SlackResponse]:
         """Updates a message in a channel.
@@ -2905,6 +2912,7 @@ Classes
                 "parse": parse,
                 "reply_broadcast": reply_broadcast,
                 "metadata": metadata,
+                "markdown_text": markdown_text,
             }
         )
         if isinstance(file_ids, (list, tuple)):
@@ -2913,7 +2921,7 @@ Classes
             kwargs.update({"file_ids": file_ids})
         _parse_web_class_objects(kwargs)
         kwargs = _remove_none_values(kwargs)
-        _warn_if_text_or_attachment_fallback_is_missing("chat.update", kwargs)
+        _warn_if_message_text_content_is_missing("chat.update", kwargs)
         # NOTE: intentionally using json over params for API methods using blocks/attachments
         return self.api_call("chat.update", json=kwargs)
 
@@ -5437,6 +5445,72 @@ Classes
         # NOTE: Intentionally using json for the "view" parameter
         return self.api_call("views.publish", json=kwargs)
 
+    def workflows_featured_add(
+        self,
+        *,
+        channel_id: str,
+        trigger_ids: Union[str, Sequence[str]],
+        **kwargs,
+    ) -> Union[Future, SlackResponse]:
+        """Add featured workflows to a channel.
+        https://api.slack.com/methods/workflows.featured.add
+        """
+        kwargs.update({"channel_id": channel_id})
+        if isinstance(trigger_ids, (list, tuple)):
+            kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+        else:
+            kwargs.update({"trigger_ids": trigger_ids})
+        return self.api_call("workflows.featured.add", params=kwargs)
+
+    def workflows_featured_list(
+        self,
+        *,
+        channel_ids: Union[str, Sequence[str]],
+        **kwargs,
+    ) -> Union[Future, SlackResponse]:
+        """List the featured workflows for specified channels.
+        https://api.slack.com/methods/workflows.featured.list
+        """
+        if isinstance(channel_ids, (list, tuple)):
+            kwargs.update({"channel_ids": ",".join(channel_ids)})
+        else:
+            kwargs.update({"channel_ids": channel_ids})
+        return self.api_call("workflows.featured.list", params=kwargs)
+
+    def workflows_featured_remove(
+        self,
+        *,
+        channel_id: str,
+        trigger_ids: Union[str, Sequence[str]],
+        **kwargs,
+    ) -> Union[Future, SlackResponse]:
+        """Remove featured workflows from a channel.
+        https://api.slack.com/methods/workflows.featured.remove
+        """
+        kwargs.update({"channel_id": channel_id})
+        if isinstance(trigger_ids, (list, tuple)):
+            kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+        else:
+            kwargs.update({"trigger_ids": trigger_ids})
+        return self.api_call("workflows.featured.remove", params=kwargs)
+
+    def workflows_featured_set(
+        self,
+        *,
+        channel_id: str,
+        trigger_ids: Union[str, Sequence[str]],
+        **kwargs,
+    ) -> Union[Future, SlackResponse]:
+        """Set featured workflows for a channel.
+        https://api.slack.com/methods/workflows.featured.set
+        """
+        kwargs.update({"channel_id": channel_id})
+        if isinstance(trigger_ids, (list, tuple)):
+            kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+        else:
+            kwargs.update({"trigger_ids": trigger_ids})
+        return self.api_call("workflows.featured.set", params=kwargs)
+
     def workflows_stepCompleted(
         self,
         *,
@@ -7914,7 +7988,7 @@ Methods
 https://api.slack.com/methods/admin.users.invite
 
 
-def admin_users_list(self,
*,
team_id: str,
include_deactivated_user_workspaces: bool | None = None,
is_active: bool | None = None,
cursor: str | None = None,
limit: int | None = None,
**kwargs) ‑> _asyncio.Future | LegacySlackResponse
+def admin_users_list(self,
*,
team_id: str | None = None,
include_deactivated_user_workspaces: bool | None = None,
is_active: bool | None = None,
cursor: str | None = None,
limit: int | None = None,
**kwargs) ‑> _asyncio.Future | LegacySlackResponse
 
 
@@ -7924,7 +7998,7 @@ Methods
 def admin_users_list(
     self,
     *,
-    team_id: str,
+    team_id: Optional[str] = None,
     include_deactivated_user_workspaces: Optional[bool] = None,
     is_active: Optional[bool] = None,
     cursor: Optional[str] = None,
@@ -9761,7 +9835,7 @@ Methods
 https://api.slack.com/methods/chat.meMessage
 
 
 
-def chat_postEphemeral(self,
*,
channel: str,
user: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
**kwargs) ‑> _asyncio.Future | LegacySlackResponse
+def chat_postEphemeral(self,
*,
channel: str,
user: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
markdown_text: str | None = None,
**kwargs) ‑> _asyncio.Future | LegacySlackResponse
 
 
@@ -9783,6 +9857,7 @@ Methods
     link_names: Optional[bool] = None,
     username: Optional[str] = None,
     parse: Optional[str] = None,
+    markdown_text: Optional[str] = None,
     **kwargs,
 ) -> Union[Future, SlackResponse]:
     """Sends an ephemeral message to a user in a channel.
@@ -9802,11 +9877,12 @@ Methods
             "link_names": link_names,
             "username": username,
             "parse": parse,
+            "markdown_text": markdown_text,
         }
     )
     _parse_web_class_objects(kwargs)
     kwargs = _remove_none_values(kwargs)
-    _warn_if_text_or_attachment_fallback_is_missing("chat.postEphemeral", kwargs)
+    _warn_if_message_text_content_is_missing("chat.postEphemeral", kwargs)
     # NOTE: intentionally using json over params for the API methods using blocks/attachments
     return self.api_call("chat.postEphemeral", json=kwargs) 
 
@@ -9814,7 +9890,7 @@ 
-def chat_postMessage(self,
*,
channel: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
container_id: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
mrkdwn: bool | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> _asyncio.Future | LegacySlackResponse
+def chat_postMessage(self,
*,
channel: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
container_id: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
mrkdwn: bool | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> _asyncio.Future | LegacySlackResponse
 
-def chat_scheduleMessage(self,
*,
channel: str,
post_at: str | int,
text: str,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
link_names: bool | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> _asyncio.Future | LegacySlackResponse
+def chat_scheduleMessage(self,
*,
channel: str,
post_at: str | int,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
link_names: bool | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> _asyncio.Future | LegacySlackResponse
 
-def chat_update(self,
*,
channel: str,
ts: str,
text: str | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
as_user: bool | None = None,
file_ids: str | Sequence[str] | None = None,
link_names: bool | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
metadata: Dict | Metadata | None = None,
**kwargs) ‑> _asyncio.Future | LegacySlackResponse
+def chat_update(self,
*,
channel: str,
ts: str,
text: str | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
as_user: bool | None = None,
file_ids: str | Sequence[str] | None = None,
link_names: bool | None = None,
parse: str | None = None,
reply_broadcast: bool | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> _asyncio.Future | LegacySlackResponse
 
+def workflows_featured_add(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> _asyncio.Future | LegacySlackResponse
+def workflows_featured_add(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> Union[Future, SlackResponse]:
+    """Add featured workflows to a channel.
+    https://api.slack.com/methods/workflows.featured.add
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.add", params=kwargs)Add featured workflows to a channel. +https://api.slack.com/methods/workflows.featured.add
+def workflows_featured_list(self, *, channel_ids: str | Sequence[str], **kwargs) ‑> _asyncio.Future | LegacySlackResponse
+def workflows_featured_list(
+    self,
+    *,
+    channel_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> Union[Future, SlackResponse]:
+    """List the featured workflows for specified channels.
+    https://api.slack.com/methods/workflows.featured.list
+    """
+    if isinstance(channel_ids, (list, tuple)):
+        kwargs.update({"channel_ids": ",".join(channel_ids)})
+    else:
+        kwargs.update({"channel_ids": channel_ids})
+    return self.api_call("workflows.featured.list", params=kwargs)List the featured workflows for specified channels. +https://api.slack.com/methods/workflows.featured.list
+def workflows_featured_remove(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> _asyncio.Future | LegacySlackResponse
+def workflows_featured_remove(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> Union[Future, SlackResponse]:
+    """Remove featured workflows from a channel.
+    https://api.slack.com/methods/workflows.featured.remove
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.remove", params=kwargs)Remove featured workflows from a channel. +https://api.slack.com/methods/workflows.featured.remove
+def workflows_featured_set(self, *, channel_id: str, trigger_ids: str | Sequence[str], **kwargs) ‑> _asyncio.Future | LegacySlackResponse
+def workflows_featured_set(
+    self,
+    *,
+    channel_id: str,
+    trigger_ids: Union[str, Sequence[str]],
+    **kwargs,
+) -> Union[Future, SlackResponse]:
+    """Set featured workflows for a channel.
+    https://api.slack.com/methods/workflows.featured.set
+    """
+    kwargs.update({"channel_id": channel_id})
+    if isinstance(trigger_ids, (list, tuple)):
+        kwargs.update({"trigger_ids": ",".join(trigger_ids)})
+    else:
+        kwargs.update({"trigger_ids": trigger_ids})
+    return self.api_call("workflows.featured.set", params=kwargs)Set featured workflows for a channel. +https://api.slack.com/methods/workflows.featured.set
 def workflows_stepCompleted(self, *, workflow_step_execute_id: str, outputs: dict | None = None, **kwargs) ‑> _asyncio.Future | LegacySlackResponse
 views_publish
 views_pushviews_updateworkflows_featured_addworkflows_featured_listworkflows_featured_removeworkflows_featured_setworkflows_stepCompletedworkflows_stepFailedworkflows_updateStep