Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions slack_sdk/web/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
_update_call_participants,
_validate_for_legacy_client,
_warn_if_message_text_content_is_missing,
_warn_if_unknown_kwargs,
)


Expand Down Expand Up @@ -3292,6 +3293,27 @@ async def chat_postMessage(

https://docs.slack.dev/reference/methods/chat.postMessage
"""
known_params = {
"channel",
"text",
"as_user",
"attachments",
"blocks",
"thread_ts",
"reply_broadcast",
"unfurl_links",
"unfurl_media",
"container_id",
"icon_emoji",
"icon_url",
"mrkdwn",
"link_names",
"username",
"parse",
"metadata",
"markdown_text",
}
_warn_if_unknown_kwargs("chat.postMessage", kwargs, known_params)
kwargs.update(
{
"channel": channel,
Expand Down
22 changes: 22 additions & 0 deletions slack_sdk/web/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
_update_call_participants,
_validate_for_legacy_client,
_warn_if_message_text_content_is_missing,
_warn_if_unknown_kwargs,
)


Expand Down Expand Up @@ -3282,6 +3283,27 @@ def chat_postMessage(

https://docs.slack.dev/reference/methods/chat.postMessage
"""
known_params = {
"channel",
"text",
"as_user",
"attachments",
"blocks",
"thread_ts",
"reply_broadcast",
"unfurl_links",
"unfurl_media",
"container_id",
"icon_emoji",
"icon_url",
"mrkdwn",
"link_names",
"username",
"parse",
"metadata",
"markdown_text",
}
_warn_if_unknown_kwargs("chat.postMessage", kwargs, known_params)
kwargs.update(
{
"channel": channel,
Expand Down
24 changes: 23 additions & 1 deletion slack_sdk/web/internal_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from http.client import HTTPResponse
from io import IOBase
from ssl import SSLContext
from typing import Any, Dict, Optional, Sequence, Union
from typing import Any, Dict, Optional, Sequence, Set, Union
from urllib.parse import urljoin
from urllib.request import HTTPSHandler, OpenerDirector, ProxyHandler, Request, urlopen

Expand Down Expand Up @@ -321,6 +321,28 @@ def _build_unexpected_body_error_message(body: str) -> str:
return message


def _warn_if_unknown_kwargs(endpoint: str, kwargs: Dict[str, Any], known_params: Set[str]) -> None:
"""Warn when **kwargs carries keys that are not declared parameters.

WebClient methods keep **kwargs as an escape hatch for undocumented API
fields, but typos such as thread_id (instead of thread_ts) are otherwise
forwarded silently. See https://github.com/slackapi/python-slack-sdk/issues/1923
"""
# for unit tests etc.
if os.environ.get("SKIP_SLACK_SDK_WARNING"):
return

unknown = sorted(key for key in kwargs if key not in known_params)
for key in unknown:
warnings.warn(
f"The `{key}` argument is not a recognized parameter of `{endpoint}` "
f"and will be forwarded to the Slack API as-is. "
f"If this was a typo, the intended parameter may be missing from the request.",
UserWarning,
stacklevel=3,
)


def _remove_none_values(d: dict) -> dict:
# To avoid having null values in JSON (Slack API does not work with null in many situations)
#
Expand Down
22 changes: 22 additions & 0 deletions slack_sdk/web/legacy_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
_update_call_participants,
_validate_for_legacy_client,
_warn_if_message_text_content_is_missing,
_warn_if_unknown_kwargs,
)


Expand Down Expand Up @@ -3293,6 +3294,27 @@ def chat_postMessage(

https://docs.slack.dev/reference/methods/chat.postMessage
"""
known_params = {
"channel",
"text",
"as_user",
"attachments",
"blocks",
"thread_ts",
"reply_broadcast",
"unfurl_links",
"unfurl_media",
"container_id",
"icon_emoji",
"icon_url",
"mrkdwn",
"link_names",
"username",
"parse",
"metadata",
"markdown_text",
}
_warn_if_unknown_kwargs("chat.postMessage", kwargs, known_params)
kwargs.update(
{
"channel": channel,
Expand Down
47 changes: 47 additions & 0 deletions tests/slack_sdk/web/test_web_client_unknown_kwargs_warnings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import unittest
import warnings

from slack_sdk import WebClient
from tests.web.mock_web_api_handler import MockHandler
from tests.mock_web_api_server import setup_mock_web_api_server, cleanup_mock_web_api_server


class TestWebClientUnknownKwargsWarnings(unittest.TestCase):
def setUp(self):
setup_mock_web_api_server(self, MockHandler)

def tearDown(self):
cleanup_mock_web_api_server(self)

def test_warns_on_thread_id_typo_chat_postMessage(self):
client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
with self.assertWarnsRegex(UserWarning, "`thread_id` argument is not a recognized parameter"):
resp = client.chat_postMessage(
channel="C111",
text="hi",
thread_id="1750000000.0001",
)
self.assertIsNone(resp["error"])

def test_warns_on_unfurl_link_typo_chat_postMessage(self):
client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
with self.assertWarnsRegex(UserWarning, "`unfurl_link` argument is not a recognized parameter"):
resp = client.chat_postMessage(
channel="C111",
text="hi",
unfurl_link=False,
)
self.assertIsNone(resp["error"])

def test_no_warning_for_known_thread_ts(self):
client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
with warnings.catch_warnings(record=True) as warning_list:
warnings.simplefilter("always")
resp = client.chat_postMessage(
channel="C111",
text="hi",
thread_ts="1750000000.0001",
)
unknown = [w for w in warning_list if "not a recognized parameter" in str(w.message)]
self.assertEqual(unknown, [])
self.assertIsNone(resp["error"])