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: concept focused nav #2302

Merged
merged 9 commits into from
Oct 29, 2024
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
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}>`);
}
});
```
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.
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
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.
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.
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.
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
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