A middleware can process request data before other middleware and listener functions.
@@ -47,9 +47,14 @@
Expand source code
class IgnoringSelfEvents(Middleware):
- def __init__(self, base_logger: Optional[logging.Logger] = None):
+ def __init__(
+ self,
+ base_logger: Optional[logging.Logger] = None,
+ ignoring_self_assistant_message_events_enabled: bool = True,
+ ):
"""Ignores the events generated by this bot user itself."""
self.logger = get_bolt_logger(IgnoringSelfEvents, base_logger=base_logger)
+ self.ignoring_self_assistant_message_events_enabled = ignoring_self_assistant_message_events_enabled
def process(
self,
@@ -62,6 +67,11 @@
# message events can have $.event.bot_id while it does not have its user_id
bot_id = req.body.get("event", {}).get("bot_id")
if self._is_self_event(auth_result, req.context.user_id, bot_id, req.body): # type: ignore[arg-type]
+ if self.ignoring_self_assistant_message_events_enabled is False:
+ if is_bot_message_event_in_assistant_thread(req.body):
+ # Assistant#bot_message handler acknowledges this pattern
+ return next()
+
self._debug_log(req.body)
return req.context.ack()
else:
diff --git a/docs/static/api-docs/slack_bolt/middleware/ignoring_self_events/index.html b/docs/static/api-docs/slack_bolt/middleware/ignoring_self_events/index.html
index 68eef6bfd..853d1225c 100644
--- a/docs/static/api-docs/slack_bolt/middleware/ignoring_self_events/index.html
+++ b/docs/static/api-docs/slack_bolt/middleware/ignoring_self_events/index.html
@@ -48,7 +48,7 @@
class IgnoringSelfEvents
-(base_logger: Optional[logging.Logger] = None)
+(base_logger: Optional[logging.Logger] = None, ignoring_self_assistant_message_events_enabled: bool = True)
-
A middleware can process request data before other middleware and listener functions.
@@ -58,9 +58,14 @@
Expand source code
class IgnoringSelfEvents(Middleware):
- def __init__(self, base_logger: Optional[logging.Logger] = None):
+ def __init__(
+ self,
+ base_logger: Optional[logging.Logger] = None,
+ ignoring_self_assistant_message_events_enabled: bool = True,
+ ):
"""Ignores the events generated by this bot user itself."""
self.logger = get_bolt_logger(IgnoringSelfEvents, base_logger=base_logger)
+ self.ignoring_self_assistant_message_events_enabled = ignoring_self_assistant_message_events_enabled
def process(
self,
@@ -73,6 +78,11 @@
# message events can have $.event.bot_id while it does not have its user_id
bot_id = req.body.get("event", {}).get("bot_id")
if self._is_self_event(auth_result, req.context.user_id, bot_id, req.body): # type: ignore[arg-type]
+ if self.ignoring_self_assistant_message_events_enabled is False:
+ if is_bot_message_event_in_assistant_thread(req.body):
+ # Assistant#bot_message handler acknowledges this pattern
+ return next()
+
self._debug_log(req.body)
return req.context.ack()
else:
diff --git a/docs/static/api-docs/slack_bolt/middleware/index.html b/docs/static/api-docs/slack_bolt/middleware/index.html
index 59cf0b3fc..2be166678 100644
--- a/docs/static/api-docs/slack_bolt/middleware/index.html
+++ b/docs/static/api-docs/slack_bolt/middleware/index.html
@@ -34,6 +34,10 @@ Module slack_bolt.middleware
+slack_bolt.middleware.assistant
+-
+
+
slack_bolt.middleware.async_builtins
-
@@ -118,7 +122,7 @@
next: Callable[[], BoltResponse],
) -> BoltResponse:
if req.context.function_bot_access_token is not None:
- req.context.client.token = req.context.function_bot_access_token # type: ignore[union-attr]
+ req.context.client.token = req.context.function_bot_access_token
return next()
@@ -218,7 +222,7 @@
Inherited members
class IgnoringSelfEvents
-(base_logger: Optional[logging.Logger] = None)
+(base_logger: Optional[logging.Logger] = None, ignoring_self_assistant_message_events_enabled: bool = True)
-
A middleware can process request data before other middleware and listener functions.
@@ -228,9 +232,14 @@
Inherited members
Expand source code
class IgnoringSelfEvents(Middleware):
- def __init__(self, base_logger: Optional[logging.Logger] = None):
+ def __init__(
+ self,
+ base_logger: Optional[logging.Logger] = None,
+ ignoring_self_assistant_message_events_enabled: bool = True,
+ ):
"""Ignores the events generated by this bot user itself."""
self.logger = get_bolt_logger(IgnoringSelfEvents, base_logger=base_logger)
+ self.ignoring_self_assistant_message_events_enabled = ignoring_self_assistant_message_events_enabled
def process(
self,
@@ -243,6 +252,11 @@ Inherited members
# message events can have $.event.bot_id while it does not have its user_id
bot_id = req.body.get("event", {}).get("bot_id")
if self._is_self_event(auth_result, req.context.user_id, bot_id, req.body): # type: ignore[arg-type]
+ if self.ignoring_self_assistant_message_events_enabled is False:
+ if is_bot_message_event_in_assistant_thread(req.body):
+ # Assistant#bot_message handler acknowledges this pattern
+ return next()
+
self._debug_log(req.body)
return req.context.ack()
else:
@@ -359,6 +373,7 @@ Inherited members
Subclasses
+- Assistant
- AttachingFunctionToken
- Authorization
- CustomMiddleware
@@ -513,7 +528,7 @@ Args
req.context["token"] = token
# As App#_init_context() generates a new WebClient for this request,
# it's safe to modify this instance.
- req.context.client.token = token # type: ignore[union-attr]
+ req.context.client.token = token
return next()
else:
# This situation can arise if:
@@ -695,6 +710,7 @@ Args
# only the internals of this method
next: Callable[[], BoltResponse],
) -> BoltResponse:
+
if _is_no_auth_required(req):
return next()
@@ -710,13 +726,13 @@ Args
try:
if not self.auth_test_result:
- self.auth_test_result = req.context.client.auth_test() # type: ignore[union-attr]
+ self.auth_test_result = req.context.client.auth_test()
if self.auth_test_result:
req.context.set_authorize_result(
_to_authorize_result(
auth_test_result=self.auth_test_result,
- token=req.context.client.token, # type: ignore[union-attr]
+ token=req.context.client.token,
request_user_id=req.context.user_id,
)
)
@@ -936,6 +952,7 @@ Inherited members
-
+slack_bolt.middleware.assistant
slack_bolt.middleware.async_builtins
slack_bolt.middleware.async_custom_middleware
slack_bolt.middleware.async_middleware
diff --git a/docs/static/api-docs/slack_bolt/middleware/middleware.html b/docs/static/api-docs/slack_bolt/middleware/middleware.html
index 687d23060..0d9d17f8b 100644
--- a/docs/static/api-docs/slack_bolt/middleware/middleware.html
+++ b/docs/static/api-docs/slack_bolt/middleware/middleware.html
@@ -91,6 +91,7 @@
Subclasses
+- Assistant
- AttachingFunctionToken
- Authorization
- CustomMiddleware
diff --git a/docs/static/api-docs/slack_bolt/middleware/ssl_check/async_ssl_check.html b/docs/static/api-docs/slack_bolt/middleware/ssl_check/async_ssl_check.html
index 0ce0a5188..5a8e90b4d 100644
--- a/docs/static/api-docs/slack_bolt/middleware/ssl_check/async_ssl_check.html
+++ b/docs/static/api-docs/slack_bolt/middleware/ssl_check/async_ssl_check.html
@@ -79,6 +79,17 @@ Ancestors
- Middleware
- AsyncMiddleware
+Class variables
+
+var logger : logging.Logger
+-
+
+
+var verification_token : Optional[str]
+-
+
+
+
Inherited members
SslCheck
:
@@ -111,6 +122,10 @@ Inherited members
diff --git a/docs/static/api-docs/slack_bolt/request/internals.html b/docs/static/api-docs/slack_bolt/request/internals.html
index 8bf932f87..d3e49c02f 100644
--- a/docs/static/api-docs/slack_bolt/request/internals.html
+++ b/docs/static/api-docs/slack_bolt/request/internals.html
@@ -123,6 +123,12 @@
-
+
+-
+
+
@@ -173,6 +179,7 @@
extract_function_inputs
extract_is_enterprise_install
extract_team_id
+extract_thread_ts
extract_user_id
parse_body
parse_query
diff --git a/docs/static/api-docs/slack_bolt/request/payload_utils.html b/docs/static/api-docs/slack_bolt/request/payload_utils.html
index 3013c8927..8eb40d22c 100644
--- a/docs/static/api-docs/slack_bolt/request/payload_utils.html
+++ b/docs/static/api-docs/slack_bolt/request/payload_utils.html
@@ -39,6 +39,24 @@
-
+
+def is_assistant_event(body: Dict[str, Any]) ‑> bool
+
+-
+
+
+
+def is_assistant_thread_context_changed_event(body: Dict[str, Any]) ‑> bool
+
+-
+
+
+
+def is_assistant_thread_started_event(body: Dict[str, Any]) ‑> bool
+
+-
+
+
def is_attachment_action(body: Dict[str, Any]) ‑> bool
@@ -57,6 +75,12 @@
-
+
+def is_bot_message_event_in_assistant_thread(body: Dict[str, Any]) ‑> bool
+
+-
+
+
def is_dialog_cancellation(body: Dict[str, Any]) ‑> bool
@@ -93,6 +117,12 @@
-
+
+def is_message_event_in_assistant_thread(body: Dict[str, Any]) ‑> bool
+
+-
+
+
def is_message_shortcut(body: Dict[str, Any]) ‑> bool
@@ -105,6 +135,12 @@
-
+
+def is_other_message_sub_event_in_assistant_thread(body: Dict[str, Any]) ‑> bool
+
+-
+
+
def is_shortcut(body: Dict[str, Any]) ‑> bool
@@ -117,6 +153,12 @@
-
+
+def is_user_message_event_in_assistant_thread(body: Dict[str, Any]) ‑> bool
+
+-
+
+
def is_view(body: Dict[str, Any]) ‑> bool
@@ -219,19 +261,26 @@
-
diff --git a/docs/static/api-docs/slack_bolt/workflows/step/async_step.html b/docs/static/api-docs/slack_bolt/workflows/step/async_step.html
index 0969b2461..b957cabad 100644
--- a/docs/static/api-docs/slack_bolt/workflows/step/async_step.html
+++ b/docs/static/api-docs/slack_bolt/workflows/step/async_step.html
@@ -583,7 +583,7 @@ Class variables
Static methods
-def to_listener_matchers(app_name: str, matchers: Optional[List[Union[Callable[..., Awaitable[bool]], AsyncListenerMatcher]]]) ‑> List[AsyncListenerMatcher]
+def to_listener_matchers(app_name: str, matchers: Optional[List[Union[AsyncListenerMatcher, Callable[..., Awaitable[bool]]]]]) ‑> List[AsyncListenerMatcher]
-
diff --git a/docs/static/api-docs/slack_bolt/workflows/step/async_step_middleware.html b/docs/static/api-docs/slack_bolt/workflows/step/async_step_middleware.html
index 2b324a7b6..43034c84f 100644
--- a/docs/static/api-docs/slack_bolt/workflows/step/async_step_middleware.html
+++ b/docs/static/api-docs/slack_bolt/workflows/step/async_step_middleware.html
@@ -37,7 +37,7 @@
class AsyncWorkflowStepMiddleware
-(step: AsyncWorkflowStep, listener_runner: AsyncioListenerRunner)
+(step: AsyncWorkflowStep)
-
Base middleware for step from app specific ones
@@ -48,9 +48,8 @@
class AsyncWorkflowStepMiddleware(AsyncMiddleware):
"""Base middleware for step from app specific ones"""
- def __init__(self, step: AsyncWorkflowStep, listener_runner: AsyncioListenerRunner):
+ def __init__(self, step: AsyncWorkflowStep):
self.step = step
- self.listener_runner = listener_runner
async def async_process(
self,
@@ -75,8 +74,8 @@
return await next()
+ @staticmethod
async def _run(
- self,
listener: AsyncListener,
req: AsyncBoltRequest,
resp: BoltResponse,
@@ -85,7 +84,7 @@
if next_was_not_called:
return None
- return await self.listener_runner.run(
+ return await req.context.listener_runner.run(
request=req,
response=resp,
listener_name=get_name_for_callable(listener.ack_function),
diff --git a/docs/static/api-docs/slack_bolt/workflows/step/index.html b/docs/static/api-docs/slack_bolt/workflows/step/index.html
index b184a9a2e..17362d7b0 100644
--- a/docs/static/api-docs/slack_bolt/workflows/step/index.html
+++ b/docs/static/api-docs/slack_bolt/workflows/step/index.html
@@ -593,7 +593,7 @@ Static methods
class WorkflowStepMiddleware
-(step: WorkflowStep, listener_runner: ThreadListenerRunner)
+(step: WorkflowStep)
-
Base middleware for step from app specific ones
@@ -604,9 +604,8 @@ Static methods
class WorkflowStepMiddleware(Middleware):
"""Base middleware for step from app specific ones"""
- def __init__(self, step: WorkflowStep, listener_runner: ThreadListenerRunner):
+ def __init__(self, step: WorkflowStep):
self.step = step
- self.listener_runner = listener_runner
def process(
self,
@@ -634,8 +633,8 @@ Static methods
return next()
+ @staticmethod
def _run(
- self,
listener: Listener,
req: BoltRequest,
resp: BoltResponse,
@@ -644,7 +643,7 @@ Static methods
if next_was_not_called:
return None
- return self.listener_runner.run(
+ return req.context.listener_runner.run(
request=req,
response=resp,
listener_name=get_name_for_callable(listener.ack_function),
diff --git a/docs/static/api-docs/slack_bolt/workflows/step/step.html b/docs/static/api-docs/slack_bolt/workflows/step/step.html
index 415fb4612..4c74b76f8 100644
--- a/docs/static/api-docs/slack_bolt/workflows/step/step.html
+++ b/docs/static/api-docs/slack_bolt/workflows/step/step.html
@@ -612,7 +612,7 @@ Class variables
Static methods
-def to_listener_matchers(app_name: str, matchers: Optional[List[Union[Callable[..., bool], ListenerMatcher]]], base_logger: Optional[logging.Logger] = None) ‑> List[ListenerMatcher]
+def to_listener_matchers(app_name: str, matchers: Optional[List[Union[ListenerMatcher, Callable[..., bool]]]], base_logger: Optional[logging.Logger] = None) ‑> List[ListenerMatcher]
-
diff --git a/docs/static/api-docs/slack_bolt/workflows/step/step_middleware.html b/docs/static/api-docs/slack_bolt/workflows/step/step_middleware.html
index b8f52cb45..60b71fb99 100644
--- a/docs/static/api-docs/slack_bolt/workflows/step/step_middleware.html
+++ b/docs/static/api-docs/slack_bolt/workflows/step/step_middleware.html
@@ -37,7 +37,7 @@
class WorkflowStepMiddleware
-(step: WorkflowStep, listener_runner: ThreadListenerRunner)
+(step: WorkflowStep)
-
Base middleware for step from app specific ones
@@ -48,9 +48,8 @@
class WorkflowStepMiddleware(Middleware):
"""Base middleware for step from app specific ones"""
- def __init__(self, step: WorkflowStep, listener_runner: ThreadListenerRunner):
+ def __init__(self, step: WorkflowStep):
self.step = step
- self.listener_runner = listener_runner
def process(
self,
@@ -78,8 +77,8 @@
return next()
+ @staticmethod
def _run(
- self,
listener: Listener,
req: BoltRequest,
resp: BoltResponse,
@@ -88,7 +87,7 @@
if next_was_not_called:
return None
- return self.listener_runner.run(
+ return req.context.listener_runner.run(
request=req,
response=resp,
listener_name=get_name_for_callable(listener.ack_function),
diff --git a/slack_bolt/version.py b/slack_bolt/version.py
index bf4428776..20e481a80 100644
--- a/slack_bolt/version.py
+++ b/slack_bolt/version.py
@@ -1,3 +1,3 @@
"""Check the latest version at https://pypi.org/project/slack-bolt/"""
-__version__ = "1.20.1"
+__version__ = "1.21.0"