Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: reorganizes nav to match Bolt JS style #1241

Merged
merged 6 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 0 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ Then grab the latest version of Node.
nvm install node
```


If you are running this project locally for the first time, you'll need to install the packages with the following command:

```
Expand Down
46 changes: 0 additions & 46 deletions docs/content/basic/action-listening.md

This file was deleted.

36 changes: 0 additions & 36 deletions docs/content/basic/action-respond.md

This file was deleted.

File renamed without changes.
73 changes: 73 additions & 0 deletions docs/content/concepts/actions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
title: Listening & responding to actions
lang: en
slug: /concepts/actions
---

Your app can listen and respond to user actions, like button clicks, and menu selects, using the `action` method.

## Listening to actions

Actions can be filtered on an `action_id` parameter of type `str` or `re.Pattern`. The `action_id` parameter acts as a unique identifier for interactive components on the Slack platform.

You'll notice in all `action()` examples, `ack()` is used. It is required to call the `ack()` function within an action listener to acknowledge that the request was received from Slack. This is discussed in the [acknowledging requests guide](/concepts/acknowledge).

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

```python
# Your listener will be called every time a block element with the action_id "approve_button" is triggered
@app.action("approve_button")
def update_message(ack):
ack()
# Update the message to reflect the action
```

### Listening to actions using a constraint object

You can use a constraints object to listen to `block_id`s and `action_id`s (or any combination of them). Constraints in the object can be of type `str` or `re.Pattern`.

```python
# Your function will only be called when the action_id matches 'select_user' AND the block_id matches 'assign_ticket'
@app.action({
"block_id": "assign_ticket",
"action_id": "select_user"
})
def update_message(ack, body, client):
ack()

if "container" in body and "message_ts" in body["container"]:
client.reactions_add(
name="white_check_mark",
channel=body["channel"]["id"],
timestamp=body["container"]["message_ts"],
)
```

## Responding to actions

There are two main ways to respond to actions. The first (and most common) way is to use `say()`, which sends a message back to the conversation where the incoming request took place.

The second way to respond to actions is using `respond()`, which is a utility to use the `response_url` associated with the action.

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

```python
# Your listener will be called every time an interactive component with the action_id “approve_button” is triggered
@app.action("approve_button")
def approve_request(ack, say):
# Acknowledge action request
ack()
say("Request approved 👍")
```

### Using `respond()` method

Since `respond()` is a utility for calling the `response_url`, it behaves in the same way. You can pass [all the message payload properties](https://api.slack.com/reference/messaging/payload) as keyword arguments along with optional properties like `response_type` (which has a value of `"in_channel"` or `"ephemeral"`), `replace_original`, `delete_original`, `unfurl_links`, and `unfurl_media`. With that, your app can send a new message payload that will be published back to the source of the original interaction.

```python
# Listens to actions triggered with action_id of “user_select”
@app.action("user_select")
def select_user(ack, action, respond):
ack()
respond(f"You selected <@{action['selected_user']}>")
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ lang: en
slug: /concepts/adapters
---

Adapters are responsible for handling and parsing incoming requests from Slack to conform to [`BoltRequest`](https://github.com/slackapi/bolt-python/blob/main/slack_bolt/request/request.py), then dispatching those requests to your Bolt app.

Adapters are responsible for handling and parsing incoming requests from Slack to conform to <a href="https://github.com/slackapi/bolt-python/blob/main/slack_bolt/request/request.py">`BoltRequest`</a>, then dispatching those requests to your Bolt app.

By default, Bolt will use the built-in <a href="https://docs.python.org/3/library/http.server.html">`HTTPServer`</a> adapter. While this is okay for local development, <b>it is not recommended for production</b>. Bolt for Python includes a collection of built-in adapters that can be imported and used with your app. The built-in adapters support a variety of popular Python frameworks including Flask, Django, and Starlette among others. Adapters support the use of any production-ready web server of your choice.
By default, Bolt will use the built-in [`HTTPServer`](https://docs.python.org/3/library/http.server.html) adapter. While this is okay for local development, **it is not recommended for production**. Bolt for Python includes a collection of built-in adapters that can be imported and used with your app. The built-in adapters support a variety of popular Python frameworks including Flask, Django, and Starlette among others. Adapters support the use of any production-ready web server of your choice.

To use an adapter, you'll create an app with the framework of your choosing and import its corresponding adapter. Then you'll initialize the adapter instance and call its function that handles and parses incoming requests.

The full list adapters, as well as configuration and sample usage, can be found within the repository's <a href="https://github.com/slackapi/bolt-python/tree/main/examples">`examples` folder</a>.

The full list adapters, as well as configuration and sample usage, can be found within the repository's [`examples`](https://github.com/slackapi/bolt-python/tree/main/examples)

```python
from slack_bolt import App
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ lang: en
slug: /concepts/app-home
---

<a href="https://api.slack.com/surfaces/tabs/using">Home tabs</a> are customizable surfaces accessible via the sidebar and search that allow apps to display views on a per-user basis. After enabling App Home within your app configuration, home tabs can be published and updated by passing a `user_id` and <a href="https://api.slack.com/reference/block-kit/views">view payload</a> to the <a href="https://api.slack.com/methods/views.publish">`views.publish`</a> method.
[Home tabs](https://api.slack.com/surfaces/tabs/using) are customizable surfaces accessible via the sidebar and search that allow apps to display views on a per-user basis. After enabling App Home within your app configuration, home tabs can be published and updated by passing a `user_id` and [view payload](https://api.slack.com/reference/block-kit/views) to the [`views.publish`](https://api.slack.com/methods/views.publish) method.

You can subscribe to the <a href="https://api.slack.com/events/app_home_opened">`app_home_opened`</a> event to listen for when users open your App Home.
You can subscribe to the [`app_home_opened`](https://api.slack.com/events/app_home_opened) event to listen for when users open your App Home.

Refer to [the module document](https://tools.slack.dev/bolt-python/api-docs/slack_bolt/kwargs_injection/args.html) to learn the available listener arguments.
```python
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,9 @@ assistant = Assistant(thread_context_store=FileAssistantThreadContextStore())

Since this reference implementation relies on local files, it's not advised for use in production. For production apps, we recommend creating a class that inherits `AssistantThreadContextStore`.

<details>
If you want to check full working example app, you can check [our sample repository](https://github.com/slack-samples/bolt-python-assistant-template) on GitHub.

<summary>
Block Kit interactions in the assistant thread
</summary>
## Block Kit interactions in the assistant thread

For advanced use cases, Block Kit buttons may be used instead of suggested prompts, as well as the sending of messages with structured [metadata](https://api.slack.com/metadata) to trigger subsequent interactions with the user.

Expand Down Expand Up @@ -230,12 +228,6 @@ def respond_to_user_messages(logger: logging.Logger, set_status: SetStatus, say:
logger.exception(f"Failed to respond to an inquiry: {e}")
say(f":warning: Sorry, something went wrong during processing your request (error: {e})")


# Enable this assistant middleware in your Bolt app
app.use(assistant)
```

</details>


Lastly, if you want to check full working example app, you can check [our sample repository](https://github.com/slack-samples/bolt-python-assistant-template) on GitHub.
```
17 changes: 4 additions & 13 deletions docs/content/advanced/async.md → docs/content/concepts/async.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ lang: en
slug: /concepts/async
---

To use the async version of Bolt, you can import and initialize an `AsyncApp` instance (rather than `App`). `AsyncApp` relies on [AIOHTTP](https://docs.aiohttp.org) to make API requests, which means you'll need to install `aiohttp` (by adding to `requirements.txt` or running `pip install aiohttp`).

To use the async version of Bolt, you can import and initialize an `AsyncApp` instance (rather than `App`). `AsyncApp` relies on <a href="https://docs.aiohttp.org/">AIOHTTP</a> to make API requests, which means you'll need to install `aiohttp` (by adding to `requirements.txt` or running `pip install aiohttp`).

Sample async projects can be found within the repository's <a href="https://github.com/slackapi/bolt-python/tree/main/examples">`examples` folder</a>.

Sample async projects can be found within the repository's [examples](https://github.com/slackapi/bolt-python/tree/main/examples) folder.

```python
# Requirement: install aiohttp
Expand All @@ -28,12 +26,7 @@ if __name__ == "__main__":
app.start(3000)
```

<details>
<summary>
Using other frameworks
</summary>


## Using other frameworks

Internally `AsyncApp#start()` implements a [`AIOHTTP`](https://docs.aiohttp.org/) web server. If you prefer, you can use a framework other than `AIOHTTP` to handle incoming requests.

Expand All @@ -48,7 +41,6 @@ pip install slack_bolt sanic uvicorn
uvicorn async_app:api --reload --port 3000 --log-level debug
```


```python
from slack_bolt.async_app import AsyncApp
app = AsyncApp()
Expand Down Expand Up @@ -76,5 +68,4 @@ async def endpoint(req: Request):

if __name__ == "__main__":
api.run(host="0.0.0.0", port=int(os.environ.get("PORT", 3000)))
```
</details>
```
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ app = App(
)
```

<details>
<summary>
Customizing OAuth defaults
</summary>
## Customizing OAuth defaults

You can override the default OAuth using `oauth_settings`, which can be passed in during the initialization of App. You can override the following:

Expand Down Expand Up @@ -90,6 +87,4 @@ app = App(
callback_options=callback_options,
),
)
```

</details>
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ lang: en
slug: /concepts/authorization
---


Authorization is the process of determining which Slack credentials should be available while processing an incoming Slack request.

Apps installed on a single workspace can simply pass their bot token into the `App` constructor using the `token` parameter. However, if your app will be installed on multiple workspaces, you have two options. The easier option is to use the built-in OAuth support. This will handle setting up OAuth routes and verifying state. Read the section on [authenticating with OAuth](/concepts/authenticating-oauth) for details.
Expand All @@ -17,7 +16,6 @@ For a more custom solution, you can set the `authorize` parameter to a function
- **`enterprise_id`** and **`team_id`**, which can be found in requests sent to your app.
- **`user_id`** only when using `user_token`.


```python
import os
from slack_bolt import App
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ lang: en
slug: /concepts/context
---


All listeners have access to a `context` dictionary, which can be used to enrich requests with additional information. Bolt automatically attaches information that is included in the incoming request, like `user_id`, `team_id`, `channel_id`, and `enterprise_id`.

`context` is just a dictionary, so you can directly modify it.


```python
# Listener middleware to fetch tasks from external system using user ID
def fetch_tasks(context, event, next):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ lang: en
slug: /concepts/custom-adapters
---


[Adapters](/concepts/adapters) are flexible and can be adjusted based on the framework you prefer. There are two necessary components of adapters:

- `__init__(app: App)`: Constructor that accepts and stores an instance of the Bolt `App`.
Expand All @@ -23,7 +22,6 @@ Your adapter will return [an instance of `BoltResponse`](https://github.com/slac

For more in-depth examples of custom adapters, look at the implementations of the [built-in adapters](https://github.com/slackapi/bolt-python/tree/main/slack_bolt/adapter).


```python
# Necessary imports for Flask
from flask import Request, Response, make_response
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Listening and responding to custom steps
sidebar_label: Custom steps
lang: en
slug: /concepts/custom-steps
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ lang: en
slug: /concepts/errors
---


If an error occurs in a listener, you can handle it directly using a try/except block. Errors associated with your app will be of type `BoltError`. Errors associated with calling Slack APIs will be of type `SlackApiError`.

By default, the global error handler will log all non-handled exceptions to the console. To handle global errors yourself, you can attach a global error handler to your app using the `app.error(fn)` function.


```python
@app.error
def custom_error_handler(error, body, logger):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@ def ask_for_introduction(event, say):
text = f"Welcome to the team, <@{user_id}>! 🎉 You can introduce yourself in this channel."
say(text=text, channel=welcome_channel_id)
```
<details>

<summary>
Filtering on message subtypes
</summary>
## Filtering on message subtypes

The `message()` listener is equivalent to `event("message")`.

Expand All @@ -38,5 +35,4 @@ You can explicitly filter for events without a subtype by explicitly setting `No
def log_message_change(logger, event):
user, text = event["user"], event["text"]
logger.info(f"The user {user} changed the message to {text}")
```
</details>
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ lang: en
slug: /concepts/global-middleware
---


Global middleware is run for all incoming requests, before any listener middleware. You can add any number of global middleware to your app by passing middleware functions to `app.use()`. Middleware functions are called with the same arguments as listeners, with an additional `next()` function.

Both global and listener middleware must call `next()` to pass control of the execution chain to the next middleware.



Refer to [the module document](https://tools.slack.dev/bolt-python/api-docs/slack_bolt/kwargs_injection/args.html) to learn the available listener arguments.
```python
@app.use
Expand Down
Loading