Skip to content

Commit 6cb1507

Browse files
authored
Migrate to slack-bolt 1.21.0 (#2)
1 parent 9d9fa7e commit 6cb1507

File tree

9 files changed

+142
-5
lines changed

9 files changed

+142
-5
lines changed

listeners/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
from listeners import events
1+
from .assistant import assistant
22

33

44
def register_listeners(app):
5-
events.register(app)
5+
# Using assistant middleware is the recommended way.
6+
app.assistant(assistant)
7+
8+
# The following event listeners demonstrate how to implement the same on your own.
9+
# from listeners import events
10+
# events.register(app)

listeners/assistant.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import logging
2+
from typing import List, Dict
3+
from slack_bolt import Assistant, BoltContext, Say, SetSuggestedPrompts, SetStatus
4+
from slack_bolt.context.get_thread_context import GetThreadContext
5+
from slack_sdk import WebClient
6+
from slack_sdk.errors import SlackApiError
7+
8+
from .llm_caller import call_llm
9+
10+
# Refer to https://tools.slack.dev/bolt-python/concepts/assistant/ for more details
11+
assistant = Assistant()
12+
13+
14+
# This listener is invoked when a human user opened an assistant thread
15+
@assistant.thread_started
16+
def start_assistant_thread(
17+
say: Say,
18+
get_thread_context: GetThreadContext,
19+
set_suggested_prompts: SetSuggestedPrompts,
20+
logger: logging.Logger,
21+
):
22+
try:
23+
say("How can I help you?")
24+
25+
prompts: List[Dict[str, str]] = [
26+
{
27+
"title": "What does Slack stand for?",
28+
"message": "Slack, a business communication service, was named after an acronym. Can you guess what it stands for?",
29+
},
30+
{
31+
"title": "Write a draft announcement",
32+
"message": "Can you write a draft announcement about a new feature my team just released? It must include how impactful it is.",
33+
},
34+
{
35+
"title": "Suggest names for my Slack app",
36+
"message": "Can you suggest a few names for my Slack app? The app helps my teammates better organize information and plan priorities and action items.",
37+
},
38+
]
39+
40+
thread_context = get_thread_context()
41+
if thread_context is not None and thread_context.channel_id is not None:
42+
summarize_channel = {
43+
"title": "Summarize the referred channel",
44+
"message": "Can you generate a brief summary of the referred channel?",
45+
}
46+
prompts.append(summarize_channel)
47+
48+
set_suggested_prompts(prompts=prompts)
49+
except Exception as e:
50+
logger.exception(f"Failed to handle an assistant_thread_started event: {e}", e)
51+
say(f":warning: Something went wrong! ({e})")
52+
53+
54+
# This listener is invoked when the human user sends a reply in the assistant thread
55+
@assistant.user_message
56+
def respond_in_assistant_thread(
57+
payload: dict,
58+
logger: logging.Logger,
59+
context: BoltContext,
60+
set_status: SetStatus,
61+
get_thread_context: GetThreadContext,
62+
client: WebClient,
63+
say: Say,
64+
):
65+
try:
66+
user_message = payload["text"]
67+
set_status("is typing...")
68+
69+
if user_message == "Can you generate a brief summary of the referred channel?":
70+
# the logic here requires the additional bot scopes:
71+
# channels:join, channels:history, groups:history
72+
thread_context = get_thread_context()
73+
referred_channel_id = thread_context.get("channel_id")
74+
try:
75+
channel_history = client.conversations_history(channel=referred_channel_id, limit=50)
76+
except SlackApiError as e:
77+
if e.response["error"] == "not_in_channel":
78+
# If this app's bot user is not in the public channel,
79+
# we'll try joining the channel and then calling the same API again
80+
client.conversations_join(channel=referred_channel_id)
81+
channel_history = client.conversations_history(channel=referred_channel_id, limit=50)
82+
else:
83+
raise e
84+
85+
prompt = f"Can you generate a brief summary of these messages in a Slack channel <#{referred_channel_id}>?\n\n"
86+
for message in reversed(channel_history.get("messages")):
87+
if message.get("user") is not None:
88+
prompt += f"\n<@{message['user']}> says: {message['text']}\n"
89+
messages_in_thread = [{"role": "user", "content": prompt}]
90+
returned_message = call_llm(messages_in_thread)
91+
say(returned_message)
92+
return
93+
94+
replies = client.conversations_replies(
95+
channel=context.channel_id,
96+
ts=context.thread_ts,
97+
oldest=context.thread_ts,
98+
limit=10,
99+
)
100+
messages_in_thread: List[Dict[str, str]] = []
101+
for message in replies["messages"]:
102+
role = "user" if message.get("bot_id") is None else "assistant"
103+
messages_in_thread.append({"role": role, "content": message["text"]})
104+
returned_message = call_llm(messages_in_thread)
105+
say(returned_message)
106+
107+
except Exception as e:
108+
logger.exception(f"Failed to handle a user message event: {e}")
109+
say(f":warning: Something went wrong! ({e})")

listeners/events/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# This sample app repository contains event listener code to help developers understand what's happening under the hood.
2+
# We recommend using assistant middleware instead of these event listeners.
3+
# For more details, refer to https://tools.slack.dev/bolt-python/concepts/assistant/.
4+
15
from typing import Dict, Any
26

37
from slack_bolt import App

listeners/events/assistant_thread_started.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# This sample app repository contains event listener code to help developers understand what's happening under the hood.
2+
# We recommend using assistant middleware instead of these event listeners.
3+
# For more details, refer to https://tools.slack.dev/bolt-python/concepts/assistant/.
4+
15
from typing import List, Dict
26
from logging import Logger
37

listeners/events/asssistant_thread_context_changed.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# This sample app repository contains event listener code to help developers understand what's happening under the hood.
2+
# We recommend using assistant middleware instead of these event listeners.
3+
# For more details, refer to https://tools.slack.dev/bolt-python/concepts/assistant/.
4+
15
from slack_sdk import WebClient
26
from slack_bolt import BoltContext
37

listeners/events/thread_context_store.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# This sample app repository contains event listener code to help developers understand what's happening under the hood.
2+
# We recommend using assistant middleware instead of these event listeners.
3+
# For more details, refer to https://tools.slack.dev/bolt-python/concepts/assistant/.
4+
15
from typing import Optional
26
from slack_sdk import WebClient
37
from slack_bolt import BoltContext

listeners/events/user_message.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
# This sample app repository contains event listener code to help developers understand what's happening under the hood.
2+
# We recommend using assistant middleware instead of these event listeners.
3+
# For more details, refer to https://tools.slack.dev/bolt-python/concepts/assistant/.
4+
15
from typing import List, Dict
26
from logging import Logger
37

48
from slack_sdk.web import WebClient
59
from slack_sdk.errors import SlackApiError
610
from slack_bolt import BoltContext
7-
from .llm_caller import call_llm
11+
from ..llm_caller import call_llm
812
from .thread_context_store import get_thread_context
913

1014

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
"""
1414

1515

16-
def call_llm(messages_in_thread: List[Dict[str, str]], system_content: str = DEFAULT_SYSTEM_CONTENT) -> str:
16+
def call_llm(
17+
messages_in_thread: List[Dict[str, str]],
18+
system_content: str = DEFAULT_SYSTEM_CONTENT,
19+
) -> str:
1720
openai_client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
1821
messages = [{"role": "system", "content": system_content}]
1922
messages.extend(messages_in_thread)

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
slack-bolt>=1.20.1,<2
1+
slack-bolt>=1.21,<2
22
slack-sdk>=3.33.1,<4
33
# If you use a different LLM vendor, replace this dependency
44
openai

0 commit comments

Comments
 (0)