diff --git a/docs/reference/async_app.html b/docs/reference/async_app.html index 6a45d2ada..670ba58d0 100644 --- a/docs/reference/async_app.html +++ b/docs/reference/async_app.html @@ -5415,7 +5415,7 @@

Class variables

class AsyncSetSuggestedPrompts -(client: slack_sdk.web.async_client.AsyncWebClient,
channel_id: str,
thread_ts: str)
+(client: slack_sdk.web.async_client.AsyncWebClient,
channel_id: str,
thread_ts: str | None = None)
@@ -5425,13 +5425,13 @@

Class variables

class AsyncSetSuggestedPrompts:
     client: AsyncWebClient
     channel_id: str
-    thread_ts: str
+    thread_ts: Optional[str]
 
     def __init__(
         self,
         client: AsyncWebClient,
         channel_id: str,
-        thread_ts: str,
+        thread_ts: Optional[str] = None,
     ):
         self.client = client
         self.channel_id = channel_id
@@ -5441,6 +5441,7 @@ 

Class variables

self, prompts: Sequence[Union[str, Dict[str, str]]], title: Optional[str] = None, + thread_ts: Optional[str] = None, ) -> AsyncSlackResponse: prompts_arg: List[Dict[str, str]] = [] for prompt in prompts: @@ -5451,7 +5452,7 @@

Class variables

return await self.client.assistant_threads_setSuggestedPrompts( channel_id=self.channel_id, - thread_ts=self.thread_ts, + thread_ts=thread_ts if thread_ts is not None else self.thread_ts, prompts=prompts_arg, title=title, )
@@ -5467,7 +5468,7 @@

Class variables

The type of the None singleton.

-
var thread_ts : str
+
var thread_ts : str | None

The type of the None singleton.

diff --git a/docs/reference/authorization/authorize_result.html b/docs/reference/authorization/authorize_result.html index 6eac3724d..d53c5cd5c 100644 --- a/docs/reference/authorization/authorize_result.html +++ b/docs/reference/authorization/authorize_result.html @@ -48,7 +48,7 @@

Classes

class AuthorizeResult -(*,
enterprise_id: str | None,
team_id: str | None,
team: str | None = None,
url: str | None = None,
bot_user_id: str | None = None,
bot_id: str | None = None,
bot_token: str | None = None,
bot_scopes: str | Sequence[str] | None = None,
user_id: str | None = None,
user: str | None = None,
user_token: str | None = None,
user_scopes: str | Sequence[str] | None = None)
+(*,
enterprise_id: str | None,
team_id: str | None,
team: str | None = None,
url: str | None = None,
bot_user_id: str | None = None,
bot_id: str | None = None,
bot_token: str | None = None,
bot_scopes: Sequence[str] | str | None = None,
user_id: str | None = None,
user: str | None = None,
user_token: str | None = None,
user_scopes: Sequence[str] | str | None = None)
@@ -246,7 +246,7 @@

Class variables

Static methods

-def from_auth_test_response(*,
bot_token: str | None = None,
user_token: str | None = None,
bot_scopes: str | Sequence[str] | None = None,
user_scopes: str | Sequence[str] | None = None,
auth_test_response: slack_sdk.web.slack_response.SlackResponse | ForwardRef('AsyncSlackResponse'),
user_auth_test_response: slack_sdk.web.slack_response.SlackResponse | ForwardRef('AsyncSlackResponse') | None = None)
+def from_auth_test_response(*,
bot_token: str | None = None,
user_token: str | None = None,
bot_scopes: Sequence[str] | str | None = None,
user_scopes: Sequence[str] | str | None = None,
auth_test_response: slack_sdk.web.slack_response.SlackResponse | AsyncSlackResponse,
user_auth_test_response: slack_sdk.web.slack_response.SlackResponse | AsyncSlackResponse | None = None)
diff --git a/docs/reference/authorization/index.html b/docs/reference/authorization/index.html index 19de311df..2fdd1f916 100644 --- a/docs/reference/authorization/index.html +++ b/docs/reference/authorization/index.html @@ -75,7 +75,7 @@

Classes

class AuthorizeResult -(*,
enterprise_id: str | None,
team_id: str | None,
team: str | None = None,
url: str | None = None,
bot_user_id: str | None = None,
bot_id: str | None = None,
bot_token: str | None = None,
bot_scopes: str | Sequence[str] | None = None,
user_id: str | None = None,
user: str | None = None,
user_token: str | None = None,
user_scopes: str | Sequence[str] | None = None)
+(*,
enterprise_id: str | None,
team_id: str | None,
team: str | None = None,
url: str | None = None,
bot_user_id: str | None = None,
bot_id: str | None = None,
bot_token: str | None = None,
bot_scopes: Sequence[str] | str | None = None,
user_id: str | None = None,
user: str | None = None,
user_token: str | None = None,
user_scopes: Sequence[str] | str | None = None)
@@ -273,7 +273,7 @@

Class variables

Static methods

-def from_auth_test_response(*,
bot_token: str | None = None,
user_token: str | None = None,
bot_scopes: str | Sequence[str] | None = None,
user_scopes: str | Sequence[str] | None = None,
auth_test_response: slack_sdk.web.slack_response.SlackResponse | ForwardRef('AsyncSlackResponse'),
user_auth_test_response: slack_sdk.web.slack_response.SlackResponse | ForwardRef('AsyncSlackResponse') | None = None)
+def from_auth_test_response(*,
bot_token: str | None = None,
user_token: str | None = None,
bot_scopes: Sequence[str] | str | None = None,
user_scopes: Sequence[str] | str | None = None,
auth_test_response: slack_sdk.web.slack_response.SlackResponse | AsyncSlackResponse,
user_auth_test_response: slack_sdk.web.slack_response.SlackResponse | AsyncSlackResponse | None = None)
diff --git a/docs/reference/context/assistant/assistant_utilities.html b/docs/reference/context/assistant/assistant_utilities.html index 40db52284..2200c4f10 100644 --- a/docs/reference/context/assistant/assistant_utilities.html +++ b/docs/reference/context/assistant/assistant_utilities.html @@ -86,28 +86,10 @@

Classes

# When moving this code to Bolt internals, no need to raise an exception for this pattern raise ValueError(f"Cannot instantiate Assistant for this event pattern ({self.payload})") - def is_valid(self) -> bool: - return self.channel_id is not None and self.thread_ts is not None - - @property - def set_status(self) -> SetStatus: - warnings.warn( - "AssistantUtilities.set_status is deprecated. " - "Use the set_status argument directly in your listener function " - "or access it via context.set_status instead.", - DeprecationWarning, - stacklevel=2, - ) - return SetStatus(self.client, self.channel_id, self.thread_ts) - @property def set_title(self) -> SetTitle: return SetTitle(self.client, self.channel_id, self.thread_ts) - @property - def set_suggested_prompts(self) -> SetSuggestedPrompts: - return SetSuggestedPrompts(self.client, self.channel_id, self.thread_ts) - @property def say(self) -> Say: def build_metadata() -> Optional[dict]: @@ -204,37 +186,6 @@

Instance variables

-
prop set_statusSetStatus
-
-
- -Expand source code - -
@property
-def set_status(self) -> SetStatus:
-    warnings.warn(
-        "AssistantUtilities.set_status is deprecated. "
-        "Use the set_status argument directly in your listener function "
-        "or access it via context.set_status instead.",
-        DeprecationWarning,
-        stacklevel=2,
-    )
-    return SetStatus(self.client, self.channel_id, self.thread_ts)
-
-
-
-
prop set_suggested_promptsSetSuggestedPrompts
-
-
- -Expand source code - -
@property
-def set_suggested_prompts(self) -> SetSuggestedPrompts:
-    return SetSuggestedPrompts(self.client, self.channel_id, self.thread_ts)
-
-
-
prop set_titleSetTitle
@@ -248,22 +199,6 @@

Instance variables

-

Methods

-
-
-def is_valid(self) ‑> bool -
-
-
- -Expand source code - -
def is_valid(self) -> bool:
-    return self.channel_id is not None and self.thread_ts is not None
-
-
-
-
@@ -286,12 +221,9 @@

channel_id
  • client
  • get_thread_context
  • -
  • is_valid
  • payload
  • save_thread_context
  • say
  • -
  • set_status
  • -
  • set_suggested_prompts
  • set_title
  • thread_context_store
  • thread_ts
  • diff --git a/docs/reference/context/assistant/async_assistant_utilities.html b/docs/reference/context/assistant/async_assistant_utilities.html index fc77b80cb..70f4d0d23 100644 --- a/docs/reference/context/assistant/async_assistant_utilities.html +++ b/docs/reference/context/assistant/async_assistant_utilities.html @@ -86,28 +86,10 @@

    Classes

    # When moving this code to Bolt internals, no need to raise an exception for this pattern raise ValueError(f"Cannot instantiate Assistant for this event pattern ({self.payload})") - def is_valid(self) -> bool: - return self.channel_id is not None and self.thread_ts is not None - - @property - def set_status(self) -> AsyncSetStatus: - warnings.warn( - "AsyncAssistantUtilities.set_status is deprecated. " - "Use the set_status argument directly in your listener function " - "or access it via context.set_status instead.", - DeprecationWarning, - stacklevel=2, - ) - return AsyncSetStatus(self.client, self.channel_id, self.thread_ts) - @property def set_title(self) -> AsyncSetTitle: return AsyncSetTitle(self.client, self.channel_id, self.thread_ts) - @property - def set_suggested_prompts(self) -> AsyncSetSuggestedPrompts: - return AsyncSetSuggestedPrompts(self.client, self.channel_id, self.thread_ts) - @property def say(self) -> AsyncSay: return AsyncSay( @@ -198,37 +180,6 @@

    Instance variables

    -
    prop set_statusAsyncSetStatus
    -
    -
    - -Expand source code - -
    @property
    -def set_status(self) -> AsyncSetStatus:
    -    warnings.warn(
    -        "AsyncAssistantUtilities.set_status is deprecated. "
    -        "Use the set_status argument directly in your listener function "
    -        "or access it via context.set_status instead.",
    -        DeprecationWarning,
    -        stacklevel=2,
    -    )
    -    return AsyncSetStatus(self.client, self.channel_id, self.thread_ts)
    -
    -
    -
    -
    prop set_suggested_promptsAsyncSetSuggestedPrompts
    -
    -
    - -Expand source code - -
    @property
    -def set_suggested_prompts(self) -> AsyncSetSuggestedPrompts:
    -    return AsyncSetSuggestedPrompts(self.client, self.channel_id, self.thread_ts)
    -
    -
    -
    prop set_titleAsyncSetTitle
    @@ -242,22 +193,6 @@

    Instance variables

    -

    Methods

    -
    -
    -def is_valid(self) ‑> bool -
    -
    -
    - -Expand source code - -
    def is_valid(self) -> bool:
    -    return self.channel_id is not None and self.thread_ts is not None
    -
    -
    -
    -
    @@ -280,12 +215,9 @@

    channel_id
  • client
  • get_thread_context
  • -
  • is_valid
  • payload
  • save_thread_context
  • say
  • -
  • set_status
  • -
  • set_suggested_prompts
  • set_title
  • thread_context_store
  • thread_ts
  • diff --git a/docs/reference/context/assistant/thread_context_store/file/index.html b/docs/reference/context/assistant/thread_context_store/file/index.html index cbb4e4db6..4a5d944e1 100644 --- a/docs/reference/context/assistant/thread_context_store/file/index.html +++ b/docs/reference/context/assistant/thread_context_store/file/index.html @@ -48,7 +48,7 @@

    Classes

    class FileAssistantThreadContextStore -(base_dir: str = '/Users/eden.zimbelman/.bolt-app-assistant-thread-contexts') +(base_dir: str = '/Users/wbergamin/.bolt-app-assistant-thread-contexts')
    diff --git a/docs/reference/context/set_suggested_prompts/async_set_suggested_prompts.html b/docs/reference/context/set_suggested_prompts/async_set_suggested_prompts.html index 4feda52ba..1c7656456 100644 --- a/docs/reference/context/set_suggested_prompts/async_set_suggested_prompts.html +++ b/docs/reference/context/set_suggested_prompts/async_set_suggested_prompts.html @@ -48,7 +48,7 @@

    Classes

    class AsyncSetSuggestedPrompts -(client: slack_sdk.web.async_client.AsyncWebClient,
    channel_id: str,
    thread_ts: str)
    +(client: slack_sdk.web.async_client.AsyncWebClient,
    channel_id: str,
    thread_ts: str | None = None)
    @@ -58,13 +58,13 @@

    Classes

    class AsyncSetSuggestedPrompts:
         client: AsyncWebClient
         channel_id: str
    -    thread_ts: str
    +    thread_ts: Optional[str]
     
         def __init__(
             self,
             client: AsyncWebClient,
             channel_id: str,
    -        thread_ts: str,
    +        thread_ts: Optional[str] = None,
         ):
             self.client = client
             self.channel_id = channel_id
    @@ -74,6 +74,7 @@ 

    Classes

    self, prompts: Sequence[Union[str, Dict[str, str]]], title: Optional[str] = None, + thread_ts: Optional[str] = None, ) -> AsyncSlackResponse: prompts_arg: List[Dict[str, str]] = [] for prompt in prompts: @@ -84,7 +85,7 @@

    Classes

    return await self.client.assistant_threads_setSuggestedPrompts( channel_id=self.channel_id, - thread_ts=self.thread_ts, + thread_ts=thread_ts if thread_ts is not None else self.thread_ts, prompts=prompts_arg, title=title, )
    @@ -100,7 +101,7 @@

    Class variables

    The type of the None singleton.

    -
    var thread_ts : str
    +
    var thread_ts : str | None

    The type of the None singleton.

    diff --git a/docs/reference/context/set_suggested_prompts/index.html b/docs/reference/context/set_suggested_prompts/index.html index 12d864dde..cf606ae2f 100644 --- a/docs/reference/context/set_suggested_prompts/index.html +++ b/docs/reference/context/set_suggested_prompts/index.html @@ -59,7 +59,7 @@

    Classes

    class SetSuggestedPrompts -(client: slack_sdk.web.client.WebClient, channel_id: str, thread_ts: str) +(client: slack_sdk.web.client.WebClient,
    channel_id: str,
    thread_ts: str | None = None)
    @@ -69,13 +69,13 @@

    Classes

    class SetSuggestedPrompts:
         client: WebClient
         channel_id: str
    -    thread_ts: str
    +    thread_ts: Optional[str]
     
         def __init__(
             self,
             client: WebClient,
             channel_id: str,
    -        thread_ts: str,
    +        thread_ts: Optional[str] = None,
         ):
             self.client = client
             self.channel_id = channel_id
    @@ -85,6 +85,7 @@ 

    Classes

    self, prompts: Sequence[Union[str, Dict[str, str]]], title: Optional[str] = None, + thread_ts: Optional[str] = None, ) -> SlackResponse: prompts_arg: List[Dict[str, str]] = [] for prompt in prompts: @@ -95,7 +96,7 @@

    Classes

    return self.client.assistant_threads_setSuggestedPrompts( channel_id=self.channel_id, - thread_ts=self.thread_ts, + thread_ts=thread_ts if thread_ts is not None else self.thread_ts, prompts=prompts_arg, title=title, )
    @@ -111,7 +112,7 @@

    Class variables

    The type of the None singleton.

    -
    var thread_ts : str
    +
    var thread_ts : str | None

    The type of the None singleton.

    diff --git a/docs/reference/context/set_suggested_prompts/set_suggested_prompts.html b/docs/reference/context/set_suggested_prompts/set_suggested_prompts.html index 6c0385e57..f034fc677 100644 --- a/docs/reference/context/set_suggested_prompts/set_suggested_prompts.html +++ b/docs/reference/context/set_suggested_prompts/set_suggested_prompts.html @@ -48,7 +48,7 @@

    Classes

    class SetSuggestedPrompts -(client: slack_sdk.web.client.WebClient, channel_id: str, thread_ts: str) +(client: slack_sdk.web.client.WebClient,
    channel_id: str,
    thread_ts: str | None = None)
    @@ -58,13 +58,13 @@

    Classes

    class SetSuggestedPrompts:
         client: WebClient
         channel_id: str
    -    thread_ts: str
    +    thread_ts: Optional[str]
     
         def __init__(
             self,
             client: WebClient,
             channel_id: str,
    -        thread_ts: str,
    +        thread_ts: Optional[str] = None,
         ):
             self.client = client
             self.channel_id = channel_id
    @@ -74,6 +74,7 @@ 

    Classes

    self, prompts: Sequence[Union[str, Dict[str, str]]], title: Optional[str] = None, + thread_ts: Optional[str] = None, ) -> SlackResponse: prompts_arg: List[Dict[str, str]] = [] for prompt in prompts: @@ -84,7 +85,7 @@

    Classes

    return self.client.assistant_threads_setSuggestedPrompts( channel_id=self.channel_id, - thread_ts=self.thread_ts, + thread_ts=thread_ts if thread_ts is not None else self.thread_ts, prompts=prompts_arg, title=title, )
    @@ -100,7 +101,7 @@

    Class variables

    The type of the None singleton.

    -
    var thread_ts : str
    +
    var thread_ts : str | None

    The type of the None singleton.

    diff --git a/docs/reference/error/index.html b/docs/reference/error/index.html index f57d690e9..9a9998e63 100644 --- a/docs/reference/error/index.html +++ b/docs/reference/error/index.html @@ -72,7 +72,7 @@

    Subclasses

    class BoltUnhandledRequestError -(*,
    request: ForwardRef('BoltRequest') | ForwardRef('AsyncBoltRequest'),
    current_response: ForwardRef('BoltResponse') | None,
    last_global_middleware_name: str | None = None)
    +(*,
    request: BoltRequest | AsyncBoltRequest,
    current_response: BoltResponse | None,
    last_global_middleware_name: str | None = None)
    diff --git a/docs/reference/index.html b/docs/reference/index.html index 70d84875a..ac1666851 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -5337,7 +5337,7 @@

    Returns

    class FileAssistantThreadContextStore -(base_dir: str = '/Users/eden.zimbelman/.bolt-app-assistant-thread-contexts') +(base_dir: str = '/Users/wbergamin/.bolt-app-assistant-thread-contexts')
    @@ -6039,7 +6039,7 @@

    Class variables

    class SetSuggestedPrompts -(client: slack_sdk.web.client.WebClient, channel_id: str, thread_ts: str) +(client: slack_sdk.web.client.WebClient,
    channel_id: str,
    thread_ts: str | None = None)
    @@ -6049,13 +6049,13 @@

    Class variables

    class SetSuggestedPrompts:
         client: WebClient
         channel_id: str
    -    thread_ts: str
    +    thread_ts: Optional[str]
     
         def __init__(
             self,
             client: WebClient,
             channel_id: str,
    -        thread_ts: str,
    +        thread_ts: Optional[str] = None,
         ):
             self.client = client
             self.channel_id = channel_id
    @@ -6065,6 +6065,7 @@ 

    Class variables

    self, prompts: Sequence[Union[str, Dict[str, str]]], title: Optional[str] = None, + thread_ts: Optional[str] = None, ) -> SlackResponse: prompts_arg: List[Dict[str, str]] = [] for prompt in prompts: @@ -6075,7 +6076,7 @@

    Class variables

    return self.client.assistant_threads_setSuggestedPrompts( channel_id=self.channel_id, - thread_ts=self.thread_ts, + thread_ts=thread_ts if thread_ts is not None else self.thread_ts, prompts=prompts_arg, title=title, )
    @@ -6091,7 +6092,7 @@

    Class variables

    The type of the None singleton.

    -
    var thread_ts : str
    +
    var thread_ts : str | None

    The type of the None singleton.

    diff --git a/docs/reference/logger/messages.html b/docs/reference/logger/messages.html index 1072e6479..e69b45fc9 100644 --- a/docs/reference/logger/messages.html +++ b/docs/reference/logger/messages.html @@ -409,7 +409,7 @@

    Functions

    -def warning_unhandled_by_global_middleware(name: str,
    req: BoltRequest | ForwardRef('AsyncBoltRequest')) ‑> str
    +def warning_unhandled_by_global_middleware(name: str,
    req: BoltRequest | AsyncBoltRequest) ‑> str
    @@ -427,7 +427,7 @@

    Functions

    -def warning_unhandled_request(req: BoltRequest | ForwardRef('AsyncBoltRequest')) ‑> str +def warning_unhandled_request(req: BoltRequest | AsyncBoltRequest) ‑> str
    diff --git a/docs/reference/middleware/async_builtins.html b/docs/reference/middleware/async_builtins.html index 1ddea9222..8f7b1ba4f 100644 --- a/docs/reference/middleware/async_builtins.html +++ b/docs/reference/middleware/async_builtins.html @@ -70,34 +70,50 @@

    Classes

    next: Callable[[], Awaitable[BoltResponse]], ) -> Optional[BoltResponse]: event = to_event(req.body) - if event is not None: - if is_assistant_event(req.body): - assistant = AsyncAssistantUtilities( - payload=event, - context=req.context, - thread_context_store=self.thread_context_store, - ) - req.context["say"] = assistant.say - req.context["set_title"] = assistant.set_title - req.context["set_suggested_prompts"] = assistant.set_suggested_prompts - req.context["get_thread_context"] = assistant.get_thread_context - req.context["save_thread_context"] = assistant.save_thread_context + if event is None: + return await next() + if req.context.channel_id is None: + return await next() + + if is_assistant_event(req.body): + # TODO: eventually we might remove this assistant specific logic + assistant = AsyncAssistantUtilities( + payload=event, + context=req.context, + thread_context_store=self.thread_context_store, + ) + req.context["say"] = assistant.say + req.context["set_title"] = assistant.set_title + req.context["get_thread_context"] = assistant.get_thread_context + req.context["save_thread_context"] = assistant.save_thread_context + + if ( + is_im_message_event(req.body) + or is_assistant_thread_started_event(req.body) + or is_assistant_thread_context_changed_event(req.body) + or is_app_home_opened_event(req.body, tab="messages") + ): + req.context["set_suggested_prompts"] = AsyncSetSuggestedPrompts( + client=req.context.client, + channel_id=req.context.channel_id, + thread_ts=req.context.thread_ts, + ) - # TODO: in the future we might want to introduce a "proper" extract_ts utility - thread_ts = req.context.thread_ts or event.get("ts") - if req.context.channel_id and thread_ts: - req.context["set_status"] = AsyncSetStatus( - client=req.context.client, - channel_id=req.context.channel_id, - thread_ts=thread_ts, - ) - req.context["say_stream"] = AsyncSayStream( - client=req.context.client, - channel=req.context.channel_id, - recipient_team_id=req.context.team_id or req.context.enterprise_id, - recipient_user_id=req.context.user_id, - thread_ts=thread_ts, - ) + # TODO: in the future we might want to introduce a "proper" extract_ts utility + thread_ts_or_ts = req.context.thread_ts or event.get("ts") + if thread_ts_or_ts: + req.context["set_status"] = AsyncSetStatus( + client=req.context.client, + channel_id=req.context.channel_id, + thread_ts=thread_ts_or_ts, + ) + req.context["say_stream"] = AsyncSayStream( + client=req.context.client, + channel=req.context.channel_id, + recipient_team_id=req.context.team_id or req.context.enterprise_id, + recipient_user_id=req.context.user_id, + thread_ts=thread_ts_or_ts, + ) return await next()

    A middleware can process request data before other middleware and listener functions.

    diff --git a/docs/reference/middleware/attaching_conversation_kwargs/async_attaching_conversation_kwargs.html b/docs/reference/middleware/attaching_conversation_kwargs/async_attaching_conversation_kwargs.html index a0f5bdf85..e2bbe7045 100644 --- a/docs/reference/middleware/attaching_conversation_kwargs/async_attaching_conversation_kwargs.html +++ b/docs/reference/middleware/attaching_conversation_kwargs/async_attaching_conversation_kwargs.html @@ -70,34 +70,50 @@

    Classes

    next: Callable[[], Awaitable[BoltResponse]], ) -> Optional[BoltResponse]: event = to_event(req.body) - if event is not None: - if is_assistant_event(req.body): - assistant = AsyncAssistantUtilities( - payload=event, - context=req.context, - thread_context_store=self.thread_context_store, - ) - req.context["say"] = assistant.say - req.context["set_title"] = assistant.set_title - req.context["set_suggested_prompts"] = assistant.set_suggested_prompts - req.context["get_thread_context"] = assistant.get_thread_context - req.context["save_thread_context"] = assistant.save_thread_context + if event is None: + return await next() + if req.context.channel_id is None: + return await next() - # TODO: in the future we might want to introduce a "proper" extract_ts utility - thread_ts = req.context.thread_ts or event.get("ts") - if req.context.channel_id and thread_ts: - req.context["set_status"] = AsyncSetStatus( - client=req.context.client, - channel_id=req.context.channel_id, - thread_ts=thread_ts, - ) - req.context["say_stream"] = AsyncSayStream( - client=req.context.client, - channel=req.context.channel_id, - recipient_team_id=req.context.team_id or req.context.enterprise_id, - recipient_user_id=req.context.user_id, - thread_ts=thread_ts, - ) + if is_assistant_event(req.body): + # TODO: eventually we might remove this assistant specific logic + assistant = AsyncAssistantUtilities( + payload=event, + context=req.context, + thread_context_store=self.thread_context_store, + ) + req.context["say"] = assistant.say + req.context["set_title"] = assistant.set_title + req.context["get_thread_context"] = assistant.get_thread_context + req.context["save_thread_context"] = assistant.save_thread_context + + if ( + is_im_message_event(req.body) + or is_assistant_thread_started_event(req.body) + or is_assistant_thread_context_changed_event(req.body) + or is_app_home_opened_event(req.body, tab="messages") + ): + req.context["set_suggested_prompts"] = AsyncSetSuggestedPrompts( + client=req.context.client, + channel_id=req.context.channel_id, + thread_ts=req.context.thread_ts, + ) + + # TODO: in the future we might want to introduce a "proper" extract_ts utility + thread_ts_or_ts = req.context.thread_ts or event.get("ts") + if thread_ts_or_ts: + req.context["set_status"] = AsyncSetStatus( + client=req.context.client, + channel_id=req.context.channel_id, + thread_ts=thread_ts_or_ts, + ) + req.context["say_stream"] = AsyncSayStream( + client=req.context.client, + channel=req.context.channel_id, + recipient_team_id=req.context.team_id or req.context.enterprise_id, + recipient_user_id=req.context.user_id, + thread_ts=thread_ts_or_ts, + ) return await next()

    A middleware can process request data before other middleware and listener functions.

    diff --git a/docs/reference/middleware/attaching_conversation_kwargs/attaching_conversation_kwargs.html b/docs/reference/middleware/attaching_conversation_kwargs/attaching_conversation_kwargs.html index 8a1911323..e9d558fec 100644 --- a/docs/reference/middleware/attaching_conversation_kwargs/attaching_conversation_kwargs.html +++ b/docs/reference/middleware/attaching_conversation_kwargs/attaching_conversation_kwargs.html @@ -64,34 +64,50 @@

    Classes

    def process(self, *, req: BoltRequest, resp: BoltResponse, next: Callable[[], BoltResponse]) -> Optional[BoltResponse]: event = to_event(req.body) - if event is not None: - if is_assistant_event(req.body): - assistant = AssistantUtilities( - payload=event, - context=req.context, - thread_context_store=self.thread_context_store, - ) - req.context["say"] = assistant.say - req.context["set_title"] = assistant.set_title - req.context["set_suggested_prompts"] = assistant.set_suggested_prompts - req.context["get_thread_context"] = assistant.get_thread_context - req.context["save_thread_context"] = assistant.save_thread_context + if event is None: + return next() + if req.context.channel_id is None: + return next() - # TODO: in the future we might want to introduce a "proper" extract_ts utility - thread_ts = req.context.thread_ts or event.get("ts") - if req.context.channel_id and thread_ts: - req.context["set_status"] = SetStatus( - client=req.context.client, - channel_id=req.context.channel_id, - thread_ts=thread_ts, - ) - req.context["say_stream"] = SayStream( - client=req.context.client, - channel=req.context.channel_id, - recipient_team_id=req.context.team_id or req.context.enterprise_id, - recipient_user_id=req.context.user_id, - thread_ts=thread_ts, - ) + if is_assistant_event(req.body): + # TODO: eventually we might remove this assistant specific logic + assistant = AssistantUtilities( + payload=event, + context=req.context, + thread_context_store=self.thread_context_store, + ) + req.context["say"] = assistant.say + req.context["set_title"] = assistant.set_title + req.context["get_thread_context"] = assistant.get_thread_context + req.context["save_thread_context"] = assistant.save_thread_context + + if ( + is_im_message_event(req.body) + or is_assistant_thread_started_event(req.body) + or is_assistant_thread_context_changed_event(req.body) + or is_app_home_opened_event(req.body, tab="messages") + ): + req.context["set_suggested_prompts"] = SetSuggestedPrompts( + client=req.context.client, + channel_id=req.context.channel_id, + thread_ts=req.context.thread_ts, + ) + + # TODO: in the future we might want to introduce a "proper" extract_ts utility + thread_ts_or_ts = req.context.thread_ts or event.get("ts") + if thread_ts_or_ts: + req.context["set_status"] = SetStatus( + client=req.context.client, + channel_id=req.context.channel_id, + thread_ts=thread_ts_or_ts, + ) + req.context["say_stream"] = SayStream( + client=req.context.client, + channel=req.context.channel_id, + recipient_team_id=req.context.team_id or req.context.enterprise_id, + recipient_user_id=req.context.user_id, + thread_ts=thread_ts_or_ts, + ) return next()

    A middleware can process request data before other middleware and listener functions.

    diff --git a/docs/reference/middleware/attaching_conversation_kwargs/index.html b/docs/reference/middleware/attaching_conversation_kwargs/index.html index 308a52712..38da4442e 100644 --- a/docs/reference/middleware/attaching_conversation_kwargs/index.html +++ b/docs/reference/middleware/attaching_conversation_kwargs/index.html @@ -75,34 +75,50 @@

    Classes

    def process(self, *, req: BoltRequest, resp: BoltResponse, next: Callable[[], BoltResponse]) -> Optional[BoltResponse]: event = to_event(req.body) - if event is not None: - if is_assistant_event(req.body): - assistant = AssistantUtilities( - payload=event, - context=req.context, - thread_context_store=self.thread_context_store, - ) - req.context["say"] = assistant.say - req.context["set_title"] = assistant.set_title - req.context["set_suggested_prompts"] = assistant.set_suggested_prompts - req.context["get_thread_context"] = assistant.get_thread_context - req.context["save_thread_context"] = assistant.save_thread_context + if event is None: + return next() + if req.context.channel_id is None: + return next() - # TODO: in the future we might want to introduce a "proper" extract_ts utility - thread_ts = req.context.thread_ts or event.get("ts") - if req.context.channel_id and thread_ts: - req.context["set_status"] = SetStatus( - client=req.context.client, - channel_id=req.context.channel_id, - thread_ts=thread_ts, - ) - req.context["say_stream"] = SayStream( - client=req.context.client, - channel=req.context.channel_id, - recipient_team_id=req.context.team_id or req.context.enterprise_id, - recipient_user_id=req.context.user_id, - thread_ts=thread_ts, - ) + if is_assistant_event(req.body): + # TODO: eventually we might remove this assistant specific logic + assistant = AssistantUtilities( + payload=event, + context=req.context, + thread_context_store=self.thread_context_store, + ) + req.context["say"] = assistant.say + req.context["set_title"] = assistant.set_title + req.context["get_thread_context"] = assistant.get_thread_context + req.context["save_thread_context"] = assistant.save_thread_context + + if ( + is_im_message_event(req.body) + or is_assistant_thread_started_event(req.body) + or is_assistant_thread_context_changed_event(req.body) + or is_app_home_opened_event(req.body, tab="messages") + ): + req.context["set_suggested_prompts"] = SetSuggestedPrompts( + client=req.context.client, + channel_id=req.context.channel_id, + thread_ts=req.context.thread_ts, + ) + + # TODO: in the future we might want to introduce a "proper" extract_ts utility + thread_ts_or_ts = req.context.thread_ts or event.get("ts") + if thread_ts_or_ts: + req.context["set_status"] = SetStatus( + client=req.context.client, + channel_id=req.context.channel_id, + thread_ts=thread_ts_or_ts, + ) + req.context["say_stream"] = SayStream( + client=req.context.client, + channel=req.context.channel_id, + recipient_team_id=req.context.team_id or req.context.enterprise_id, + recipient_user_id=req.context.user_id, + thread_ts=thread_ts_or_ts, + ) return next()

    A middleware can process request data before other middleware and listener functions.

    diff --git a/docs/reference/middleware/index.html b/docs/reference/middleware/index.html index 9f2053a5d..153342bc1 100644 --- a/docs/reference/middleware/index.html +++ b/docs/reference/middleware/index.html @@ -136,34 +136,50 @@

    Classes

    def process(self, *, req: BoltRequest, resp: BoltResponse, next: Callable[[], BoltResponse]) -> Optional[BoltResponse]: event = to_event(req.body) - if event is not None: - if is_assistant_event(req.body): - assistant = AssistantUtilities( - payload=event, - context=req.context, - thread_context_store=self.thread_context_store, - ) - req.context["say"] = assistant.say - req.context["set_title"] = assistant.set_title - req.context["set_suggested_prompts"] = assistant.set_suggested_prompts - req.context["get_thread_context"] = assistant.get_thread_context - req.context["save_thread_context"] = assistant.save_thread_context + if event is None: + return next() + if req.context.channel_id is None: + return next() - # TODO: in the future we might want to introduce a "proper" extract_ts utility - thread_ts = req.context.thread_ts or event.get("ts") - if req.context.channel_id and thread_ts: - req.context["set_status"] = SetStatus( - client=req.context.client, - channel_id=req.context.channel_id, - thread_ts=thread_ts, - ) - req.context["say_stream"] = SayStream( - client=req.context.client, - channel=req.context.channel_id, - recipient_team_id=req.context.team_id or req.context.enterprise_id, - recipient_user_id=req.context.user_id, - thread_ts=thread_ts, - ) + if is_assistant_event(req.body): + # TODO: eventually we might remove this assistant specific logic + assistant = AssistantUtilities( + payload=event, + context=req.context, + thread_context_store=self.thread_context_store, + ) + req.context["say"] = assistant.say + req.context["set_title"] = assistant.set_title + req.context["get_thread_context"] = assistant.get_thread_context + req.context["save_thread_context"] = assistant.save_thread_context + + if ( + is_im_message_event(req.body) + or is_assistant_thread_started_event(req.body) + or is_assistant_thread_context_changed_event(req.body) + or is_app_home_opened_event(req.body, tab="messages") + ): + req.context["set_suggested_prompts"] = SetSuggestedPrompts( + client=req.context.client, + channel_id=req.context.channel_id, + thread_ts=req.context.thread_ts, + ) + + # TODO: in the future we might want to introduce a "proper" extract_ts utility + thread_ts_or_ts = req.context.thread_ts or event.get("ts") + if thread_ts_or_ts: + req.context["set_status"] = SetStatus( + client=req.context.client, + channel_id=req.context.channel_id, + thread_ts=thread_ts_or_ts, + ) + req.context["say_stream"] = SayStream( + client=req.context.client, + channel=req.context.channel_id, + recipient_team_id=req.context.team_id or req.context.enterprise_id, + recipient_user_id=req.context.user_id, + thread_ts=thread_ts_or_ts, + ) return next()

    A middleware can process request data before other middleware and listener functions.

    diff --git a/docs/reference/oauth/async_oauth_settings.html b/docs/reference/oauth/async_oauth_settings.html index 5e6a543c4..3b8c04edb 100644 --- a/docs/reference/oauth/async_oauth_settings.html +++ b/docs/reference/oauth/async_oauth_settings.html @@ -48,7 +48,7 @@

    Classes

    class AsyncOAuthSettings -(*,
    client_id: str | None = None,
    client_secret: str | None = None,
    scopes: str | Sequence[str] | None = None,
    user_scopes: str | Sequence[str] | None = None,
    redirect_uri: str | None = None,
    install_path: str = '/slack/install',
    install_page_rendering_enabled: bool = True,
    redirect_uri_path: str = '/slack/oauth_redirect',
    callback_options: AsyncCallbackOptions | None = None,
    success_url: str | None = None,
    failure_url: str | None = None,
    authorization_url: str | None = None,
    installation_store: slack_sdk.oauth.installation_store.async_installation_store.AsyncInstallationStore | None = None,
    installation_store_bot_only: bool = False,
    token_rotation_expiration_minutes: int = 120,
    user_token_resolution: str = 'authed_user',
    state_validation_enabled: bool = True,
    state_store: slack_sdk.oauth.state_store.async_state_store.AsyncOAuthStateStore | None = None,
    state_cookie_name: str = 'slack-app-oauth-state',
    state_expiration_seconds: int = 600,
    logger: logging.Logger = <Logger slack_bolt.oauth.async_oauth_settings (WARNING)>)
    +(*,
    client_id: str | None = None,
    client_secret: str | None = None,
    scopes: Sequence[str] | str | None = None,
    user_scopes: Sequence[str] | str | None = None,
    redirect_uri: str | None = None,
    install_path: str = '/slack/install',
    install_page_rendering_enabled: bool = True,
    redirect_uri_path: str = '/slack/oauth_redirect',
    callback_options: AsyncCallbackOptions | None = None,
    success_url: str | None = None,
    failure_url: str | None = None,
    authorization_url: str | None = None,
    installation_store: slack_sdk.oauth.installation_store.async_installation_store.AsyncInstallationStore | None = None,
    installation_store_bot_only: bool = False,
    token_rotation_expiration_minutes: int = 120,
    user_token_resolution: str = 'authed_user',
    state_validation_enabled: bool = True,
    state_store: slack_sdk.oauth.state_store.async_state_store.AsyncOAuthStateStore | None = None,
    state_cookie_name: str = 'slack-app-oauth-state',
    state_expiration_seconds: int = 600,
    logger: logging.Logger = <Logger slack_bolt.oauth.async_oauth_settings (WARNING)>)
    diff --git a/docs/reference/oauth/oauth_settings.html b/docs/reference/oauth/oauth_settings.html index 1eb2ab7dd..cd8def497 100644 --- a/docs/reference/oauth/oauth_settings.html +++ b/docs/reference/oauth/oauth_settings.html @@ -48,7 +48,7 @@

    Classes

    class OAuthSettings -(*,
    client_id: str | None = None,
    client_secret: str | None = None,
    scopes: str | Sequence[str] | None = None,
    user_scopes: str | Sequence[str] | None = None,
    redirect_uri: str | None = None,
    install_path: str = '/slack/install',
    install_page_rendering_enabled: bool = True,
    redirect_uri_path: str = '/slack/oauth_redirect',
    callback_options: CallbackOptions | None = None,
    success_url: str | None = None,
    failure_url: str | None = None,
    authorization_url: str | None = None,
    installation_store: slack_sdk.oauth.installation_store.installation_store.InstallationStore | None = None,
    installation_store_bot_only: bool = False,
    token_rotation_expiration_minutes: int = 120,
    user_token_resolution: str = 'authed_user',
    state_validation_enabled: bool = True,
    state_store: slack_sdk.oauth.state_store.state_store.OAuthStateStore | None = None,
    state_cookie_name: str = 'slack-app-oauth-state',
    state_expiration_seconds: int = 600,
    logger: logging.Logger = <Logger slack_bolt.oauth.oauth_settings (WARNING)>)
    +(*,
    client_id: str | None = None,
    client_secret: str | None = None,
    scopes: Sequence[str] | str | None = None,
    user_scopes: Sequence[str] | str | None = None,
    redirect_uri: str | None = None,
    install_path: str = '/slack/install',
    install_page_rendering_enabled: bool = True,
    redirect_uri_path: str = '/slack/oauth_redirect',
    callback_options: CallbackOptions | None = None,
    success_url: str | None = None,
    failure_url: str | None = None,
    authorization_url: str | None = None,
    installation_store: slack_sdk.oauth.installation_store.installation_store.InstallationStore | None = None,
    installation_store_bot_only: bool = False,
    token_rotation_expiration_minutes: int = 120,
    user_token_resolution: str = 'authed_user',
    state_validation_enabled: bool = True,
    state_store: slack_sdk.oauth.state_store.state_store.OAuthStateStore | None = None,
    state_cookie_name: str = 'slack-app-oauth-state',
    state_expiration_seconds: int = 600,
    logger: logging.Logger = <Logger slack_bolt.oauth.oauth_settings (WARNING)>)
    diff --git a/docs/reference/request/payload_utils.html b/docs/reference/request/payload_utils.html index 4fe75fd81..b583c3a51 100644 --- a/docs/reference/request/payload_utils.html +++ b/docs/reference/request/payload_utils.html @@ -63,6 +63,39 @@

    Functions

    +
    +def is_any_im_message_event(body: Dict[str, Any]) ‑> bool +
    +
    +
    + +Expand source code + +
    def is_any_im_message_event(body: Dict[str, Any]) -> bool:
    +    if is_message_event(body):
    +        # Any message event with no subtype or any subtype (message_changed, message_deleted, etc.)
    +        return body["event"].get("channel_type") == "im"
    +    return False
    +
    +
    +
    +
    +def is_app_home_opened_event(body: Dict[str, Any], tab: str | None = None) ‑> bool +
    +
    +
    + +Expand source code + +
    def is_app_home_opened_event(body: Dict[str, Any], tab: Optional[str] = None) -> bool:
    +    if is_event(body) and body["event"]["type"] == "app_home_opened":
    +        if tab is not None:
    +            return body["event"].get("tab") == tab
    +        return True
    +    return False
    +
    +
    +
    def is_assistant_event(body: Dict[str, Any]) ‑> bool
    @@ -159,10 +192,9 @@

    Functions

    Expand source code
    def is_bot_message_event_in_assistant_thread(body: Dict[str, Any]) -> bool:
    -    if is_event(body):
    +    if is_any_im_message_event(body):
             return (
    -            is_message_event_in_assistant_thread(body)
    -            and body["event"].get("subtype") is None
    +            body["event"].get("subtype") is None
                 and body["event"].get("thread_ts") is not None
                 and body["event"].get("bot_id") is not None
             )
    @@ -248,17 +280,32 @@ 

    Functions

    -
    -def is_message_event_in_assistant_thread(body: Dict[str, Any]) ‑> bool +
    +def is_im_message_event(body: Dict[str, Any]) ‑> bool +
    +
    +
    + +Expand source code + +
    def is_im_message_event(body: Dict[str, Any]) -> bool:
    +    if is_any_im_message_event(body):
    +        return body["event"].get("subtype") in (None, "file_share")
    +    return False
    +
    +
    +
    +
    +def is_message_event(body: Dict[str, Any]) ‑> bool
    Expand source code -
    def is_message_event_in_assistant_thread(body: Dict[str, Any]) -> bool:
    +
    def is_message_event(body: Dict[str, Any]) -> bool:
         if is_event(body):
    -        return body["event"]["type"] == "message" and body["event"].get("channel_type") == "im"
    +        return body["event"]["type"] == "message"
         return False
    @@ -299,14 +346,10 @@

    Functions

    def is_other_message_sub_event_in_assistant_thread(body: Dict[str, Any]) -> bool:
         # message_changed, message_deleted etc.
    -    if is_event(body):
    -        return (
    -            is_message_event_in_assistant_thread(body)
    -            and not is_user_message_event_in_assistant_thread(body)
    -            and (
    -                _is_other_message_sub_event(body["event"].get("message"))
    -                or _is_other_message_sub_event(body["event"].get("previous_message"))
    -            )
    +    if is_any_im_message_event(body):
    +        return not is_user_message_event_in_assistant_thread(body) and (
    +            _is_other_message_sub_event(body["event"].get("message"))
    +            or _is_other_message_sub_event(body["event"].get("previous_message"))
             )
         return False
    @@ -347,13 +390,8 @@

    Functions

    Expand source code
    def is_user_message_event_in_assistant_thread(body: Dict[str, Any]) -> bool:
    -    if is_event(body):
    -        return (
    -            is_message_event_in_assistant_thread(body)
    -            and body["event"].get("subtype") in (None, "file_share")
    -            and body["event"].get("thread_ts") is not None
    -            and body["event"].get("bot_id") is None
    -        )
    +    if is_im_message_event(body):
    +        return body["event"].get("thread_ts") is not None and body["event"].get("bot_id") is None
         return False
    @@ -491,7 +529,7 @@

    Functions

    Expand source code
    def to_message(body: Dict[str, Any]) -> Optional[Dict[str, Any]]:
    -    if is_event(body) and body["event"]["type"] == "message":
    +    if is_message_event(body):
             return to_event(body)
         return None
    @@ -582,6 +620,8 @@

    Functions

  • Functions