Skip to content

Commit 3e7031b

Browse files
bring assistant logic to general bolt logic
1 parent af21620 commit 3e7031b

6 files changed

Lines changed: 108 additions & 185 deletions

File tree

‎slack_bolt/context/assistant/assistant_utilities.py‎

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import warnings
21
from typing import Optional
32

43
from slack_sdk.web import WebClient
@@ -8,12 +7,8 @@
87

98
from slack_bolt.context.context import BoltContext
109
from slack_bolt.context.say import Say
11-
from .internals import has_channel_id_and_thread_ts
1210
from ..get_thread_context.get_thread_context import GetThreadContext
1311
from ..save_thread_context import SaveThreadContext
14-
from ..set_status import SetStatus
15-
from ..set_suggested_prompts import SetSuggestedPrompts
16-
from ..set_title import SetTitle
1712

1813

1914
class AssistantUtilities:
@@ -34,48 +29,13 @@ def __init__(
3429
self.client = context.client
3530
self.thread_context_store = thread_context_store or DefaultAssistantThreadContextStore(context)
3631

37-
if has_channel_id_and_thread_ts(self.payload):
38-
# assistant_thread_started
39-
thread = self.payload["assistant_thread"]
40-
self.channel_id = thread["channel_id"]
41-
self.thread_ts = thread["thread_ts"]
42-
elif self.payload.get("channel") is not None and self.payload.get("thread_ts") is not None:
43-
# message event
44-
self.channel_id = self.payload["channel"]
45-
self.thread_ts = self.payload["thread_ts"]
32+
if context.channel_id is not None and context.thread_ts is not None:
33+
self.channel_id = context.channel_id
34+
self.thread_ts = context.thread_ts
4635
else:
4736
# When moving this code to Bolt internals, no need to raise an exception for this pattern
4837
raise ValueError(f"Cannot instantiate Assistant for this event pattern ({self.payload})")
4938

50-
def is_valid(self) -> bool:
51-
return self.channel_id is not None and self.thread_ts is not None
52-
53-
@property
54-
def set_status(self) -> SetStatus:
55-
warnings.warn(
56-
"AssistantUtilities.set_status is deprecated. "
57-
"Use the set_status argument directly in your listener function "
58-
"or access it via context.set_status instead.",
59-
DeprecationWarning,
60-
stacklevel=2,
61-
)
62-
return SetStatus(self.client, self.channel_id, self.thread_ts)
63-
64-
@property
65-
def set_title(self) -> SetTitle:
66-
return SetTitle(self.client, self.channel_id, self.thread_ts)
67-
68-
@property
69-
def set_suggested_prompts(self) -> SetSuggestedPrompts:
70-
warnings.warn(
71-
"AssistantUtilities.set_suggested_prompts is deprecated. "
72-
"Use the set_suggested_prompts argument directly in your listener function "
73-
"or access it via context.set_suggested_prompts instead.",
74-
DeprecationWarning,
75-
stacklevel=2,
76-
)
77-
return SetSuggestedPrompts(self.client, self.channel_id, self.thread_ts)
78-
7939
@property
8040
def say(self) -> Say:
8141
def build_metadata() -> Optional[dict]:

‎slack_bolt/context/assistant/async_assistant_utilities.py‎

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import warnings
21
from typing import Optional
32

43
from slack_sdk.web.async_client import AsyncWebClient
@@ -11,12 +10,8 @@
1110

1211
from slack_bolt.context.async_context import AsyncBoltContext
1312
from slack_bolt.context.say.async_say import AsyncSay
14-
from .internals import has_channel_id_and_thread_ts
1513
from ..get_thread_context.async_get_thread_context import AsyncGetThreadContext
1614
from ..save_thread_context.async_save_thread_context import AsyncSaveThreadContext
17-
from ..set_status.async_set_status import AsyncSetStatus
18-
from ..set_suggested_prompts.async_set_suggested_prompts import AsyncSetSuggestedPrompts
19-
from ..set_title.async_set_title import AsyncSetTitle
2015

2116

2217
class AsyncAssistantUtilities:
@@ -37,48 +32,13 @@ def __init__(
3732
self.client = context.client
3833
self.thread_context_store = thread_context_store or DefaultAsyncAssistantThreadContextStore(context)
3934

40-
if has_channel_id_and_thread_ts(self.payload):
41-
# assistant_thread_started
42-
thread = self.payload["assistant_thread"]
43-
self.channel_id = thread["channel_id"]
44-
self.thread_ts = thread["thread_ts"]
45-
elif self.payload.get("channel") is not None and self.payload.get("thread_ts") is not None:
46-
# message event
47-
self.channel_id = self.payload["channel"]
48-
self.thread_ts = self.payload["thread_ts"]
35+
if context.channel_id is not None and context.thread_ts is not None:
36+
self.channel_id = context.channel_id
37+
self.thread_ts = context.thread_ts
4938
else:
5039
# When moving this code to Bolt internals, no need to raise an exception for this pattern
5140
raise ValueError(f"Cannot instantiate Assistant for this event pattern ({self.payload})")
5241

53-
def is_valid(self) -> bool:
54-
return self.channel_id is not None and self.thread_ts is not None
55-
56-
@property
57-
def set_status(self) -> AsyncSetStatus:
58-
warnings.warn(
59-
"AsyncAssistantUtilities.set_status is deprecated. "
60-
"Use the set_status argument directly in your listener function "
61-
"or access it via context.set_status instead.",
62-
DeprecationWarning,
63-
stacklevel=2,
64-
)
65-
return AsyncSetStatus(self.client, self.channel_id, self.thread_ts)
66-
67-
@property
68-
def set_title(self) -> AsyncSetTitle:
69-
return AsyncSetTitle(self.client, self.channel_id, self.thread_ts)
70-
71-
@property
72-
def set_suggested_prompts(self) -> AsyncSetSuggestedPrompts:
73-
warnings.warn(
74-
"AsyncAssistantUtilities.set_suggested_prompts is deprecated. "
75-
"Use the set_suggested_prompts argument directly in your listener function "
76-
"or access it via context.set_suggested_prompts instead.",
77-
DeprecationWarning,
78-
stacklevel=2,
79-
)
80-
return AsyncSetSuggestedPrompts(self.client, self.channel_id, self.thread_ts)
81-
8242
@property
8343
def say(self) -> AsyncSay:
8444
return AsyncSay(

‎slack_bolt/context/assistant/internals.py‎

Lines changed: 0 additions & 9 deletions
This file was deleted.

‎slack_bolt/middleware/attaching_conversation_kwargs/async_attaching_conversation_kwargs.py‎

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from slack_bolt.context.say_stream.async_say_stream import AsyncSayStream
66
from slack_bolt.context.set_status.async_set_status import AsyncSetStatus
77
from slack_bolt.context.set_suggested_prompts.async_set_suggested_prompts import AsyncSetSuggestedPrompts
8+
from slack_bolt.context.set_title.async_set_title import AsyncSetTitle
89
from slack_bolt.middleware.async_middleware import AsyncMiddleware
910
from slack_bolt.request.async_request import AsyncBoltRequest
1011
from slack_bolt.request.payload_utils import (
@@ -32,43 +33,48 @@ async def async_process(
3233
next: Callable[[], Awaitable[BoltResponse]],
3334
) -> Optional[BoltResponse]:
3435
event = to_event(req.body)
35-
if event is not None:
36-
if is_assistant_event(req.body):
37-
assistant = AsyncAssistantUtilities(
38-
payload=event,
39-
context=req.context,
40-
thread_context_store=self.thread_context_store,
41-
)
42-
req.context["say"] = assistant.say
43-
req.context["set_title"] = assistant.set_title
44-
# req.context["set_suggested_prompts"] = assistant.set_suggested_prompts
45-
req.context["get_thread_context"] = assistant.get_thread_context
46-
req.context["save_thread_context"] = assistant.save_thread_context
36+
if event is None:
37+
return await next()
38+
if req.context.channel_id is None:
39+
return await next()
4740

48-
if req.context.channel_id:
49-
# TODO: in the future we might want to introduce a "proper" extract_ts utility
50-
thread_ts = req.context.thread_ts or event.get("ts")
51-
if (
52-
is_im_message_event(req.body)
53-
or is_assistant_thread_started_event(req.body)
54-
or is_assistant_thread_context_changed_event(req.body)
55-
):
56-
req.context["set_suggested_prompts"] = AsyncSetSuggestedPrompts(
57-
client=req.context.client,
58-
channel_id=req.context.channel_id,
59-
thread_ts=thread_ts,
60-
)
61-
if thread_ts:
62-
req.context["set_status"] = AsyncSetStatus(
63-
client=req.context.client,
64-
channel_id=req.context.channel_id,
65-
thread_ts=thread_ts,
66-
)
67-
req.context["say_stream"] = AsyncSayStream(
68-
client=req.context.client,
69-
channel=req.context.channel_id,
70-
recipient_team_id=req.context.team_id or req.context.enterprise_id,
71-
recipient_user_id=req.context.user_id,
72-
thread_ts=thread_ts,
73-
)
41+
if is_assistant_event(req.body):
42+
# TODO: eventually we might remove this assistant specific logic
43+
assistant = AsyncAssistantUtilities(
44+
payload=event,
45+
context=req.context,
46+
thread_context_store=self.thread_context_store,
47+
)
48+
req.context["say"] = assistant.say
49+
req.context["get_thread_context"] = assistant.get_thread_context
50+
req.context["save_thread_context"] = assistant.save_thread_context
51+
52+
if (
53+
is_im_message_event(req.body)
54+
or is_assistant_thread_started_event(req.body)
55+
or is_assistant_thread_context_changed_event(req.body)
56+
):
57+
req.context["set_suggested_prompts"] = AsyncSetSuggestedPrompts(
58+
client=req.context.client,
59+
channel_id=req.context.channel_id,
60+
thread_ts=req.context.thread_ts,
61+
)
62+
if req.context.thread_ts:
63+
req.context["set_title"] = AsyncSetTitle(req.context.client, req.context.channel_id, req.context.thread_ts)
64+
65+
# TODO: in the future we might want to introduce a "proper" extract_ts utility
66+
thread_ts_or_ts = req.context.thread_ts or event.get("ts")
67+
if thread_ts_or_ts:
68+
req.context["set_status"] = AsyncSetStatus(
69+
client=req.context.client,
70+
channel_id=req.context.channel_id,
71+
thread_ts=thread_ts_or_ts,
72+
)
73+
req.context["say_stream"] = AsyncSayStream(
74+
client=req.context.client,
75+
channel=req.context.channel_id,
76+
recipient_team_id=req.context.team_id or req.context.enterprise_id,
77+
recipient_user_id=req.context.user_id,
78+
thread_ts=thread_ts_or_ts,
79+
)
7480
return await next()
Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from typing import Optional, Callable
22

3-
from slack_bolt.context.assistant.assistant_utilities import AssistantUtilities
43
from slack_bolt.context.assistant.thread_context_store.store import AssistantThreadContextStore
54
from slack_bolt.context.say_stream.say_stream import SayStream
65
from slack_bolt.context.set_status.set_status import SetStatus
76
from slack_bolt.context.set_suggested_prompts.set_suggested_prompts import SetSuggestedPrompts
7+
from slack_bolt.context.set_title import SetTitle
88
from slack_bolt.middleware import Middleware
9+
from slack_bolt.context.assistant.assistant_utilities import AssistantUtilities
910
from slack_bolt.request.payload_utils import (
1011
is_assistant_event,
1112
is_assistant_thread_context_changed_event,
@@ -26,43 +27,48 @@ def __init__(self, thread_context_store: Optional[AssistantThreadContextStore] =
2627

2728
def process(self, *, req: BoltRequest, resp: BoltResponse, next: Callable[[], BoltResponse]) -> Optional[BoltResponse]:
2829
event = to_event(req.body)
29-
if event is not None:
30-
if is_assistant_event(req.body):
31-
assistant = AssistantUtilities(
32-
payload=event,
33-
context=req.context,
34-
thread_context_store=self.thread_context_store,
35-
)
36-
req.context["say"] = assistant.say
37-
req.context["set_title"] = assistant.set_title
38-
# req.context["set_suggested_prompts"] = assistant.set_suggested_prompts
39-
req.context["get_thread_context"] = assistant.get_thread_context
40-
req.context["save_thread_context"] = assistant.save_thread_context
30+
if event is None:
31+
return next()
32+
if req.context.channel_id is None:
33+
return next()
34+
35+
if is_assistant_event(req.body):
36+
# TODO: eventually we might remove this assistant specific logic
37+
assistant = AssistantUtilities(
38+
payload=event,
39+
context=req.context,
40+
thread_context_store=self.thread_context_store,
41+
)
42+
req.context["say"] = assistant.say
43+
req.context["get_thread_context"] = assistant.get_thread_context
44+
req.context["save_thread_context"] = assistant.save_thread_context
45+
46+
if (
47+
is_im_message_event(req.body)
48+
or is_assistant_thread_started_event(req.body)
49+
or is_assistant_thread_context_changed_event(req.body)
50+
):
51+
req.context["set_suggested_prompts"] = SetSuggestedPrompts(
52+
client=req.context.client,
53+
channel_id=req.context.channel_id,
54+
thread_ts=req.context.thread_ts,
55+
)
56+
if req.context.thread_ts:
57+
req.context["set_title"] = SetTitle(req.context.client, req.context.channel_id, req.context.thread_ts)
4158

42-
if req.context.channel_id:
43-
# TODO: in the future we might want to introduce a "proper" extract_ts utility
44-
thread_ts = req.context.thread_ts or event.get("ts")
45-
if (
46-
is_im_message_event(req.body)
47-
or is_assistant_thread_started_event(req.body)
48-
or is_assistant_thread_context_changed_event(req.body)
49-
):
50-
req.context["set_suggested_prompts"] = SetSuggestedPrompts(
51-
client=req.context.client,
52-
channel_id=req.context.channel_id,
53-
thread_ts=thread_ts,
54-
)
55-
if thread_ts:
56-
req.context["set_status"] = SetStatus(
57-
client=req.context.client,
58-
channel_id=req.context.channel_id,
59-
thread_ts=thread_ts,
60-
)
61-
req.context["say_stream"] = SayStream(
62-
client=req.context.client,
63-
channel=req.context.channel_id,
64-
recipient_team_id=req.context.team_id or req.context.enterprise_id,
65-
recipient_user_id=req.context.user_id,
66-
thread_ts=thread_ts,
67-
)
59+
# TODO: in the future we might want to introduce a "proper" extract_ts utility
60+
thread_ts_or_ts = req.context.thread_ts or event.get("ts")
61+
if thread_ts_or_ts:
62+
req.context["set_status"] = SetStatus(
63+
client=req.context.client,
64+
channel_id=req.context.channel_id,
65+
thread_ts=thread_ts_or_ts,
66+
)
67+
req.context["say_stream"] = SayStream(
68+
client=req.context.client,
69+
channel=req.context.channel_id,
70+
recipient_team_id=req.context.team_id or req.context.enterprise_id,
71+
recipient_user_id=req.context.user_id,
72+
thread_ts=thread_ts_or_ts,
73+
)
6874
return next()

‎slack_bolt/request/payload_utils.py‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@ def is_message_event(body: Dict[str, Any]) -> bool:
3737
return False
3838

3939

40+
def is_any_im_message_event(body: Dict[str, Any]) -> bool:
41+
if is_message_event(body):
42+
# Any message event with no subtype or any subtype (message_changed, message_deleted, etc.)
43+
return body["event"].get("channel_type") == "im"
44+
return False
45+
46+
47+
def is_im_message_event(body: Dict[str, Any]) -> bool:
48+
if is_any_im_message_event(body):
49+
return body["event"].get("subtype") in (None, "file_share")
50+
return False
51+
52+
4053
def is_assistant_event(body: Dict[str, Any]) -> bool:
4154
return is_event(body) and (
4255
is_assistant_thread_started_event(body)
@@ -58,19 +71,6 @@ def is_assistant_thread_context_changed_event(body: Dict[str, Any]) -> bool:
5871
return False
5972

6073

61-
def is_any_im_message_event(body: Dict[str, Any]) -> bool:
62-
if is_message_event(body):
63-
# no subtype or message_changed, message_deleted etc.
64-
return body["event"].get("channel_type") == "im"
65-
return False
66-
67-
68-
def is_im_message_event(body: Dict[str, Any]) -> bool:
69-
if is_any_im_message_event(body):
70-
return body["event"].get("subtype") in (None, "file_share")
71-
return False
72-
73-
7474
def is_user_message_event_in_assistant_thread(body: Dict[str, Any]) -> bool:
7575
if is_event(body):
7676
return (

0 commit comments

Comments
 (0)