Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
408 changes: 317 additions & 91 deletions docs/english/concepts/ai-apps.md

Large diffs are not rendered by default.

61 changes: 60 additions & 1 deletion docs/english/concepts/message-sending.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Within your listener function, `say()` is available whenever there is an associa
In the case that you'd like to send a message outside of a listener or you want to do something more advanced (like handle specific errors), you can call `client.chat_postMessage` [using the client attached to your Bolt instance](/tools/bolt-python/concepts/web-api).

Refer to [the module document](https://docs.slack.dev/tools/bolt-python/reference/kwargs_injection/args.html) to learn the available listener arguments.

```python
# Listens for messages containing "knock knock" and responds with an italicized "who's there?"
@app.message("knock knock")
Expand Down Expand Up @@ -38,4 +39,62 @@ def show_datepicker(event, say):
blocks=blocks,
text="Pick a date for me to remind you"
)
```
```

## Streaming messages {#streaming-messages}

You can have your app's messages stream in to replicate conventional AI chatbot behavior. This is done through three Web API methods:

* [`chat_startStream`](/reference/methods/chat.startstream)
* [`chat_appendStream`](/reference/methods/chat.appendstream)
* [`chat_stopStream`](/reference/methods/chat.stopstream)

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):

```python
streamer = client.chat_stream(
channel=channel_id,
recipient_team_id=team_id,
recipient_user_id=user_id,
thread_ts=thread_ts,
)

# Loop over OpenAI response stream
# https://platform.openai.com/docs/api-reference/responses/create
for event in returned_message:
if event.type == "response.output_text.delta":
streamer.append(markdown_text=f"{event.delta}")
else:
continue

feedback_block = create_feedback_block()
streamer.stop(blocks=feedback_block)
```

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.

```python
def create_feedback_block() -> List[Block]:
blocks: List[Block] = [
ContextActionsBlock(
elements=[
FeedbackButtonsElement(
action_id="feedback",
positive_button=FeedbackButtonObject(
text="Good Response",
accessibility_label="Submit positive feedback on this response",
value="good-feedback",
),
negative_button=FeedbackButtonObject(
text="Bad Response",
accessibility_label="Submit negative feedback on this response",
value="bad-feedback",
),
)
]
)
]
return blocks
```

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.
11 changes: 8 additions & 3 deletions docs/reference/app/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -1195,7 +1195,9 @@ <h2 class="section-title" id="header-classes">Classes</h2>
middleware: Optional[Sequence[Union[Callable, Middleware]]] = None,
) -&gt; Callable[..., Optional[Callable[..., Optional[BoltResponse]]]]:
&#34;&#34;&#34;Registers a new `view_submission` listener.
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for details.&#34;&#34;&#34;
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for
details.
&#34;&#34;&#34;

def __call__(*args, **kwargs):
functions = self._to_listener_functions(kwargs) if kwargs else list(args)
Expand Down Expand Up @@ -3018,7 +3020,9 @@ <h2 id="args">Args</h2>
middleware: Optional[Sequence[Union[Callable, Middleware]]] = None,
) -&gt; Callable[..., Optional[Callable[..., Optional[BoltResponse]]]]:
&#34;&#34;&#34;Registers a new `view_submission` listener.
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for details.&#34;&#34;&#34;
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for
details.
&#34;&#34;&#34;

def __call__(*args, **kwargs):
functions = self._to_listener_functions(kwargs) if kwargs else list(args)
Expand All @@ -3028,7 +3032,8 @@ <h2 id="args">Args</h2>
return __call__</code></pre>
</details>
<div class="desc"><p>Registers a new <code>view_submission</code> listener.
Refer to <a href="https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission">https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission</a> for details.</p></div>
Refer to <a href="https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission">https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission</a> for
details.</p></div>
</dd>
</dl>
</dd>
Expand Down
11 changes: 8 additions & 3 deletions docs/reference/app/async_app.html
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,9 @@ <h2 class="section-title" id="header-classes">Classes</h2>
middleware: Optional[Sequence[Union[Callable, AsyncMiddleware]]] = None,
) -&gt; Callable[..., Optional[Callable[..., Awaitable[Optional[BoltResponse]]]]]:
&#34;&#34;&#34;Registers a new `view_submission` listener.
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for details.&#34;&#34;&#34;
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for
details.
&#34;&#34;&#34;

def __call__(*args, **kwargs):
functions = self._to_listener_functions(kwargs) if kwargs else list(args)
Expand Down Expand Up @@ -3075,7 +3077,9 @@ <h2 id="args">Args</h2>
middleware: Optional[Sequence[Union[Callable, AsyncMiddleware]]] = None,
) -&gt; Callable[..., Optional[Callable[..., Awaitable[Optional[BoltResponse]]]]]:
&#34;&#34;&#34;Registers a new `view_submission` listener.
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for details.&#34;&#34;&#34;
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for
details.
&#34;&#34;&#34;

def __call__(*args, **kwargs):
functions = self._to_listener_functions(kwargs) if kwargs else list(args)
Expand All @@ -3085,7 +3089,8 @@ <h2 id="args">Args</h2>
return __call__</code></pre>
</details>
<div class="desc"><p>Registers a new <code>view_submission</code> listener.
Refer to <a href="https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission">https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission</a> for details.</p></div>
Refer to <a href="https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission">https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission</a> for
details.</p></div>
</dd>
<dt id="slack_bolt.app.async_app.AsyncApp.web_app"><code class="name flex">
<span>def <span class="ident">web_app</span></span>(<span>self, path: str = '/slack/events', port: int = 3000) ‑> aiohttp.web_app.Application</span>
Expand Down
11 changes: 8 additions & 3 deletions docs/reference/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1214,7 +1214,9 @@ <h2 class="section-title" id="header-classes">Classes</h2>
middleware: Optional[Sequence[Union[Callable, Middleware]]] = None,
) -&gt; Callable[..., Optional[Callable[..., Optional[BoltResponse]]]]:
&#34;&#34;&#34;Registers a new `view_submission` listener.
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for details.&#34;&#34;&#34;
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for
details.
&#34;&#34;&#34;

def __call__(*args, **kwargs):
functions = self._to_listener_functions(kwargs) if kwargs else list(args)
Expand Down Expand Up @@ -3037,7 +3039,9 @@ <h2 id="args">Args</h2>
middleware: Optional[Sequence[Union[Callable, Middleware]]] = None,
) -&gt; Callable[..., Optional[Callable[..., Optional[BoltResponse]]]]:
&#34;&#34;&#34;Registers a new `view_submission` listener.
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for details.&#34;&#34;&#34;
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for
details.
&#34;&#34;&#34;

def __call__(*args, **kwargs):
functions = self._to_listener_functions(kwargs) if kwargs else list(args)
Expand All @@ -3047,7 +3051,8 @@ <h2 id="args">Args</h2>
return __call__</code></pre>
</details>
<div class="desc"><p>Registers a new <code>view_submission</code> listener.
Refer to <a href="https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission">https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission</a> for details.</p></div>
Refer to <a href="https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission">https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission</a> for
details.</p></div>
</dd>
</dl>
</dd>
Expand Down
26 changes: 20 additions & 6 deletions docs/reference/async_app.html
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,9 @@ <h3>Class variables</h3>
middleware: Optional[Sequence[Union[Callable, AsyncMiddleware]]] = None,
) -&gt; Callable[..., Optional[Callable[..., Awaitable[Optional[BoltResponse]]]]]:
&#34;&#34;&#34;Registers a new `view_submission` listener.
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for details.&#34;&#34;&#34;
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for
details.
&#34;&#34;&#34;

def __call__(*args, **kwargs):
functions = self._to_listener_functions(kwargs) if kwargs else list(args)
Expand Down Expand Up @@ -3166,7 +3168,9 @@ <h2 id="args">Args</h2>
middleware: Optional[Sequence[Union[Callable, AsyncMiddleware]]] = None,
) -&gt; Callable[..., Optional[Callable[..., Awaitable[Optional[BoltResponse]]]]]:
&#34;&#34;&#34;Registers a new `view_submission` listener.
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for details.&#34;&#34;&#34;
Refer to https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission for
details.
&#34;&#34;&#34;

def __call__(*args, **kwargs):
functions = self._to_listener_functions(kwargs) if kwargs else list(args)
Expand All @@ -3176,7 +3180,8 @@ <h2 id="args">Args</h2>
return __call__</code></pre>
</details>
<div class="desc"><p>Registers a new <code>view_submission</code> listener.
Refer to <a href="https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission">https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission</a> for details.</p></div>
Refer to <a href="https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission">https://docs.slack.dev/reference/interaction-payloads/view-interactions-payload/#view_submission</a> for
details.</p></div>
</dd>
<dt id="slack_bolt.async_app.AsyncApp.web_app"><code class="name flex">
<span>def <span class="ident">web_app</span></span>(<span>self, path: str = '/slack/events', port: int = 3000) ‑> aiohttp.web_app.Application</span>
Expand Down Expand Up @@ -5158,6 +5163,7 @@ <h3>Class variables</h3>
icon_emoji: Optional[str] = None,
icon_url: Optional[str] = None,
username: Optional[str] = None,
markdown_text: Optional[str] = None,
mrkdwn: Optional[bool] = None,
link_names: Optional[bool] = None,
parse: Optional[str] = None, # none, full
Expand All @@ -5183,6 +5189,7 @@ <h3>Class variables</h3>
icon_emoji=icon_emoji,
icon_url=icon_url,
username=username,
markdown_text=markdown_text,
mrkdwn=mrkdwn,
link_names=link_names,
parse=parse,
Expand Down Expand Up @@ -5248,11 +5255,18 @@ <h3>Class variables</h3>
self.channel_id = channel_id
self.thread_ts = thread_ts

async def __call__(self, status: str) -&gt; AsyncSlackResponse:
async def __call__(
self,
status: str,
loading_messages: Optional[List[str]] = None,
**kwargs,
) -&gt; AsyncSlackResponse:
return await self.client.assistant_threads_setStatus(
status=status,
channel_id=self.channel_id,
thread_ts=self.thread_ts,
status=status,
loading_messages=loading_messages,
**kwargs,
)</code></pre>
</details>
<div class="desc"></div>
Expand Down Expand Up @@ -5298,7 +5312,7 @@ <h3>Class variables</h3>

async def __call__(
self,
prompts: List[Union[str, Dict[str, str]]],
prompts: Sequence[Union[str, Dict[str, str]]],
title: Optional[str] = None,
) -&gt; AsyncSlackResponse:
prompts_arg: List[Dict[str, str]] = []
Expand Down
2 changes: 2 additions & 0 deletions docs/reference/context/say/async_say.html
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
icon_emoji: Optional[str] = None,
icon_url: Optional[str] = None,
username: Optional[str] = None,
markdown_text: Optional[str] = None,
mrkdwn: Optional[bool] = None,
link_names: Optional[bool] = None,
parse: Optional[str] = None, # none, full
Expand All @@ -112,6 +113,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
icon_emoji=icon_emoji,
icon_url=icon_url,
username=username,
markdown_text=markdown_text,
mrkdwn=mrkdwn,
link_names=link_names,
parse=parse,
Expand Down
2 changes: 2 additions & 0 deletions docs/reference/context/say/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
icon_emoji: Optional[str] = None,
icon_url: Optional[str] = None,
username: Optional[str] = None,
markdown_text: Optional[str] = None,
mrkdwn: Optional[bool] = None,
link_names: Optional[bool] = None,
parse: Optional[str] = None, # none, full
Expand All @@ -130,6 +131,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
icon_emoji=icon_emoji,
icon_url=icon_url,
username=username,
markdown_text=markdown_text,
mrkdwn=mrkdwn,
link_names=link_names,
parse=parse,
Expand Down
2 changes: 2 additions & 0 deletions docs/reference/context/say/say.html
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
icon_emoji: Optional[str] = None,
icon_url: Optional[str] = None,
username: Optional[str] = None,
markdown_text: Optional[str] = None,
mrkdwn: Optional[bool] = None,
link_names: Optional[bool] = None,
parse: Optional[str] = None, # none, full
Expand All @@ -115,6 +116,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
icon_emoji=icon_emoji,
icon_url=icon_url,
username=username,
markdown_text=markdown_text,
mrkdwn=mrkdwn,
link_names=link_names,
parse=parse,
Expand Down
11 changes: 9 additions & 2 deletions docs/reference/context/set_status/async_set_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,18 @@ <h2 class="section-title" id="header-classes">Classes</h2>
self.channel_id = channel_id
self.thread_ts = thread_ts

async def __call__(self, status: str) -&gt; AsyncSlackResponse:
async def __call__(
self,
status: str,
loading_messages: Optional[List[str]] = None,
**kwargs,
) -&gt; AsyncSlackResponse:
return await self.client.assistant_threads_setStatus(
status=status,
channel_id=self.channel_id,
thread_ts=self.thread_ts,
status=status,
loading_messages=loading_messages,
**kwargs,
)</code></pre>
</details>
<div class="desc"></div>
Expand Down
11 changes: 9 additions & 2 deletions docs/reference/context/set_status/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,18 @@ <h2 class="section-title" id="header-classes">Classes</h2>
self.channel_id = channel_id
self.thread_ts = thread_ts

def __call__(self, status: str) -&gt; SlackResponse:
def __call__(
self,
status: str,
loading_messages: Optional[List[str]] = None,
**kwargs,
) -&gt; SlackResponse:
return self.client.assistant_threads_setStatus(
status=status,
channel_id=self.channel_id,
thread_ts=self.thread_ts,
status=status,
loading_messages=loading_messages,
**kwargs,
)</code></pre>
</details>
<div class="desc"></div>
Expand Down
11 changes: 9 additions & 2 deletions docs/reference/context/set_status/set_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,18 @@ <h2 class="section-title" id="header-classes">Classes</h2>
self.channel_id = channel_id
self.thread_ts = thread_ts

def __call__(self, status: str) -&gt; SlackResponse:
def __call__(
self,
status: str,
loading_messages: Optional[List[str]] = None,
**kwargs,
) -&gt; SlackResponse:
return self.client.assistant_threads_setStatus(
status=status,
channel_id=self.channel_id,
thread_ts=self.thread_ts,
status=status,
loading_messages=loading_messages,
**kwargs,
)</code></pre>
</details>
<div class="desc"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>

async def __call__(
self,
prompts: List[Union[str, Dict[str, str]]],
prompts: Sequence[Union[str, Dict[str, str]]],
title: Optional[str] = None,
) -&gt; AsyncSlackResponse:
prompts_arg: List[Dict[str, str]] = []
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/context/set_suggested_prompts/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>

def __call__(
self,
prompts: List[Union[str, Dict[str, str]]],
prompts: Sequence[Union[str, Dict[str, str]]],
title: Optional[str] = None,
) -&gt; SlackResponse:
prompts_arg: List[Dict[str, str]] = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>

def __call__(
self,
prompts: List[Union[str, Dict[str, str]]],
prompts: Sequence[Union[str, Dict[str, str]]],
title: Optional[str] = None,
) -&gt; SlackResponse:
prompts_arg: List[Dict[str, str]] = []
Expand Down
Loading
Loading