Skip to content
Merged
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
19 changes: 16 additions & 3 deletions nui_shared_utils/slack_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,9 @@ def send_message(
blocks: Optional[List[Dict]] = None,
attachments: Optional[List[Dict]] = None,
include_lambda_header: bool = True,
event_type: Optional[str] = None
event_type: Optional[str] = None,
unfurl_links: Optional[bool] = None,
unfurl_media: Optional[bool] = None,
) -> bool:
"""
Send message to Slack channel with standardized error handling.
Expand All @@ -400,6 +402,10 @@ def send_message(
attachments: Legacy attachment objects (supports color sidebars)
include_lambda_header: Whether to include context header
event_type: Optional event type label for header (e.g., "Scheduled", "API", "SQS")
unfurl_links: Override Slack link unfurling. None leaves Slack's default;
False suppresses link preview cards (links stay clickable)
unfurl_media: Override Slack media unfurling. None leaves Slack's default;
False suppresses media preview cards

Returns:
True if successful, False otherwise
Expand All @@ -419,12 +425,19 @@ def _send_operation():
else:
blocks_with_header = blocks

response = self._service_client.chat_postMessage(
kwargs = dict(
channel=channel,
text=text,
blocks=blocks_with_header,
attachments=attachments
attachments=attachments,
)
# Forward unfurl controls only when explicitly set, so existing callers
# keep Slack's default behavior (and their call assertions stay unchanged).
if unfurl_links is not None:
kwargs["unfurl_links"] = unfurl_links
if unfurl_media is not None:
kwargs["unfurl_media"] = unfurl_media
response = self._service_client.chat_postMessage(**kwargs)

if response["ok"]:
log.info(
Expand Down
46 changes: 46 additions & 0 deletions tests/test_slack_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,52 @@ def test_send_message_with_attachments(self, mock_webclient, mock_get_secret):
channel="C123", text="Fallback", blocks=None, attachments=attachments
)

@patch("nui_shared_utils.base_client.get_secret")
@patch("nui_shared_utils.slack_client.WebClient")
def test_send_message_forwards_unfurl_flags(self, mock_webclient, mock_get_secret):
"""unfurl_links / unfurl_media are forwarded to chat_postMessage when set."""
mock_get_secret.return_value = {"bot_token": "xoxb-test-token"}
mock_client = Mock()
mock_webclient.return_value = mock_client
mock_client.chat_postMessage.return_value = {"ok": True, "ts": "1234567890.123456"}

slack = SlackClient(secret_name="test-secret")
result = slack.send_message(
"C123",
"Test message",
include_lambda_header=False,
unfurl_links=False,
unfurl_media=False,
)

assert result is True
mock_client.chat_postMessage.assert_called_once_with(
channel="C123",
text="Test message",
blocks=None,
attachments=None,
unfurl_links=False,
unfurl_media=False,
)

@patch("nui_shared_utils.base_client.get_secret")
@patch("nui_shared_utils.slack_client.WebClient")
def test_send_message_omits_unfurl_when_unset(self, mock_webclient, mock_get_secret):
"""When the unfurl flags are unset (default None), they are NOT forwarded, so
Slack's default behavior is preserved for every existing caller."""
mock_get_secret.return_value = {"bot_token": "xoxb-test-token"}
mock_client = Mock()
mock_webclient.return_value = mock_client
mock_client.chat_postMessage.return_value = {"ok": True, "ts": "1234567890.123456"}

slack = SlackClient(secret_name="test-secret")
result = slack.send_message("C123", "Test message", include_lambda_header=False)

assert result is True
_, kwargs = mock_client.chat_postMessage.call_args
assert "unfurl_links" not in kwargs
assert "unfurl_media" not in kwargs

@patch("nui_shared_utils.base_client.get_secret")
@patch("nui_shared_utils.slack_client.WebClient")
def test_send_message_api_error(self, mock_webclient, mock_get_secret):
Expand Down
Loading