Skip to content

Commit 65ac185

Browse files
docs: add say_stream notes to the sending messages page (#1463)
Co-authored-by: William Bergamin <wbergamin@salesforce.com>
1 parent 6406058 commit 65ac185

File tree

3 files changed

+48
-37
lines changed

3 files changed

+48
-37
lines changed

docs/english/_sidebar.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,7 @@
8585
"tools/bolt-python/concepts/token-rotation"
8686
]
8787
},
88-
{
89-
"type": "category",
90-
"label": "Experiments",
91-
"items": ["tools/bolt-python/experiments"]
92-
},
88+
"tools/bolt-python/experiments",
9389
{
9490
"type": "category",
9591
"label": "Legacy",

docs/english/concepts/message-sending.md

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -43,37 +43,58 @@ def show_datepicker(event, say):
4343

4444
## Streaming messages {#streaming-messages}
4545

46-
You can have your app's messages stream in to replicate conventional AI chatbot behavior. This is done through three Web API methods:
46+
You can have your app's messages stream in to replicate conventional agent behavior. Bolt for Python provides a `say_stream` utility as a listener argument available for `app.event` and `app.message` listeners.
4747

48-
* [`chat_startStream`](/reference/methods/chat.startStream)
49-
* [`chat_appendStream`](/reference/methods/chat.appendStream)
50-
* [`chat_stopStream`](/reference/methods/chat.stopStream)
48+
The `say_stream` utility streamlines calling the Python Slack SDK's [`WebClient.chat_stream`](https://docs.slack.dev/tools/python-slack-sdk/reference/web/client.html#slack_sdk.web.client.WebClient.chat_stream) helper utility by sourcing parameter values from the relevant event payload.
5149

52-
The Python Slack SDK provides a [`chat_stream()`](https://docs.slack.dev/tools/python-slack-sdk/reference/web/client.html#slack_sdk.web.client.WebClient.chat_stream) helper utility to streamline calling these methods. Here's an excerpt from our [Assistant template app](https://github.com/slack-samples/bolt-python-assistant-template):
50+
| Parameter | Value |
51+
|---|---|
52+
| `channel_id` | Sourced from the event payload.
53+
| `thread_ts` | Sourced from the event payload. Falls back to the `ts` value if available.
54+
| `recipient_team_id` | Sourced from the event `team_id` (`enterprise_id` if the app is installed on an org).
55+
| `recipient_user_id` | Sourced from the `user_id` of the event.
5356

54-
```python
55-
streamer = client.chat_stream(
56-
channel=channel_id,
57-
recipient_team_id=team_id,
58-
recipient_user_id=user_id,
59-
thread_ts=thread_ts,
60-
)
61-
62-
# Loop over OpenAI response stream
63-
# https://platform.openai.com/docs/api-reference/responses/create
64-
for event in returned_message:
65-
if event.type == "response.output_text.delta":
66-
streamer.append(markdown_text=f"{event.delta}")
67-
else:
68-
continue
69-
70-
feedback_block = create_feedback_block()
71-
streamer.stop(blocks=feedback_block)
57+
If neither a `channel_id` or `thread_ts` can be sourced, then the utility will merely be `None`.
58+
59+
For information on calling the `chat_*Stream` API methods directly, see the [_Sending streaming messages_](/tools/python-slack-sdk/web#sending-streaming-messages) section of the Python Slack SDK docs.
60+
61+
### Example {#example}
62+
63+
```py
64+
import os
65+
66+
from slack_bolt import App, SayStream
67+
from slack_bolt.adapter.socket_mode import SocketModeHandler
68+
from slack_sdk import WebClient
69+
70+
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))
71+
72+
@app.event("app_mention")
73+
def handle_app_mention(client: WebClient, say_stream: SayStream):
74+
stream = say_stream()
75+
stream.append(markdown_text="Someone rang the bat signal!")
76+
stream.stop()
77+
78+
@app.message("")
79+
def handle_message(client: WebClient, say_stream: SayStream):
80+
stream = say_stream()
81+
82+
stream.append(markdown_text="Let me consult my *vast knowledge database*...)
83+
stream.stop()
84+
85+
if __name__ == "__main__":
86+
SocketModeHandler(app, os.environ.get("SLACK_APP_TOKEN")).start()
7287
```
7388

74-
In that example, a [feedback buttons](/reference/block-kit/block-elements/feedback-buttons-element) block element is passed to `streamer.stop` to provide feedback buttons to the user at the bottom of the message. Interaction with these buttons will send a block action event to your app to receive the feedback.
89+
#### Adding feedback buttons after a stream
7590

76-
```python
91+
You can pass a [feedback buttons](/reference/block-kit/block-elements/feedback-buttons-element) block element to `stream.stop` to provide feedback buttons to the user at the bottom of the message. Interaction with these buttons will send a block action event to your app to receive the feedback.
92+
93+
```py
94+
stream.stop(blocks=feedback_block)
95+
```
96+
97+
```py
7798
def create_feedback_block() -> List[Block]:
7899
blocks: List[Block] = [
79100
ContextActionsBlock(
@@ -95,6 +116,4 @@ def create_feedback_block() -> List[Block]:
95116
)
96117
]
97118
return blocks
98-
```
99-
100-
For information on calling the `chat_*Stream` API methods without the helper utility, see the [_Sending streaming messages_](/tools/python-slack-sdk/web#sending-streaming-messages) section of the Python Slack SDK docs.
119+
```

docs/english/experiments.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,3 @@ def handle_mention(agent: BoltAgent):
2828
stream.append(markdown_text="Hello!")
2929
stream.stop()
3030
```
31-
32-
### Limitations
33-
34-
The `chat_stream()` method currently only works when the `thread_ts` field is available in the event context (DMs and threaded replies). Top-level channel messages do not have a `thread_ts` field, and the `ts` field is not yet provided to `BoltAgent`.

0 commit comments

Comments
 (0)