Skip to content

Commit

Permalink
docs: concept focused nav (#2302)
Browse files Browse the repository at this point in the history
Co-authored-by: Kazuhiro Sera <seratch@gmail.com>
  • Loading branch information
lukegalbraithrussell and seratch authored Oct 29, 2024
1 parent e51960b commit d3fe549
Show file tree
Hide file tree
Showing 89 changed files with 1,134 additions and 1,648 deletions.
36 changes: 0 additions & 36 deletions docs/content/basic/action-respond.md

This file was deleted.

53 changes: 0 additions & 53 deletions docs/content/basic/event-listening.md

This file was deleted.

41 changes: 0 additions & 41 deletions docs/content/basic/message-listening.md

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
---
title: Listening to actions
title: Listening & responding to actions
lang: en
slug: /concepts/action-listening
slug: /concepts/actions
---

Your app can listen to user actions like button clicks, and menu selects, using the `action` method.
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` of type string or RegExp object. `action_id`s act as unique identifiers 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 section](/concepts/acknowledge).

:::info

Since v2, message shortcuts (previously message actions) now use the `shortcut()` method instead of the `action()` method. View the [migration guide for V2](/tutorial/migration-v2) to learn about the changes.

:::

View more information about the `block_actions` payload within the [relevant API documentation page](https://api.slack.com/reference/interaction-payloads). To access the full payload of a view from within a listener, reference the `body` argument within your callback function.

```javascript
Expand All @@ -26,10 +22,7 @@ app.action('approve_button', async ({ ack }) => {
});
```

<details>
<summary>
Listening to actions using a constraint object
</summary>
### Listening to actions using a constraint object

You can use a constraints object to listen to `callback_id`s, `block_id`s, and `action_id`s (or any combination of them). Constraints in the object can be of type string or RegExp object.

Expand All @@ -56,4 +49,32 @@ app.action({ action_id: 'select_user', block_id: 'assign_ticket' },
});
```

</details>
## Responding to actions

There are two main ways to respond to actions. The first (and most common) way is to use the `say` function. The `say` function 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 simple utility to use the `response_url` associated with an action.

```javascript
// Your middleware will be called every time an interactive component with the action_id “approve_button” is triggered
app.action('approve_button', async ({ ack, say }) => {
// Acknowledge action request
await ack();
await say('Request approved 👍');
});
```


### Using the `respond()` utility

Since `respond()` is a utility for calling the `response_url`, it behaves in the same way. You can pass a JSON object with a new message payload that will be published back to the source of the original interaction with optional properties like `response_type` (which has a value of `in_channel` or `ephemeral`), `replace_original`, and `delete_original`.

```javascript
// Listens to actions triggered with action_id of “user_select”
app.action('user_select', async ({ action, ack, respond }) => {
await ack();
if (action.type === 'users_select') {
await respond(`You selected <@${action.selected_user}>`);
}
});
```
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Listening and responding to commands
title: Listening & responding to commands
lang: en
slug: /concepts/commands
---
Expand All @@ -14,7 +14,7 @@ If you use `command()` multiple times with overlapping RegExp matches, _all_ mat

Commands must be acknowledged with `ack()` to inform Slack your app has received the request.

There are two ways to respond to slash commands. The first way is to use `say()`, which accepts a string or JSON payload. The second is `respond()` which is a utility for the `response_url`. These are explained in more depth in the [responding to actions](/concepts/action-respond) section.
There are two ways to respond to slash commands. The first way is to use `say()`, which accepts a string or JSON payload. The second is `respond()` which is a utility for the `response_url`. These are explained in more depth in the [responding to actions](/concepts/actions) section.

When configuring commands within your app configuration, you'll continue to append `/slack/events` to your request URL.

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Listening and responding to custom steps
title: Custom Steps
lang: en
slug: /concepts/custom-steps
---
Expand Down Expand Up @@ -64,11 +64,11 @@ Example app manifest definition

---

### Listening to custom step interactivity events
## Listening to custom step interactivity events

Your app's custom steps may create interactivity points for users, for example: Post a message with a button

If such interaction points originate from a custom step execution, the events sent to your app representing the end-user interaction with these points are considered to be _function-scoped interactivity events_. These interactivity events can be handled by your app using the same concepts we covered earlier, such as [Listening to actions](/concepts/action-listening).
If such interaction points originate from a custom step execution, the events sent to your app representing the end-user interaction with these points are considered to be _function-scoped interactivity events_. These interactivity events can be handled by your app using the same concepts we covered earlier, such as [Listening to actions](/concepts/actions).

_function-scoped interactivity events_ will contain data related to the custom step (`function_executed` event) they were spawned from, such as custom step `inputs` and access to `complete()` and `fail()` listener arguments.

Expand Down
File renamed without changes.
28 changes: 28 additions & 0 deletions docs/content/concepts/event-listening.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: Listening to events
lang: en
slug: /concepts/event-listening
---

You can listen to any [Events API event](https://api.slack.com/events) using the `event()` method after subscribing to it in your app configuration. This allows your app to take action when something happens in Slack, like a user reacting to a message or joining a channel.

The `event()` method requires an `eventType` of type string.

```javascript
const welcomeChannelId = 'C12345';

// When a user joins the team, send a message in a predefined channel asking them to introduce themselves
app.event('team_join', async ({ event, client, logger }) => {
try {
// Call chat.postMessage with the built-in client
const result = await client.chat.postMessage({
channel: welcomeChannelId,
text: `Welcome to the team, <@${event.user.id}>! 🎉 You can introduce yourself in this channel.`
});
logger.info(result);
}
catch (error) {
logger.error(error);
}
});
```
File renamed without changes.
File renamed without changes.
56 changes: 56 additions & 0 deletions docs/content/concepts/message-listening.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: Listening to messages
lang: en
slug: /concepts/message-listening
---

To listen to messages that [your app has access to receive](https://api.slack.com/messaging/retrieving#permissions), you can use the `message()` method which filters out events that aren’t of type `message` .A `message()` listener is equivalent to `event('message')`

The `message()` listener accepts an optional `pattern` parameter of type `string` or `RegExp` object which filters out any messages that don’t match the pattern.

```javascript
// This will match any message that contains 👋
app.message(':wave:', async ({ message, say }) => {
// Handle only newly posted messages here
if (message.subtype === undefined
|| message.subtype === 'bot_message'
|| message.subtype === 'file_share'
|| message.subtype === 'thread_broadcast') {
await say(`Hello, <@${message.user}>`);
}
});
```

## Using a RegExp pattern {#using-regexp}

A RegExp pattern can be used instead of a string for more granular matching.

All of the results of the RegExp match will be in `context.matches`.

```javascript
app.message(/^(hi|hello|hey).*/, async ({ context, say }) => {
// RegExp matches are inside of context.matches
const greeting = context.matches[0];

await say(`${greeting}, how are you?`);
});
```

## Filtering on event subtypes {#filtering-event-subtypes}

You can filter on subtypes of events by using the built-in `subtype()` middleware. Common message subtypes like `message_changed` and `message_replied` can be found [on the message event page](https://api.slack.com/events/message#message_subtypes).

```javascript
// Import subtype from the package
const { App, subtype } = require('@slack/bolt');

// Matches all message changes from users
app.message(subtype('message_changed'), ({ event, logger }) => {
// This if statement is required in TypeScript code
if (event.subtype === 'message_changed'
&& !event.message.subtype
&& !event.previous_message.subtype) {
logger.info(`The user ${event.message.user} changed their message from ${event.previous_message.text} to ${event.message.text}`);
}
});
```
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
title: Listening and responding to options
title: Listening & responding to select menu options
lang: en
slug: /concepts/options
---

The `options()` method listens for incoming option request payloads from Slack. [Similar to `action()`](/concepts/action-listening),
The `options()` method listens for incoming option request payloads from Slack. [Similar to `action()`](/concepts/actions),
an `action_id` or constraints object is required.

While it's recommended to use `action_id` for `external_select` menus, dialogs do not yet support Block Kit so you'll have to
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Listening and responding to shortcuts
title: Listening & responding to shortcuts
lang: en
slug: /concepts/shortcuts
---
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Updating and pushing views
title: Updating & pushing views
lang: en
slug: /concepts/updating-pushing-views
---
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ lang: en
slug: /concepts/web-api
---

You can call [any Web API method](https://api.slack.com/methods) using the [`WebClient`](https://tools.slack.dev/node-slack-sdk/web-api) provided to your app's listeners as `client`. This uses either the token that initialized your app **or** the token that is returned from the [`authorize`](/concepts/authorization) function for the incoming event. The built-in [OAuth support](/concepts/authenticating-oauth) handles the second case by default.
You can call any [Web API method](https://api.slack.com/methods) using the [`WebClient`](https://tools.slack.dev/node-slack-sdk/web-api) provided to your app's listeners as `client`. This uses either the token that initialized your app **or** the token that is returned from the [`authorize`](/concepts/authorization) function for the incoming event. The built-in [OAuth support](/concepts/authenticating-oauth) handles the second case by default.

Your Bolt app also has a top-level `app.client` which you can manually pass the `token` parameter. If the incoming request is not authorized or you're calling a method from outside of a listener, use the top-level `app.client`.

Expand Down
Loading

0 comments on commit d3fe549

Please sign in to comment.