From 07160da52c446dba5a96ec6d394874a0eed40d0f Mon Sep 17 00:00:00 2001 From: hyaffe Date: Mon, 24 Aug 2026 14:38:32 +0300 Subject: [PATCH 1/4] =?UTF-8?q?HY/CRTX-275112/TelematryFailuresSlackListMe?= =?UTF-8?q?ssages=D7=B4=20=D7=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Packs/Slack/Integrations/SlackV3/SlackV3.py | 26 ++++++++++++------- Packs/Slack/Integrations/SlackV3/SlackV3.yml | 11 ++++++-- .../Integrations/SlackV3/SlackV3_test.py | 9 ++++--- Packs/Slack/ReleaseNotes/3_8_16.md | 9 +++++++ Packs/Slack/pack_metadata.json | 2 +- 5 files changed, 41 insertions(+), 16 deletions(-) create mode 100644 Packs/Slack/ReleaseNotes/3_8_16.md diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3.py b/Packs/Slack/Integrations/SlackV3/SlackV3.py index 3873ab2c7d28..8456d1dc2171 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3.py +++ b/Packs/Slack/Integrations/SlackV3/SlackV3.py @@ -3491,7 +3491,11 @@ def resolve_conversation_id_from_name(channel_name): channel_id = conversation_info.get("id") if not channel_id: - raise DemistoException(f"Channel '{channel_name}' does not exist.") + raise CortexResourceNotFoundError( + resource_type="Slack channel", + identifier=channel_name, + override_message=(f"Channel '{channel_name}' does not exist."), + ) return channel_id @@ -3513,7 +3517,11 @@ def conversation_history() -> None: thread_id = args.get("thread_id") if not conversation_id and not conversation_name: - raise ValueError("Either conversation_id or conversation_name must be provided.") + raise CortexMissingArgError( + ["conversation_id", "conversation_name"], + require_one=True, + override_message=("Either conversation_id or conversation_name must be provided."), + ) if not conversation_id: conversation_id = resolve_conversation_id_from_name(conversation_name) @@ -3530,11 +3538,11 @@ def conversation_history() -> None: if page_token: body["cursor"] = page_token - raw_response = send_slack_request_sync(CLIENT, "conversations.history", http_verb="GET", body=body) - - if not raw_response.get("ok"): - raise DemistoException( - f'An error occurred while listing conversation history: {raw_response.get("error")}', res=raw_response + try: + raw_response = send_slack_request_sync(CLIENT, "conversations.history", http_verb="GET", body=body) + except SlackApiError as e: + raise CortexExternalApiError( + override_message=f"An error occurred while listing conversation history: {e.response.get('error')}" ) messages: Any = raw_response.get("messages", []) @@ -3545,8 +3553,8 @@ def conversation_history() -> None: if isinstance(messages, dict): messages = [messages] if not isinstance(messages, list): - raise DemistoException( - f'An error occurred while listing conversation history: {raw_response.get("error")}', res=raw_response + raise CortexExternalApiError( + override_message=f"An error occurred while listing conversation history: {raw_response.get('error')}" ) context: List[Dict[str, Any]] = [] diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3.yml b/Packs/Slack/Integrations/SlackV3/SlackV3.yml index 3cb1cd9124fd..bf7dc56dd672 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3.yml +++ b/Packs/Slack/Integrations/SlackV3/SlackV3.yml @@ -503,9 +503,16 @@ script: - description: Deprecated. Use *conversation_id* instead. name: channel_id deprecated: true - - description: The name of the conversation. For channels, provide the channel name. For direct messages, use the username or display name. Either this or *conversation_id* is required. If both are provided, *conversation_id* takes precedence. + - description: >- + The name of the conversation. For channels, provide the channel name. For direct messages, use the username or display name. + Either this or *conversation_id* is required. If both are provided, *conversation_id* takes precedence. + IMPORTANT: Only use channel names explicitly confirmed by the user or previously retrieved via the 'slack-list-channels' command. + Do not guess or infer channel names (e.g. 'general', 'alerts', 'incidents') — guessed names will fail if the channel does not exist in the workspace. + Prefer *conversation_id* when available. name: conversation_name - - description: The ID of the conversation. Either this or *conversation_name* is required. If both are provided, *conversation_id* takes precedence. + - description: >- + The ID of the conversation. Either this or *conversation_name* is required. If both are provided, *conversation_id* takes precedence. + Prefer this over *conversation_name* when the ID is known, as it is more reliable and avoids name-resolution failures. name: conversation_id - defaultValue: 100 description: Set this argument to specify how many results to return. diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3_test.py b/Packs/Slack/Integrations/SlackV3/SlackV3_test.py index 9ca4c006e965..35838ed8b689 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3_test.py +++ b/Packs/Slack/Integrations/SlackV3/SlackV3_test.py @@ -6,6 +6,7 @@ from pytest_mock.plugin import MockerFixture import slack_sdk from CommonServerPython import * +from CommonServerPython import CortexMissingArgError, CortexResourceNotFoundError from slack_sdk.errors import SlackApiError from slack_sdk.web.async_slack_response import AsyncSlackResponse from slack_sdk.web.slack_response import SlackResponse @@ -5459,14 +5460,14 @@ def test_conversation_history_no_channel_provided_error(mocker): Given: A conversation_history command is configured and no channel parameters are provided When: The conversation_history command is called with args missing both conversation_id and conversation_name - Then: The command raises ValueError with appropriate error message + Then: The command raises CortexMissingArgError with appropriate error message """ args = {"limit": "10"} mocker.patch.object(demisto, "args", return_value=args) - with pytest.raises(ValueError, match="Either conversation_id or conversation_name must be provided."): + with pytest.raises(CortexMissingArgError, match="Either conversation_id or conversation_name must be provided."): conversation_history() @@ -5508,12 +5509,12 @@ def test_resolve_conversation_id_from_name_no_channel_found(mocker): Given: The resolve_conversation_id_from_name function is called with a channel name that doesn't exist. When: No private conversation or channel exists for the specified name and channel id is not provided. - Then: The function raises ValueError with appropriate error message indicating the channel was not found. + Then: The function raises CortexResourceNotFoundError with appropriate error message indicating the channel was not found. """ mocker.patch("SlackV3.get_direct_message_channel_id_by_username", return_value=None) mocker.patch("SlackV3.get_conversation_by_name", return_value={}) - with pytest.raises(DemistoException, match="Channel 'nonexistent' does not exist."): + with pytest.raises(CortexResourceNotFoundError, match="Slack channel 'nonexistent' does not exist in this workspace."): resolve_conversation_id_from_name("nonexistent") diff --git a/Packs/Slack/ReleaseNotes/3_8_16.md b/Packs/Slack/ReleaseNotes/3_8_16.md new file mode 100644 index 000000000000..b6e29dbb5324 --- /dev/null +++ b/Packs/Slack/ReleaseNotes/3_8_16.md @@ -0,0 +1,9 @@ +#### Integrations + +##### SlackV3 + +- documentation and metadata improvements. + + diff --git a/Packs/Slack/pack_metadata.json b/Packs/Slack/pack_metadata.json index 3448dd4065d6..d329d2e6207c 100644 --- a/Packs/Slack/pack_metadata.json +++ b/Packs/Slack/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Slack", "description": "Interact with Slack API - collect logs, send messages and notifications to your Slack team.", "support": "xsoar", - "currentVersion": "3.8.15", + "currentVersion": "3.8.16", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 7d2a65863c2c6d0f5c380e8ba04f5fb68cc35d5c Mon Sep 17 00:00:00 2001 From: hyaffe Date: Mon, 24 Aug 2026 14:47:17 +0300 Subject: [PATCH 2/4] revert yml --- Packs/Slack/Integrations/SlackV3/SlackV3.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3.yml b/Packs/Slack/Integrations/SlackV3/SlackV3.yml index bf7dc56dd672..3cb1cd9124fd 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3.yml +++ b/Packs/Slack/Integrations/SlackV3/SlackV3.yml @@ -503,16 +503,9 @@ script: - description: Deprecated. Use *conversation_id* instead. name: channel_id deprecated: true - - description: >- - The name of the conversation. For channels, provide the channel name. For direct messages, use the username or display name. - Either this or *conversation_id* is required. If both are provided, *conversation_id* takes precedence. - IMPORTANT: Only use channel names explicitly confirmed by the user or previously retrieved via the 'slack-list-channels' command. - Do not guess or infer channel names (e.g. 'general', 'alerts', 'incidents') — guessed names will fail if the channel does not exist in the workspace. - Prefer *conversation_id* when available. + - description: The name of the conversation. For channels, provide the channel name. For direct messages, use the username or display name. Either this or *conversation_id* is required. If both are provided, *conversation_id* takes precedence. name: conversation_name - - description: >- - The ID of the conversation. Either this or *conversation_name* is required. If both are provided, *conversation_id* takes precedence. - Prefer this over *conversation_name* when the ID is known, as it is more reliable and avoids name-resolution failures. + - description: The ID of the conversation. Either this or *conversation_name* is required. If both are provided, *conversation_id* takes precedence. name: conversation_id - defaultValue: 100 description: Set this argument to specify how many results to return. From 00928e56ae453dde1ad1fecd5b03880b3dc0a568 Mon Sep 17 00:00:00 2001 From: hyaffe Date: Mon, 24 Aug 2026 14:47:47 +0300 Subject: [PATCH 3/4] Trigger build From 98a14a0bbe5db24e81087ab7455380ae42dc56ad Mon Sep 17 00:00:00 2001 From: hyaffe Date: Mon, 24 Aug 2026 17:27:26 +0300 Subject: [PATCH 4/4] review --- Packs/Slack/Integrations/SlackV3/SlackV3.py | 4 ++-- Packs/Slack/Integrations/SlackV3/SlackV3_test.py | 2 +- Packs/Slack/ReleaseNotes/3_8_18.md | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3.py b/Packs/Slack/Integrations/SlackV3/SlackV3.py index 8456d1dc2171..1bd4a6f36865 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3.py +++ b/Packs/Slack/Integrations/SlackV3/SlackV3.py @@ -3494,7 +3494,7 @@ def resolve_conversation_id_from_name(channel_name): raise CortexResourceNotFoundError( resource_type="Slack channel", identifier=channel_name, - override_message=(f"Channel '{channel_name}' does not exist."), + override_message=f"Channel '{channel_name}' does not exist.", ) return channel_id @@ -3520,7 +3520,7 @@ def conversation_history() -> None: raise CortexMissingArgError( ["conversation_id", "conversation_name"], require_one=True, - override_message=("Either conversation_id or conversation_name must be provided."), + override_message="Either conversation_id or conversation_name must be provided.", ) if not conversation_id: diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3_test.py b/Packs/Slack/Integrations/SlackV3/SlackV3_test.py index 35838ed8b689..ddaca74f1342 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3_test.py +++ b/Packs/Slack/Integrations/SlackV3/SlackV3_test.py @@ -5514,7 +5514,7 @@ def test_resolve_conversation_id_from_name_no_channel_found(mocker): mocker.patch("SlackV3.get_direct_message_channel_id_by_username", return_value=None) mocker.patch("SlackV3.get_conversation_by_name", return_value={}) - with pytest.raises(CortexResourceNotFoundError, match="Slack channel 'nonexistent' does not exist in this workspace."): + with pytest.raises(CortexResourceNotFoundError, match="Channel 'nonexistent' does not exist."): resolve_conversation_id_from_name("nonexistent") diff --git a/Packs/Slack/ReleaseNotes/3_8_18.md b/Packs/Slack/ReleaseNotes/3_8_18.md index b81b6357d604..9d43d4f61756 100644 --- a/Packs/Slack/ReleaseNotes/3_8_18.md +++ b/Packs/Slack/ReleaseNotes/3_8_18.md @@ -1,10 +1,9 @@ #### Integrations -##### SlackV3 +##### Slack v3 -- documentation and metadata improvements. - -