diff --git a/docs/api-docs/slack_sdk/audit_logs/v1/logs.html b/docs/api-docs/slack_sdk/audit_logs/v1/logs.html
index 93041fb55..e63a1bff3 100644
--- a/docs/api-docs/slack_sdk/audit_logs/v1/logs.html
+++ b/docs/api-docs/slack_sdk/audit_logs/v1/logs.html
@@ -29,6 +29,35 @@
Module slack_sdk.audit_logs.v1.logs
from typing import Optional, List, Union, Any, Dict
+class App:
+ id: Optional[str]
+ name: Optional[str]
+ is_distributed: Optional[bool]
+ is_directory_approved: Optional[bool]
+ is_workflow_app: Optional[bool]
+ scopes: Optional[List[str]]
+ unknown_fields: Dict[str, Any]
+
+ def __init__(
+ self,
+ *,
+ id: Optional[str] = None,
+ name: Optional[str] = None,
+ is_distributed: Optional[bool] = None,
+ is_directory_approved: Optional[bool] = None,
+ is_workflow_app: Optional[bool] = None,
+ scopes: Optional[List[str]] = None,
+ **kwargs,
+ ) -> None:
+ self.id = id
+ self.name = name
+ self.is_distributed = is_distributed
+ self.is_directory_approved = is_directory_approved
+ self.is_workflow_app = is_workflow_app
+ self.scopes = scopes
+ self.unknown_fields = kwargs
+
+
class User:
id: Optional[str]
name: Optional[str]
@@ -96,6 +125,7 @@ Module slack_sdk.audit_logs.v1.logs
ua: Optional[str]
ip_address: Optional[str]
session_id: Optional[str]
+ app: Optional[App]
unknown_fields: Dict[str, Any]
def __init__(
@@ -105,12 +135,14 @@ Module slack_sdk.audit_logs.v1.logs
ua: Optional[str] = None,
ip_address: Optional[str] = None,
session_id: Optional[str] = None,
+ app: Optional[App] = None,
**kwargs,
) -> None:
self.location = Location(**location) if isinstance(location, dict) else location
self.ua = ua
self.ip_address = ip_address
self.session_id = session_id
+ self.app = app
self.unknown_fields = kwargs
@@ -146,6 +178,19 @@ Module slack_sdk.audit_logs.v1.logs
self.unknown_fields = kwargs
+class FeatureEnablement:
+ enabled: Optional[bool]
+
+ def __init__(
+ self,
+ *,
+ enabled: Optional[bool] = None,
+ **kwargs,
+ ) -> None:
+ self.enabled = enabled
+ self.unknown_fields = kwargs
+
+
class Details:
name: Optional[str]
new_value: Optional[Union[str, List[str], Dict[str, Any]]]
@@ -170,6 +215,7 @@ Module slack_sdk.audit_logs.v1.logs
previous_scopes: Optional[List[str]]
granular_bot_token: Optional[bool]
scopes: Optional[List[str]]
+ scopes_bot: Optional[List[str]]
resolution: Optional[str]
app_previously_resolved: Optional[bool]
admin_app_id: Optional[str]
@@ -210,6 +256,12 @@ Module slack_sdk.audit_logs.v1.logs
session_search_start: Optional[int]
deprecation_search_end: Optional[int]
is_error: Optional[bool]
+ creator: Optional[str]
+ team: Optional[str]
+ app_id: Optional[str]
+ enable_at_here: Optional[FeatureEnablement]
+ enable_at_channel: Optional[FeatureEnablement]
+ can_huddle: Optional[FeatureEnablement]
def __init__(
self,
@@ -237,6 +289,7 @@ Module slack_sdk.audit_logs.v1.logs
previous_scopes: Optional[List[str]] = None,
granular_bot_token: Optional[bool] = None,
scopes: Optional[List[str]] = None,
+ scopes_bot: Optional[List[str]] = None,
resolution: Optional[str] = None,
app_previously_resolved: Optional[bool] = None,
admin_app_id: Optional[str] = None,
@@ -276,6 +329,12 @@ Module slack_sdk.audit_logs.v1.logs
session_search_start: Optional[int] = None,
deprecation_search_end: Optional[int] = None,
is_error: Optional[bool] = None,
+ creator: Optional[str] = None,
+ team: Optional[str] = None,
+ app_id: Optional[str] = None,
+ enable_at_here: Optional[FeatureEnablement] = None,
+ enable_at_channel: Optional[FeatureEnablement] = None,
+ can_huddle: Optional[FeatureEnablement] = None,
**kwargs,
) -> None:
self.name = name
@@ -287,8 +346,12 @@ Module slack_sdk.audit_logs.v1.logs
self.non_sso_only = non_sso_only
self.type = type
self.is_workflow = is_workflow
- self.inviter = inviter if isinstance(inviter, User) else User(**inviter)
- self.kicker = kicker if isinstance(kicker, User) else User(**kicker)
+ self.inviter = (
+ inviter if inviter is None or isinstance(inviter, User) else User(**inviter)
+ )
+ self.kicker = (
+ kicker if kicker is None or isinstance(kicker, User) else User(**kicker)
+ )
self.shared_to = shared_to
self.reason = reason
self.origin_team = origin_team
@@ -301,6 +364,7 @@ Module slack_sdk.audit_logs.v1.logs
self.previous_scopes = previous_scopes
self.granular_bot_token = granular_bot_token
self.scopes = scopes
+ self.scopes_bot = scopes_bot
self.resolution = resolution
self.app_previously_resolved = app_previously_resolved
self.admin_app_id = admin_app_id
@@ -334,22 +398,24 @@ Module slack_sdk.audit_logs.v1.logs
self.is_token_rotation_enabled_app = is_token_rotation_enabled_app
self.old_retention_policy = (
old_retention_policy
- if isinstance(old_retention_policy, RetentionPolicy)
+ if old_retention_policy is None
+ or isinstance(old_retention_policy, RetentionPolicy)
else RetentionPolicy(**old_retention_policy)
)
self.new_retention_policy = (
new_retention_policy
- if isinstance(new_retention_policy, RetentionPolicy)
+ if new_retention_policy is None
+ or isinstance(new_retention_policy, RetentionPolicy)
else RetentionPolicy(**new_retention_policy)
)
self.who_can_post = (
who_can_post
- if isinstance(who_can_post, ConversationPref)
+ if who_can_post is None or isinstance(who_can_post, ConversationPref)
else ConversationPref(**who_can_post)
)
self.can_thread = (
can_thread
- if isinstance(can_thread, ConversationPref)
+ if can_thread is None or isinstance(can_thread, ConversationPref)
else ConversationPref(**can_thread)
)
self.is_external_limited = is_external_limited
@@ -357,35 +423,25 @@ Module slack_sdk.audit_logs.v1.logs
self.session_search_start = session_search_start
self.deprecation_search_end = deprecation_search_end
self.is_error = is_error
-
-
-class App:
- id: Optional[str]
- name: Optional[str]
- is_distributed: Optional[bool]
- is_directory_approved: Optional[bool]
- is_workflow_app: Optional[bool]
- scopes: Optional[List[str]]
- unknown_fields: Dict[str, Any]
-
- def __init__(
- self,
- *,
- id: Optional[str] = None,
- name: Optional[str] = None,
- is_distributed: Optional[bool] = None,
- is_directory_approved: Optional[bool] = None,
- is_workflow_app: Optional[bool] = None,
- scopes: Optional[List[str]] = None,
- **kwargs,
- ) -> None:
- self.id = id
- self.name = name
- self.is_distributed = is_distributed
- self.is_directory_approved = is_directory_approved
- self.is_workflow_app = is_workflow_app
- self.scopes = scopes
- self.unknown_fields = kwargs
+ self.creator = creator
+ self.team = team
+ self.app_id = app_id
+ self.enable_at_here = (
+ enable_at_here
+ if enable_at_here is None or isinstance(enable_at_here, FeatureEnablement)
+ else FeatureEnablement(**enable_at_here)
+ )
+ self.enable_at_channel = (
+ enable_at_channel
+ if enable_at_channel is None
+ or isinstance(enable_at_channel, FeatureEnablement)
+ else FeatureEnablement(**enable_at_channel)
+ )
+ self.can_huddle = (
+ can_huddle
+ if can_huddle is None or isinstance(can_huddle, FeatureEnablement)
+ else FeatureEnablement(**can_huddle)
+ )
class Channel:
@@ -830,7 +886,7 @@ Class variables
class Context
-(*, location: Optional[Location] = None, ua: Optional[str] = None, ip_address: Optional[str] = None, session_id: Optional[str] = None, **kwargs)
+(*, location: Optional[Location] = None, ua: Optional[str] = None, ip_address: Optional[str] = None, session_id: Optional[str] = None, app: Optional[App] = None, **kwargs)
@@ -843,6 +899,7 @@ Class variables
ua: Optional[str]
ip_address: Optional[str]
session_id: Optional[str]
+ app: Optional[App]
unknown_fields: Dict[str, Any]
def __init__(
@@ -852,16 +909,22 @@ Class variables
ua: Optional[str] = None,
ip_address: Optional[str] = None,
session_id: Optional[str] = None,
+ app: Optional[App] = None,
**kwargs,
) -> None:
self.location = Location(**location) if isinstance(location, dict) else location
self.ua = ua
self.ip_address = ip_address
self.session_id = session_id
+ self.app = app
self.unknown_fields = kwargs
Class variables
+var app : Optional[App]
+-
+
+
var ip_address : Optional[str]
-
@@ -923,7 +986,7 @@
Class variables
class Details
-(*, name: Optional[str] = None, new_value: Union[str, List[str], Dict[str, Any], ForwardRef(None)] = None, previous_value: Union[str, List[str], Dict[str, Any], ForwardRef(None)] = None, expires_on: Optional[int] = None, mobile_only: Optional[bool] = None, web_only: Optional[bool] = None, non_sso_only: Optional[bool] = None, type: Optional[str] = None, is_workflow: Optional[bool] = None, inviter: Union[Dict[str, Any], User, ForwardRef(None)] = None, kicker: Union[Dict[str, Any], User, ForwardRef(None)] = None, shared_to: Optional[str] = None, reason: Optional[str] = None, origin_team: Optional[str] = None, target_team: Optional[str] = None, is_internal_integration: Optional[bool] = None, cleared_resolution: Optional[str] = None, app_owner_id: Optional[str] = None, bot_scopes: Optional[List[str]] = None, new_scopes: Optional[List[str]] = None, previous_scopes: Optional[List[str]] = None, granular_bot_token: Optional[bool] = None, scopes: Optional[List[str]] = None, resolution: Optional[str] = None, app_previously_resolved: Optional[bool] = None, admin_app_id: Optional[str] = None, bot_id: Optional[str] = None, installer_user_id: Optional[str] = None, approver_id: Optional[str] = None, approval_type: Optional[str] = None, app_previously_approved: Optional[bool] = None, old_scopes: Optional[List[str]] = None, channels: Optional[List[str]] = None, permissions: Optional[List[Dict[str, Any]]] = None, new_version_id: Optional[str] = None, trigger: Optional[str] = None, export_type: Optional[str] = None, export_start_ts: Optional[str] = None, export_end_ts: Optional[str] = None, barrier_id: Optional[str] = None, primary_usergroup_id: Optional[str] = None, barriered_from_usergroup_ids: Optional[List[str]] = None, restricted_subjects: Optional[List[str]] = None, duration: Optional[int] = None, desktop_app_browser_quit: Optional[bool] = None, invite_id: Optional[str] = None, external_organization_id: Optional[str] = None, external_organization_name: Optional[str] = None, external_user_id: Optional[str] = None, external_user_email: Optional[str] = None, channel_id: Optional[str] = None, added_team_id: Optional[str] = None, is_token_rotation_enabled_app: Optional[bool] = None, old_retention_policy: Union[Dict[str, Any], RetentionPolicy, ForwardRef(None)] = None, new_retention_policy: Union[Dict[str, Any], RetentionPolicy, ForwardRef(None)] = None, who_can_post: Union[Dict[str, List[str]], ConversationPref, ForwardRef(None)] = None, can_thread: Union[Dict[str, List[str]], ConversationPref, ForwardRef(None)] = None, is_external_limited: Optional[bool] = None, exporting_team_id: Optional[int] = None, session_search_start: Optional[int] = None, deprecation_search_end: Optional[int] = None, is_error: Optional[bool] = None, **kwargs)
+(*, name: Optional[str] = None, new_value: Union[str, List[str], Dict[str, Any], ForwardRef(None)] = None, previous_value: Union[str, List[str], Dict[str, Any], ForwardRef(None)] = None, expires_on: Optional[int] = None, mobile_only: Optional[bool] = None, web_only: Optional[bool] = None, non_sso_only: Optional[bool] = None, type: Optional[str] = None, is_workflow: Optional[bool] = None, inviter: Union[Dict[str, Any], User, ForwardRef(None)] = None, kicker: Union[Dict[str, Any], User, ForwardRef(None)] = None, shared_to: Optional[str] = None, reason: Optional[str] = None, origin_team: Optional[str] = None, target_team: Optional[str] = None, is_internal_integration: Optional[bool] = None, cleared_resolution: Optional[str] = None, app_owner_id: Optional[str] = None, bot_scopes: Optional[List[str]] = None, new_scopes: Optional[List[str]] = None, previous_scopes: Optional[List[str]] = None, granular_bot_token: Optional[bool] = None, scopes: Optional[List[str]] = None, scopes_bot: Optional[List[str]] = None, resolution: Optional[str] = None, app_previously_resolved: Optional[bool] = None, admin_app_id: Optional[str] = None, bot_id: Optional[str] = None, installer_user_id: Optional[str] = None, approver_id: Optional[str] = None, approval_type: Optional[str] = None, app_previously_approved: Optional[bool] = None, old_scopes: Optional[List[str]] = None, channels: Optional[List[str]] = None, permissions: Optional[List[Dict[str, Any]]] = None, new_version_id: Optional[str] = None, trigger: Optional[str] = None, export_type: Optional[str] = None, export_start_ts: Optional[str] = None, export_end_ts: Optional[str] = None, barrier_id: Optional[str] = None, primary_usergroup_id: Optional[str] = None, barriered_from_usergroup_ids: Optional[List[str]] = None, restricted_subjects: Optional[List[str]] = None, duration: Optional[int] = None, desktop_app_browser_quit: Optional[bool] = None, invite_id: Optional[str] = None, external_organization_id: Optional[str] = None, external_organization_name: Optional[str] = None, external_user_id: Optional[str] = None, external_user_email: Optional[str] = None, channel_id: Optional[str] = None, added_team_id: Optional[str] = None, is_token_rotation_enabled_app: Optional[bool] = None, old_retention_policy: Union[Dict[str, Any], RetentionPolicy, ForwardRef(None)] = None, new_retention_policy: Union[Dict[str, Any], RetentionPolicy, ForwardRef(None)] = None, who_can_post: Union[Dict[str, List[str]], ConversationPref, ForwardRef(None)] = None, can_thread: Union[Dict[str, List[str]], ConversationPref, ForwardRef(None)] = None, is_external_limited: Optional[bool] = None, exporting_team_id: Optional[int] = None, session_search_start: Optional[int] = None, deprecation_search_end: Optional[int] = None, is_error: Optional[bool] = None, creator: Optional[str] = None, team: Optional[str] = None, app_id: Optional[str] = None, enable_at_here: Optional[FeatureEnablement] = None, enable_at_channel: Optional[FeatureEnablement] = None, can_huddle: Optional[FeatureEnablement] = None, **kwargs)
-
@@ -955,6 +1018,7 @@
Class variables
previous_scopes: Optional[List[str]]
granular_bot_token: Optional[bool]
scopes: Optional[List[str]]
+ scopes_bot: Optional[List[str]]
resolution: Optional[str]
app_previously_resolved: Optional[bool]
admin_app_id: Optional[str]
@@ -995,6 +1059,12 @@ Class variables
session_search_start: Optional[int]
deprecation_search_end: Optional[int]
is_error: Optional[bool]
+ creator: Optional[str]
+ team: Optional[str]
+ app_id: Optional[str]
+ enable_at_here: Optional[FeatureEnablement]
+ enable_at_channel: Optional[FeatureEnablement]
+ can_huddle: Optional[FeatureEnablement]
def __init__(
self,
@@ -1022,6 +1092,7 @@ Class variables
previous_scopes: Optional[List[str]] = None,
granular_bot_token: Optional[bool] = None,
scopes: Optional[List[str]] = None,
+ scopes_bot: Optional[List[str]] = None,
resolution: Optional[str] = None,
app_previously_resolved: Optional[bool] = None,
admin_app_id: Optional[str] = None,
@@ -1061,6 +1132,12 @@ Class variables
session_search_start: Optional[int] = None,
deprecation_search_end: Optional[int] = None,
is_error: Optional[bool] = None,
+ creator: Optional[str] = None,
+ team: Optional[str] = None,
+ app_id: Optional[str] = None,
+ enable_at_here: Optional[FeatureEnablement] = None,
+ enable_at_channel: Optional[FeatureEnablement] = None,
+ can_huddle: Optional[FeatureEnablement] = None,
**kwargs,
) -> None:
self.name = name
@@ -1072,8 +1149,12 @@ Class variables
self.non_sso_only = non_sso_only
self.type = type
self.is_workflow = is_workflow
- self.inviter = inviter if isinstance(inviter, User) else User(**inviter)
- self.kicker = kicker if isinstance(kicker, User) else User(**kicker)
+ self.inviter = (
+ inviter if inviter is None or isinstance(inviter, User) else User(**inviter)
+ )
+ self.kicker = (
+ kicker if kicker is None or isinstance(kicker, User) else User(**kicker)
+ )
self.shared_to = shared_to
self.reason = reason
self.origin_team = origin_team
@@ -1086,6 +1167,7 @@ Class variables
self.previous_scopes = previous_scopes
self.granular_bot_token = granular_bot_token
self.scopes = scopes
+ self.scopes_bot = scopes_bot
self.resolution = resolution
self.app_previously_resolved = app_previously_resolved
self.admin_app_id = admin_app_id
@@ -1119,29 +1201,50 @@ Class variables
self.is_token_rotation_enabled_app = is_token_rotation_enabled_app
self.old_retention_policy = (
old_retention_policy
- if isinstance(old_retention_policy, RetentionPolicy)
+ if old_retention_policy is None
+ or isinstance(old_retention_policy, RetentionPolicy)
else RetentionPolicy(**old_retention_policy)
)
self.new_retention_policy = (
new_retention_policy
- if isinstance(new_retention_policy, RetentionPolicy)
+ if new_retention_policy is None
+ or isinstance(new_retention_policy, RetentionPolicy)
else RetentionPolicy(**new_retention_policy)
)
self.who_can_post = (
who_can_post
- if isinstance(who_can_post, ConversationPref)
+ if who_can_post is None or isinstance(who_can_post, ConversationPref)
else ConversationPref(**who_can_post)
)
self.can_thread = (
can_thread
- if isinstance(can_thread, ConversationPref)
+ if can_thread is None or isinstance(can_thread, ConversationPref)
else ConversationPref(**can_thread)
)
self.is_external_limited = is_external_limited
self.exporting_team_id = exporting_team_id
self.session_search_start = session_search_start
self.deprecation_search_end = deprecation_search_end
- self.is_error = is_error
+ self.is_error = is_error
+ self.creator = creator
+ self.team = team
+ self.app_id = app_id
+ self.enable_at_here = (
+ enable_at_here
+ if enable_at_here is None or isinstance(enable_at_here, FeatureEnablement)
+ else FeatureEnablement(**enable_at_here)
+ )
+ self.enable_at_channel = (
+ enable_at_channel
+ if enable_at_channel is None
+ or isinstance(enable_at_channel, FeatureEnablement)
+ else FeatureEnablement(**enable_at_channel)
+ )
+ self.can_huddle = (
+ can_huddle
+ if can_huddle is None or isinstance(can_huddle, FeatureEnablement)
+ else FeatureEnablement(**can_huddle)
+ )
Class variables
@@ -1153,6 +1256,10 @@ Class variables
-
+var app_id : Optional[str]
+-
+
+
var app_owner_id : Optional[str]
-
@@ -1189,6 +1296,10 @@
Class variables
-
+ var can_huddle : Optional[FeatureEnablement]
+-
+
+
var can_thread : Optional[ConversationPref]
-
@@ -1205,6 +1316,10 @@
Class variables
-
+ var creator : Optional[str]
+-
+
+
var deprecation_search_end : Optional[int]
-
@@ -1217,6 +1332,14 @@
Class variables
-
+ var enable_at_channel : Optional[FeatureEnablement]
+-
+
+
+var enable_at_here : Optional[FeatureEnablement]
+-
+
+
var expires_on : Optional[int]
-
@@ -1365,6 +1488,10 @@
Class variables
-
+ var scopes_bot : Optional[List[str]]
+-
+
+
var session_search_start : Optional[int]
-
@@ -1377,6 +1504,10 @@
Class variables
-
+ var team : Optional[str]
+-
+
+
var trigger : Optional[str]
-
@@ -1582,6 +1713,36 @@
Class variables
+
+class FeatureEnablement
+(*, enabled: Optional[bool] = None, **kwargs)
+
+-
+
+
+
+Expand source code
+
+class FeatureEnablement:
+ enabled: Optional[bool]
+
+ def __init__(
+ self,
+ *,
+ enabled: Optional[bool] = None,
+ **kwargs,
+ ) -> None:
+ self.enabled = enabled
+ self.unknown_fields = kwargs
+
+Class variables
+
+var enabled : Optional[bool]
+-
+
+
+
+
class File
(*, id: Optional[str] = None, name: Optional[str] = None, filetype: Optional[str] = None, title: Optional[str] = None, **kwargs)
@@ -2094,7 +2255,8 @@
-
+
+app
ip_address
location
session_id
@@ -2114,6 +2276,7 @@
added_team_id
admin_app_id
+app_id
app_owner_id
app_previously_approved
app_previously_resolved
@@ -2123,13 +2286,17 @@ bot_id
bot_scopes
+can_huddle
can_thread
channel_id
channels
cleared_resolution
+creator
deprecation_search_end
desktop_app_browser_quit
duration
+enable_at_channel
+enable_at_here
expires_on
export_end_ts
export_start_ts
@@ -2167,9 +2334,11 @@ restricted_subjects
scopes
+scopes_bot
session_search_start
shared_to
target_team
+team
trigger
type
unknown_fields
@@ -2207,6 +2376,12 @@
+
+
+-
filetype
diff --git a/docs/api-docs/slack_sdk/version.html b/docs/api-docs/slack_sdk/version.html
index d3ba7bf22..27637897b 100644
--- a/docs/api-docs/slack_sdk/version.html
+++ b/docs/api-docs/slack_sdk/version.html
@@ -28,7 +28,7 @@ Module slack_sdk.version
Expand source code
"""Check the latest version at https://pypi.org/project/slack-sdk/"""
-__version__ = "3.16.0"
+__version__ = "3.16.1"
diff --git a/docs/api-docs/slack_sdk/web/async_client.html b/docs/api-docs/slack_sdk/web/async_client.html
index 7c47e979e..cd7dbbeda 100644
--- a/docs/api-docs/slack_sdk/web/async_client.html
+++ b/docs/api-docs/slack_sdk/web/async_client.html
@@ -48,7 +48,7 @@ Module slack_sdk.web.async_client
from .internal_utils import (
_parse_web_class_objects,
_update_call_participants,
- _warn_if_text_is_missing,
+ _warn_if_text_or_attachment_fallback_is_missing,
_remove_none_values,
)
from ..models.attachments import Attachment
@@ -2104,7 +2104,7 @@ Module slack_sdk.web.async_client
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2158,7 +2158,7 @@ Module slack_sdk.web.async_client
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2202,7 +2202,7 @@ Module slack_sdk.web.async_client
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2275,7 +2275,7 @@ Module slack_sdk.web.async_client
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6657,7 +6657,7 @@ Note
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6711,7 +6711,7 @@ Note
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6755,7 +6755,7 @@ Note
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6828,7 +6828,7 @@ Note
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12328,7 +12328,7 @@ Methods
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12393,7 +12393,7 @@ Methods
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12448,7 +12448,7 @@ Methods
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12580,7 +12580,7 @@ Methods
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
diff --git a/docs/api-docs/slack_sdk/web/client.html b/docs/api-docs/slack_sdk/web/client.html
index 06fb40eba..1277dbf4a 100644
--- a/docs/api-docs/slack_sdk/web/client.html
+++ b/docs/api-docs/slack_sdk/web/client.html
@@ -39,7 +39,7 @@ Module slack_sdk.web.client
from .internal_utils import (
_parse_web_class_objects,
_update_call_participants,
- _warn_if_text_is_missing,
+ _warn_if_text_or_attachment_fallback_is_missing,
_remove_none_values,
)
from ..models.attachments import Attachment
@@ -2053,7 +2053,7 @@ Module slack_sdk.web.client
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2107,7 +2107,7 @@ Module slack_sdk.web.client
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2151,7 +2151,7 @@ Module slack_sdk.web.client
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2224,7 +2224,7 @@ Module slack_sdk.web.client
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6544,7 +6544,7 @@ Note
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6598,7 +6598,7 @@ Note
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6642,7 +6642,7 @@ Note
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6715,7 +6715,7 @@ Note
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12153,7 +12153,7 @@ Methods
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12218,7 +12218,7 @@ Methods
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12273,7 +12273,7 @@ Methods
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12405,7 +12405,7 @@ Methods
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
diff --git a/docs/api-docs/slack_sdk/web/internal_utils.html b/docs/api-docs/slack_sdk/web/internal_utils.html
index e59d732af..0d3415e6e 100644
--- a/docs/api-docs/slack_sdk/web/internal_utils.html
+++ b/docs/api-docs/slack_sdk/web/internal_utils.html
@@ -269,41 +269,55 @@ Module slack_sdk.web.internal_utils
return v
-def _warn_if_text_is_missing(endpoint: str, kwargs: Dict[str, Any]) -> None:
- missing = "text"
+def _warn_if_text_or_attachment_fallback_is_missing(
+ endpoint: str, kwargs: Dict[str, Any]
+) -> None:
+ text = kwargs.get("text")
+ if text and len(text.strip()) > 0:
+ # If a top-level text arg is provided, we are good. This is the recommended accessibility field to always provide.
+ return
+
+ # for unit tests etc.
+ skip_deprecation = os.environ.get("SKIP_SLACK_SDK_WARNING")
+ if skip_deprecation:
+ return
+
+ # At this point, at a minimum, text argument is missing. Warn the user about this.
+ message = (
+ f"The top-level `text` argument is missing in the request payload for a {endpoint} call - "
+ f"It's a best practice to always provide a `text` argument when posting a message. "
+ f"The `text` argument is used in places where content cannot be rendered such as: "
+ "system push notifications, assistive technology such as screen readers, etc."
+ )
+ warnings.warn(message, UserWarning)
+
+ # Additionally, specifically for attachments, there is a legacy field available at the attachment level called `fallback`
+ # Even with a missing text, one can provide a `fallback` per attachment.
+ # More details here: https://api.slack.com/reference/messaging/attachments#legacy_fields
attachments = kwargs.get("attachments")
# Note that this method does not verify attachments
# if the value is already serialized as a single str value.
- if attachments is not None and isinstance(attachments, list):
- # https://api.slack.com/reference/messaging/attachments
- # Check if the fallback field exists for all the attachments
- if all(
+ if (
+ attachments is not None
+ and isinstance(attachments, list)
+ and not all(
[
isinstance(attachment, dict)
and len(attachment.get("fallback", "").strip()) > 0
for attachment in attachments
]
- ):
- # The attachments are all good
- return
- missing = "fallback"
- else:
- text = kwargs.get("text")
- if text and len(text.strip()) > 0:
- # Note that this is applicable only for blocks.
- return
-
- message = (
- f"The `{missing}` argument is missing in the request payload for a {endpoint} call - "
- f"It's a best practice to always provide a `{missing}` argument when posting a message. "
- f"The `{missing}` argument is used in places where content cannot be rendered such as: "
- "system push notifications, assistive technology such as screen readers, etc."
- )
- # for unit tests etc.
- skip_deprecation = os.environ.get("SKIP_SLACK_SDK_WARNING")
- if skip_deprecation:
- return
- warnings.warn(message, UserWarning)
+ )
+ ):
+ # https://api.slack.com/reference/messaging/attachments
+ # Check if the fallback field exists for all the attachments
+ # Not all attachments have a fallback property; warn about this too!
+ message = (
+ f"Additionally, the attachment-level `fallback` argument is missing in the request payload for a {endpoint} call"
+ f" - To avoid this warning, it is recommended to always provide a top-level `text` argument when posting a"
+ f" message. Alternatively you can provide an attachment-level `fallback` argument, though this is now considered"
+ f" a legacy field (see https://api.slack.com/reference/messaging/attachments#legacy_fields for more details)."
+ )
+ warnings.warn(message, UserWarning)
def _build_unexpected_body_error_message(body: str) -> str:
diff --git a/docs/api-docs/slack_sdk/web/legacy_client.html b/docs/api-docs/slack_sdk/web/legacy_client.html
index 49c6fc8ab..6930dd54a 100644
--- a/docs/api-docs/slack_sdk/web/legacy_client.html
+++ b/docs/api-docs/slack_sdk/web/legacy_client.html
@@ -49,7 +49,7 @@ Module slack_sdk.web.legacy_client
from .internal_utils import (
_parse_web_class_objects,
_update_call_participants,
- _warn_if_text_is_missing,
+ _warn_if_text_or_attachment_fallback_is_missing,
_remove_none_values,
)
from ..models.attachments import Attachment
@@ -2063,7 +2063,7 @@ Module slack_sdk.web.legacy_client
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2117,7 +2117,7 @@ Module slack_sdk.web.legacy_client
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2161,7 +2161,7 @@ Module slack_sdk.web.legacy_client
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2234,7 +2234,7 @@ Module slack_sdk.web.legacy_client
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6554,7 +6554,7 @@ Note
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6608,7 +6608,7 @@ Note
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6652,7 +6652,7 @@ Note
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -6725,7 +6725,7 @@ Note
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12163,7 +12163,7 @@ Methods
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12228,7 +12228,7 @@ Methods
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12283,7 +12283,7 @@ Methods
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -12415,7 +12415,7 @@ Methods
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
diff --git a/pytest.ini b/pytest.ini
index c1710c8ef..c9030f7af 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -5,4 +5,5 @@ log_format = %(asctime)s %(levelname)s %(message)s
log_date_format = %Y-%m-%d %H:%M:%S
filterwarnings =
ignore:"@coroutine" decorator is deprecated since Python 3.8, use "async def" instead:DeprecationWarning
- ignore:The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.:DeprecationWarning
\ No newline at end of file
+ ignore:The loop argument is deprecated since Python 3.8, and scheduled for removal in Python 3.10.:DeprecationWarning
+asyncio_mode = auto
diff --git a/setup.py b/setup.py
index eec35c1af..af5ca12e0 100644
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@
"Flask-Sockets>=0.2,<1",
"Flask>=1,<2", # TODO: Flask-Sockets is not yet compatible with Flask 2.x
"Werkzeug<2", # TODO: Flask-Sockets is not yet compatible with Flask 2.x
- "itsdangerous==2.0.1", # TODO: Flask-Sockets is not yet compatible with Flask 2.x
+ "itsdangerous==1.1.0", # TODO: Flask-Sockets is not yet compatible with Flask 2.x
"Jinja2==3.0.3", # https://github.com/pallets/flask/issues/4494
"pytest-cov>=2,<3",
"codecov>=2,<3",
diff --git a/slack_sdk/audit_logs/v1/logs.py b/slack_sdk/audit_logs/v1/logs.py
index 170d7716d..d72b55a86 100644
--- a/slack_sdk/audit_logs/v1/logs.py
+++ b/slack_sdk/audit_logs/v1/logs.py
@@ -1,6 +1,35 @@
from typing import Optional, List, Union, Any, Dict
+class App:
+ id: Optional[str]
+ name: Optional[str]
+ is_distributed: Optional[bool]
+ is_directory_approved: Optional[bool]
+ is_workflow_app: Optional[bool]
+ scopes: Optional[List[str]]
+ unknown_fields: Dict[str, Any]
+
+ def __init__(
+ self,
+ *,
+ id: Optional[str] = None,
+ name: Optional[str] = None,
+ is_distributed: Optional[bool] = None,
+ is_directory_approved: Optional[bool] = None,
+ is_workflow_app: Optional[bool] = None,
+ scopes: Optional[List[str]] = None,
+ **kwargs,
+ ) -> None:
+ self.id = id
+ self.name = name
+ self.is_distributed = is_distributed
+ self.is_directory_approved = is_directory_approved
+ self.is_workflow_app = is_workflow_app
+ self.scopes = scopes
+ self.unknown_fields = kwargs
+
+
class User:
id: Optional[str]
name: Optional[str]
@@ -68,6 +97,7 @@ class Context:
ua: Optional[str]
ip_address: Optional[str]
session_id: Optional[str]
+ app: Optional[App]
unknown_fields: Dict[str, Any]
def __init__(
@@ -77,12 +107,14 @@ def __init__(
ua: Optional[str] = None,
ip_address: Optional[str] = None,
session_id: Optional[str] = None,
+ app: Optional[App] = None,
**kwargs,
) -> None:
self.location = Location(**location) if isinstance(location, dict) else location
self.ua = ua
self.ip_address = ip_address
self.session_id = session_id
+ self.app = app
self.unknown_fields = kwargs
@@ -118,6 +150,19 @@ def __init__(
self.unknown_fields = kwargs
+class FeatureEnablement:
+ enabled: Optional[bool]
+
+ def __init__(
+ self,
+ *,
+ enabled: Optional[bool] = None,
+ **kwargs,
+ ) -> None:
+ self.enabled = enabled
+ self.unknown_fields = kwargs
+
+
class Details:
name: Optional[str]
new_value: Optional[Union[str, List[str], Dict[str, Any]]]
@@ -142,6 +187,7 @@ class Details:
previous_scopes: Optional[List[str]]
granular_bot_token: Optional[bool]
scopes: Optional[List[str]]
+ scopes_bot: Optional[List[str]]
resolution: Optional[str]
app_previously_resolved: Optional[bool]
admin_app_id: Optional[str]
@@ -182,6 +228,12 @@ class Details:
session_search_start: Optional[int]
deprecation_search_end: Optional[int]
is_error: Optional[bool]
+ creator: Optional[str]
+ team: Optional[str]
+ app_id: Optional[str]
+ enable_at_here: Optional[FeatureEnablement]
+ enable_at_channel: Optional[FeatureEnablement]
+ can_huddle: Optional[FeatureEnablement]
def __init__(
self,
@@ -209,6 +261,7 @@ def __init__(
previous_scopes: Optional[List[str]] = None,
granular_bot_token: Optional[bool] = None,
scopes: Optional[List[str]] = None,
+ scopes_bot: Optional[List[str]] = None,
resolution: Optional[str] = None,
app_previously_resolved: Optional[bool] = None,
admin_app_id: Optional[str] = None,
@@ -248,6 +301,12 @@ def __init__(
session_search_start: Optional[int] = None,
deprecation_search_end: Optional[int] = None,
is_error: Optional[bool] = None,
+ creator: Optional[str] = None,
+ team: Optional[str] = None,
+ app_id: Optional[str] = None,
+ enable_at_here: Optional[FeatureEnablement] = None,
+ enable_at_channel: Optional[FeatureEnablement] = None,
+ can_huddle: Optional[FeatureEnablement] = None,
**kwargs,
) -> None:
self.name = name
@@ -259,8 +318,12 @@ def __init__(
self.non_sso_only = non_sso_only
self.type = type
self.is_workflow = is_workflow
- self.inviter = inviter if isinstance(inviter, User) else User(**inviter)
- self.kicker = kicker if isinstance(kicker, User) else User(**kicker)
+ self.inviter = (
+ inviter if inviter is None or isinstance(inviter, User) else User(**inviter)
+ )
+ self.kicker = (
+ kicker if kicker is None or isinstance(kicker, User) else User(**kicker)
+ )
self.shared_to = shared_to
self.reason = reason
self.origin_team = origin_team
@@ -273,6 +336,7 @@ def __init__(
self.previous_scopes = previous_scopes
self.granular_bot_token = granular_bot_token
self.scopes = scopes
+ self.scopes_bot = scopes_bot
self.resolution = resolution
self.app_previously_resolved = app_previously_resolved
self.admin_app_id = admin_app_id
@@ -306,22 +370,24 @@ def __init__(
self.is_token_rotation_enabled_app = is_token_rotation_enabled_app
self.old_retention_policy = (
old_retention_policy
- if isinstance(old_retention_policy, RetentionPolicy)
+ if old_retention_policy is None
+ or isinstance(old_retention_policy, RetentionPolicy)
else RetentionPolicy(**old_retention_policy)
)
self.new_retention_policy = (
new_retention_policy
- if isinstance(new_retention_policy, RetentionPolicy)
+ if new_retention_policy is None
+ or isinstance(new_retention_policy, RetentionPolicy)
else RetentionPolicy(**new_retention_policy)
)
self.who_can_post = (
who_can_post
- if isinstance(who_can_post, ConversationPref)
+ if who_can_post is None or isinstance(who_can_post, ConversationPref)
else ConversationPref(**who_can_post)
)
self.can_thread = (
can_thread
- if isinstance(can_thread, ConversationPref)
+ if can_thread is None or isinstance(can_thread, ConversationPref)
else ConversationPref(**can_thread)
)
self.is_external_limited = is_external_limited
@@ -329,35 +395,25 @@ def __init__(
self.session_search_start = session_search_start
self.deprecation_search_end = deprecation_search_end
self.is_error = is_error
-
-
-class App:
- id: Optional[str]
- name: Optional[str]
- is_distributed: Optional[bool]
- is_directory_approved: Optional[bool]
- is_workflow_app: Optional[bool]
- scopes: Optional[List[str]]
- unknown_fields: Dict[str, Any]
-
- def __init__(
- self,
- *,
- id: Optional[str] = None,
- name: Optional[str] = None,
- is_distributed: Optional[bool] = None,
- is_directory_approved: Optional[bool] = None,
- is_workflow_app: Optional[bool] = None,
- scopes: Optional[List[str]] = None,
- **kwargs,
- ) -> None:
- self.id = id
- self.name = name
- self.is_distributed = is_distributed
- self.is_directory_approved = is_directory_approved
- self.is_workflow_app = is_workflow_app
- self.scopes = scopes
- self.unknown_fields = kwargs
+ self.creator = creator
+ self.team = team
+ self.app_id = app_id
+ self.enable_at_here = (
+ enable_at_here
+ if enable_at_here is None or isinstance(enable_at_here, FeatureEnablement)
+ else FeatureEnablement(**enable_at_here)
+ )
+ self.enable_at_channel = (
+ enable_at_channel
+ if enable_at_channel is None
+ or isinstance(enable_at_channel, FeatureEnablement)
+ else FeatureEnablement(**enable_at_channel)
+ )
+ self.can_huddle = (
+ can_huddle
+ if can_huddle is None or isinstance(can_huddle, FeatureEnablement)
+ else FeatureEnablement(**can_huddle)
+ )
class Channel:
diff --git a/slack_sdk/version.py b/slack_sdk/version.py
index 487f9c304..d5250dae3 100644
--- a/slack_sdk/version.py
+++ b/slack_sdk/version.py
@@ -1,2 +1,2 @@
"""Check the latest version at https://pypi.org/project/slack-sdk/"""
-__version__ = "3.16.0"
+__version__ = "3.16.1"
diff --git a/slack_sdk/web/async_client.py b/slack_sdk/web/async_client.py
index c3ca205fb..12cfeb4f7 100644
--- a/slack_sdk/web/async_client.py
+++ b/slack_sdk/web/async_client.py
@@ -19,7 +19,7 @@
from .internal_utils import (
_parse_web_class_objects,
_update_call_participants,
- _warn_if_text_is_missing,
+ _warn_if_text_or_attachment_fallback_is_missing,
_remove_none_values,
)
from ..models.attachments import Attachment
@@ -2075,7 +2075,7 @@ async def chat_postEphemeral(
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2129,7 +2129,7 @@ async def chat_postMessage(
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2173,7 +2173,7 @@ async def chat_scheduleMessage(
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2246,7 +2246,7 @@ async def chat_update(
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
diff --git a/slack_sdk/web/client.py b/slack_sdk/web/client.py
index 9d26c6894..f64582d22 100644
--- a/slack_sdk/web/client.py
+++ b/slack_sdk/web/client.py
@@ -10,7 +10,7 @@
from .internal_utils import (
_parse_web_class_objects,
_update_call_participants,
- _warn_if_text_is_missing,
+ _warn_if_text_or_attachment_fallback_is_missing,
_remove_none_values,
)
from ..models.attachments import Attachment
@@ -2024,7 +2024,7 @@ def chat_postEphemeral(
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2078,7 +2078,7 @@ def chat_postMessage(
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2122,7 +2122,7 @@ def chat_scheduleMessage(
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2195,7 +2195,7 @@ def chat_update(
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
diff --git a/slack_sdk/web/internal_utils.py b/slack_sdk/web/internal_utils.py
index 115478923..7e45f685e 100644
--- a/slack_sdk/web/internal_utils.py
+++ b/slack_sdk/web/internal_utils.py
@@ -241,41 +241,55 @@ def _to_0_or_1_if_bool(v: Any) -> Union[Any, str]:
return v
-def _warn_if_text_is_missing(endpoint: str, kwargs: Dict[str, Any]) -> None:
- missing = "text"
+def _warn_if_text_or_attachment_fallback_is_missing(
+ endpoint: str, kwargs: Dict[str, Any]
+) -> None:
+ text = kwargs.get("text")
+ if text and len(text.strip()) > 0:
+ # If a top-level text arg is provided, we are good. This is the recommended accessibility field to always provide.
+ return
+
+ # for unit tests etc.
+ skip_deprecation = os.environ.get("SKIP_SLACK_SDK_WARNING")
+ if skip_deprecation:
+ return
+
+ # At this point, at a minimum, text argument is missing. Warn the user about this.
+ message = (
+ f"The top-level `text` argument is missing in the request payload for a {endpoint} call - "
+ f"It's a best practice to always provide a `text` argument when posting a message. "
+ f"The `text` argument is used in places where content cannot be rendered such as: "
+ "system push notifications, assistive technology such as screen readers, etc."
+ )
+ warnings.warn(message, UserWarning)
+
+ # Additionally, specifically for attachments, there is a legacy field available at the attachment level called `fallback`
+ # Even with a missing text, one can provide a `fallback` per attachment.
+ # More details here: https://api.slack.com/reference/messaging/attachments#legacy_fields
attachments = kwargs.get("attachments")
# Note that this method does not verify attachments
# if the value is already serialized as a single str value.
- if attachments is not None and isinstance(attachments, list):
- # https://api.slack.com/reference/messaging/attachments
- # Check if the fallback field exists for all the attachments
- if all(
+ if (
+ attachments is not None
+ and isinstance(attachments, list)
+ and not all(
[
isinstance(attachment, dict)
and len(attachment.get("fallback", "").strip()) > 0
for attachment in attachments
]
- ):
- # The attachments are all good
- return
- missing = "fallback"
- else:
- text = kwargs.get("text")
- if text and len(text.strip()) > 0:
- # Note that this is applicable only for blocks.
- return
-
- message = (
- f"The `{missing}` argument is missing in the request payload for a {endpoint} call - "
- f"It's a best practice to always provide a `{missing}` argument when posting a message. "
- f"The `{missing}` argument is used in places where content cannot be rendered such as: "
- "system push notifications, assistive technology such as screen readers, etc."
- )
- # for unit tests etc.
- skip_deprecation = os.environ.get("SKIP_SLACK_SDK_WARNING")
- if skip_deprecation:
- return
- warnings.warn(message, UserWarning)
+ )
+ ):
+ # https://api.slack.com/reference/messaging/attachments
+ # Check if the fallback field exists for all the attachments
+ # Not all attachments have a fallback property; warn about this too!
+ message = (
+ f"Additionally, the attachment-level `fallback` argument is missing in the request payload for a {endpoint} call"
+ f" - To avoid this warning, it is recommended to always provide a top-level `text` argument when posting a"
+ f" message. Alternatively you can provide an attachment-level `fallback` argument, though this is now considered"
+ f" a legacy field (see https://api.slack.com/reference/messaging/attachments#legacy_fields for more details)."
+ )
+ warnings.warn(message, UserWarning)
def _build_unexpected_body_error_message(body: str) -> str:
diff --git a/slack_sdk/web/legacy_client.py b/slack_sdk/web/legacy_client.py
index 626b1a927..4de793c91 100644
--- a/slack_sdk/web/legacy_client.py
+++ b/slack_sdk/web/legacy_client.py
@@ -21,7 +21,7 @@
from .internal_utils import (
_parse_web_class_objects,
_update_call_participants,
- _warn_if_text_is_missing,
+ _warn_if_text_or_attachment_fallback_is_missing,
_remove_none_values,
)
from ..models.attachments import Attachment
@@ -2035,7 +2035,7 @@ def chat_postEphemeral(
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postEphemeral", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2089,7 +2089,7 @@ def chat_postMessage(
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.postMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2133,7 +2133,7 @@ def chat_scheduleMessage(
)
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.scheduleMessage", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
@@ -2206,7 +2206,7 @@ def chat_update(
kwargs.update({"file_ids": file_ids})
_parse_web_class_objects(kwargs)
kwargs = _remove_none_values(kwargs)
- _warn_if_text_is_missing("chat.update", kwargs)
+ _warn_if_text_or_attachment_fallback_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)
diff --git a/tests/slack_sdk/web/test_web_client_issue_891.py b/tests/slack_sdk/web/test_web_client_issue_891.py
index 27c742dbc..5def6888b 100644
--- a/tests/slack_sdk/web/test_web_client_issue_891.py
+++ b/tests/slack_sdk/web/test_web_client_issue_891.py
@@ -14,24 +14,64 @@ def setUp(self):
def tearDown(self):
cleanup_mock_web_api_server(self)
- def test_missing_text_warnings_chat_postMessage(self):
+ def test_missing_text_warning_chat_postMessage(self):
client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = client.chat_postMessage(channel="C111", blocks=[])
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = client.chat_postMessage(channel="C111", blocks=[])
self.assertIsNone(resp["error"])
- def test_missing_text_warnings_chat_postEphemeral(self):
+ def test_missing_text_warning_chat_postEphemeral(self):
client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = client.chat_postEphemeral(channel="C111", user="U111", blocks=[])
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = client.chat_postEphemeral(channel="C111", user="U111", blocks=[])
self.assertIsNone(resp["error"])
- def test_missing_text_warnings_chat_scheduleMessage(self):
+ def test_missing_text_warning_chat_scheduleMessage(self):
client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = client.chat_scheduleMessage(
- channel="C111", post_at="299876400", text="", blocks=[]
- )
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = client.chat_scheduleMessage(
+ channel="C111", post_at="299876400", text="", blocks=[]
+ )
self.assertIsNone(resp["error"])
- def test_missing_text_warnings_chat_update(self):
+ def test_missing_text_warning_chat_update(self):
client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = client.chat_update(channel="C111", ts="111.222", blocks=[])
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = client.chat_update(channel="C111", ts="111.222", blocks=[])
+ self.assertIsNone(resp["error"])
+
+ def test_missing_fallback_warning_chat_postMessage(self):
+ client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`fallback` argument is missing"):
+ resp = client.chat_postMessage(
+ channel="C111", blocks=[], attachments=[{"text": "hi"}]
+ )
+ self.assertIsNone(resp["error"])
+
+ def test_missing_fallback_warning_chat_postEphemeral(self):
+ client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`fallback` argument is missing"):
+ resp = client.chat_postEphemeral(
+ channel="C111", user="U111", blocks=[], attachments=[{"text": "hi"}]
+ )
+ self.assertIsNone(resp["error"])
+
+ def test_missing_fallback_warning_chat_scheduleMessage(self):
+ client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`fallback` argument is missing"):
+ resp = client.chat_scheduleMessage(
+ channel="C111",
+ post_at="299876400",
+ text="",
+ blocks=[],
+ attachments=[{"text": "hi"}],
+ )
+ self.assertIsNone(resp["error"])
+
+ def test_missing_fallback_warning_chat_update(self):
+ client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`fallback` argument is missing"):
+ resp = client.chat_update(
+ channel="C111", ts="111.222", blocks=[], attachments=[{"text": "hi"}]
+ )
self.assertIsNone(resp["error"])
diff --git a/tests/slack_sdk/web/test_web_client_issue_971.py b/tests/slack_sdk/web/test_web_client_issue_971.py
index e2c5e8ea5..274e7173f 100644
--- a/tests/slack_sdk/web/test_web_client_issue_971.py
+++ b/tests/slack_sdk/web/test_web_client_issue_971.py
@@ -33,6 +33,7 @@ def test_blocks_without_text_arg(self):
client = WebClient(
base_url="http://localhost:8888", token="xoxb-api_test", team_id="T111"
)
+ # this generates a warning because "text" is missing
with self.assertWarns(UserWarning):
resp = client.chat_postMessage(channel="C111", blocks=[])
self.assertTrue(resp["ok"])
@@ -41,6 +42,7 @@ def test_attachments_with_fallback(self):
client = WebClient(
base_url="http://localhost:8888", token="xoxb-api_test", team_id="T111"
)
+ # this generates a warning because "text" is missing
resp = client.chat_postMessage(
channel="C111", attachments=[{"fallback": "test"}]
)
@@ -50,6 +52,7 @@ def test_attachments_with_empty_fallback(self):
client = WebClient(
base_url="http://localhost:8888", token="xoxb-api_test", team_id="T111"
)
+ # this generates two warnings: "text" is missing, and also one attachment with no fallback
with self.assertWarns(UserWarning):
resp = client.chat_postMessage(
channel="C111", attachments=[{"fallback": ""}]
@@ -60,25 +63,16 @@ def test_attachments_without_fallback(self):
client = WebClient(
base_url="http://localhost:8888", token="xoxb-api_test", team_id="T111"
)
+ # this generates two warnings: "text" is missing, and also one attachment with no fallback
with self.assertWarns(UserWarning):
resp = client.chat_postMessage(channel="C111", attachments=[{}])
self.assertTrue(resp["ok"])
- def test_attachments_without_fallback_with_text_arg(self):
- client = WebClient(
- base_url="http://localhost:8888", token="xoxb-api_test", team_id="T111"
- )
- # this warns because each attachment should have its own fallback, even with "text"
- with self.assertWarns(UserWarning):
- resp = client.chat_postMessage(
- channel="C111", text="test", attachments=[{}]
- )
- self.assertTrue(resp["ok"])
-
def test_multiple_attachments_one_without_fallback(self):
client = WebClient(
base_url="http://localhost:8888", token="xoxb-api_test", team_id="T111"
)
+ # this generates two warnings: "text" is missing, and also one attachment with no fallback
with self.assertWarns(UserWarning):
resp = client.chat_postMessage(
channel="C111", attachments=[{"fallback": "test"}, {}]
diff --git a/tests/slack_sdk_async/web/test_web_client_issue_891.py b/tests/slack_sdk_async/web/test_web_client_issue_891.py
index a21371ddc..10d2d6a98 100644
--- a/tests/slack_sdk_async/web/test_web_client_issue_891.py
+++ b/tests/slack_sdk_async/web/test_web_client_issue_891.py
@@ -16,27 +16,73 @@ def tearDown(self):
cleanup_mock_web_api_server(self)
@async_test
- async def test_missing_text_warnings_chat_postMessage(self):
+ async def test_missing_text_warning_chat_postMessage(self):
client = AsyncWebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = await client.chat_postMessage(channel="C111", blocks=[])
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = await client.chat_postMessage(channel="C111", blocks=[])
self.assertIsNone(resp["error"])
@async_test
- async def test_missing_text_warnings_chat_postEphemeral(self):
+ async def test_missing_text_warning_chat_postEphemeral(self):
client = AsyncWebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = await client.chat_postEphemeral(channel="C111", user="U111", blocks=[])
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = await client.chat_postEphemeral(
+ channel="C111", user="U111", blocks=[]
+ )
self.assertIsNone(resp["error"])
@async_test
- async def test_missing_text_warnings_chat_scheduleMessage(self):
+ async def test_missing_text_warning_chat_scheduleMessage(self):
client = AsyncWebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = await client.chat_scheduleMessage(
- channel="C111", post_at="299876400", text="", blocks=[]
- )
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = await client.chat_scheduleMessage(
+ channel="C111", post_at="299876400", text="", blocks=[]
+ )
self.assertIsNone(resp["error"])
@async_test
- async def test_missing_text_warnings_chat_update(self):
+ async def test_missing_text_warning_chat_update(self):
client = AsyncWebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = await client.chat_update(channel="C111", ts="111.222", blocks=[])
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = await client.chat_update(channel="C111", ts="111.222", blocks=[])
+ self.assertIsNone(resp["error"])
+
+ @async_test
+ async def test_missing_fallback_warning_chat_postMessage(self):
+ client = AsyncWebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`fallback` argument is missing"):
+ resp = await client.chat_postMessage(
+ channel="C111", blocks=[], attachments=[{"text": "hi"}]
+ )
+ self.assertIsNone(resp["error"])
+
+ @async_test
+ async def test_missing_fallback_warning_chat_postEphemeral(self):
+ client = AsyncWebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`fallback` argument is missing"):
+ resp = await client.chat_postEphemeral(
+ channel="C111", user="U111", blocks=[], attachments=[{"text": "hi"}]
+ )
+ self.assertIsNone(resp["error"])
+
+ @async_test
+ async def test_missing_fallback_warning_chat_scheduleMessage(self):
+ client = AsyncWebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = await client.chat_scheduleMessage(
+ channel="C111",
+ post_at="299876400",
+ text="",
+ blocks=[],
+ attachments=[{"text": "hi"}],
+ )
+ self.assertIsNone(resp["error"])
+
+ @async_test
+ async def test_missing_fallback_warning_chat_update(self):
+ client = AsyncWebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = await client.chat_update(
+ channel="C111", ts="111.222", blocks=[], attachments=[{"text": "hi"}]
+ )
self.assertIsNone(resp["error"])
diff --git a/tests/web/test_web_client_issue_891.py b/tests/web/test_web_client_issue_891.py
index 19abfd6b0..d510e3744 100644
--- a/tests/web/test_web_client_issue_891.py
+++ b/tests/web/test_web_client_issue_891.py
@@ -14,24 +14,64 @@ def setUp(self):
def tearDown(self):
cleanup_mock_web_api_server(self)
- def test_missing_text_warnings_chat_postMessage(self):
+ def test_missing_text_warning_chat_postMessage(self):
client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = client.chat_postMessage(channel="C111", blocks=[])
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = client.chat_postMessage(channel="C111", blocks=[])
self.assertIsNone(resp["error"])
- def test_missing_text_warnings_chat_postEphemeral(self):
+ def test_missing_text_warning_chat_postEphemeral(self):
client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = client.chat_postEphemeral(channel="C111", user="U111", blocks=[])
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = client.chat_postEphemeral(channel="C111", user="U111", blocks=[])
self.assertIsNone(resp["error"])
- def test_missing_text_warnings_chat_scheduleMessage(self):
+ def test_missing_text_warning_chat_scheduleMessage(self):
client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = client.chat_scheduleMessage(
- channel="C111", post_at="299876400", text="", blocks=[]
- )
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = client.chat_scheduleMessage(
+ channel="C111", post_at="299876400", text="", blocks=[]
+ )
self.assertIsNone(resp["error"])
- def test_missing_text_warnings_chat_update(self):
+ def test_missing_text_warning_chat_update(self):
client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
- resp = client.chat_update(channel="C111", ts="111.222", blocks=[])
+ with self.assertWarnsRegex(UserWarning, "`text` argument is missing"):
+ resp = client.chat_update(channel="C111", ts="111.222", blocks=[])
+ self.assertIsNone(resp["error"])
+
+ def test_missing_fallback_warning_chat_postMessage(self):
+ client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`fallback` argument is missing"):
+ resp = client.chat_postMessage(
+ channel="C111", blocks=[], attachments=[{"text": "hi"}]
+ )
+ self.assertIsNone(resp["error"])
+
+ def test_missing_fallback_warning_chat_postEphemeral(self):
+ client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`fallback` argument is missing"):
+ resp = client.chat_postEphemeral(
+ channel="C111", user="U111", blocks=[], attachments=[{"text": "hi"}]
+ )
+ self.assertIsNone(resp["error"])
+
+ def test_missing_fallback_warning_chat_scheduleMessage(self):
+ client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`fallback` argument is missing"):
+ resp = client.chat_scheduleMessage(
+ channel="C111",
+ post_at="299876400",
+ text="",
+ blocks=[],
+ attachments=[{"text": "hi"}],
+ )
+ self.assertIsNone(resp["error"])
+
+ def test_missing_fallback_warning_chat_update(self):
+ client = WebClient(base_url="http://localhost:8888", token="xoxb-api_test")
+ with self.assertWarnsRegex(UserWarning, "`fallback` argument is missing"):
+ resp = client.chat_update(
+ channel="C111", ts="111.222", blocks=[], attachments=[{"text": "hi"}]
+ )
self.assertIsNone(resp["error"])