Skip to content

Commit dcccf9d

Browse files
authored
docs: add JSDoc to and list out all available builtin middleware functions in the docs (#2136)
* docs: add JSDoc to and list out all available builtin middleware functions in the docs. * split up docs on built-in middleware into global vs. listener middleware lists.
1 parent 0f9326e commit dcccf9d

File tree

4 files changed

+56
-7
lines changed

4 files changed

+56
-7
lines changed

docs/_advanced/middleware_global.md

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@ order: 5
66
---
77

88
<div class="section-content">
9-
Global middleware is run for all incoming requests before any listener middleware. You can add any number of global middleware to your app by utilizing `app.use(fn)`. The middleware function `fn` is called with the same arguments as listeners and an additional `next` function.
9+
Global middleware is run for all incoming requests before any [listener middleware](#listener-middleware). You can add any number of global middleware to your app by utilizing `app.use(fn)`. The middleware function `fn` is called with the same arguments as listeners and an additional `next` function.
1010

11-
Both global and listener middleware must call `await next()` to pass control of the execution chain to the next middleware, or call `throw` to pass an error back up the previously-executed middleware chain.
11+
Both global and [listener middleware](#listener-middleware) must call `await next()` to pass control of the execution chain to the next middleware, or call `throw` to pass an error back up the previously-executed middleware chain.
1212

1313
As an example, let's say your app should only respond to users identified with a corresponding internal authentication service (an SSO provider or LDAP, for example). You may define a global middleware that looks up a user record in the authentication service and errors if the user is not found.
14-
15-
*Note: Since v2, global middleware was updated to support `async` functions! View the [migration guide for V2](https://slack.dev/bolt/tutorial/migration-v2) to learn about the changes.*
1614
</div>
1715

1816
```javascript

docs/_advanced/middleware_listener.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@ order: 6
88
<div class="section-content">
99
Listener middleware is used for logic across many listener functions (but usually not all of them). They are added as arguments before the listener function in one of the built-in methods. You can add any number of listener middleware before the listener function.
1010

11-
There’s a collection of built-in listener middleware that you can use like `subtype()` for filtering on a message subtype and `directMention()` which filters out any message that doesn’t directly @-mention your bot at the start of a message.
11+
There’s a collection of [built-in listener middleware](reference#built-in-listener-middleware-functions) that you can use like `directMention` which filters out any message that doesn’t directly @-mention your bot at the start of a message.
1212

1313
But of course, you can write your own middleware for more custom functionality. While writing your own middleware, your function must call `await next()` to pass control to the next middleware, or `throw` to pass an error back up the previously-executed middleware chain.
1414

1515
As an example, let’s say your listener should only deal with messages from humans. You can write a listener middleware that excludes any bot messages.
16-
17-
*Note: Since v2, listener middleware was updated to support `async` functions! View the [migration guide for V2](https://slack.dev/bolt/tutorial/migration-v2) to learn about the changes.*
1816
</div>
1917

2018
```javascript

docs/_tutorials/reference.md

+40
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ This guide is intended to detail the Bolt interface–including listeners and th
1919
- [Listener function arguments](#listener-function-arguments)
2020
- [Body and payload references](#body-and-payload-references)
2121
- [Difference from listener middleware](#difference-from-listener-middleware)
22+
- [Built-in middleware functions](#built-in-listener-functions)
23+
- [Built-in global middleware functions](#built-in-global-middleware-functions)
24+
- [Built-in listener middleware functions](#built-in-listener-middleware-functions)
2225
- [Initialization options](#initialization-options)
2326
- [Receiver options](#receiver-options)
2427
- [App options](#app-options)
@@ -79,6 +82,43 @@ The structure of the `payload` and `body` is detailed on the API site:
7982
### Difference from listener middleware
8083
Listener middleware is used to implement logic across many listener functions (though usually not all of them). Listener middleware has the same arguments as the above listener functions, with one distinction: they also have a `next()` function that **must** be called in order to pass the chain of execution. Learn more about listener middleware [in the documentation](/bolt-js/concepts#listener-middleware).
8184

85+
## Built-in middleware functions
86+
87+
Bolt offers a variety of built-in middleware functions to help simplify development of your Slack applications. These middleware functions implement common patterns to help filter out or focus your own listener function implementations.
88+
89+
These middleware functions are exported from the main `@slack/bolt` package for you to easily `import` in your applications:
90+
91+
```javascript
92+
import { matchMessage } from '@slack/bolt';
93+
app.message(matchMessage('hello'), async ({ message, logger }) => {
94+
// this function will now only execute if "hello" is present in the message
95+
});
96+
```
97+
98+
These middleware functions are divided into two groups: [global middleware functions](concepts#global-middleware) and [listener middleware functions](concepts#listener-middleware).
99+
100+
### Built-in global middleware functions
101+
102+
- `ignoreSelf()`: Filters out any event that originates from the app. Note that this middleware is enabled by default via the [`ignoreSelf` App initialization options](#app-options).
103+
- `onlyActions`: Filters out any event that isn't an action.
104+
- `onlyCommands`: Filters out any event that isn't a command.
105+
- `onlyEvents`: Allows for only events to propagate down the middleware chain.
106+
- `onlyOptions`: Filters out any event that isn't a drop-down-options event.
107+
- `onlyShortcuts`: Filters out any event that isn't a shortcut.
108+
- `onlyViewActions`: Filters out any event that isn't a `view_submission` or `view_closed` event.
109+
110+
### Built-in listener middleware functions
111+
112+
- `directMention()`: Filters out any `message` event whose text does not start with an @-mention of the handling app.
113+
- `matchCommandName(pattern)`: Filters out any shortcut command whose name does not match the provided `pattern`; `pattern` can be a string or regular expression.
114+
- `matchConstraints(constraint)`: Filters out any `block_action`, View or Options event that does not match the properties of the provided `constraint` object. Supported `constraint` object properties include:
115+
- `block_id` and `action_id`: for filtering out `block_action` events that do not match the provided IDs.
116+
- `callback_id`: for filtering out `view_*` events not matching the provided `callback_id`.
117+
- `type`: for filtering out any event `type`s not matching the provided `type`.
118+
- `matchEventType(pattern)`: filters out any event whose `type` does not match the provided `pattern`. `pattern` can be a string or regular expression.
119+
- `matchMessage(pattern)`: filters out any `message` or `app_mention` events whose message contents do not match the provided `pattern`. `pattern` can be a string or regular expression.
120+
- `subtype(type)`: Filters out any `message` event whose `subtype` does not exactly equal the provided `type`.
121+
82122
## Initialization options
83123
Bolt includes a collection of initialization options to customize apps. There are two primary kinds of options: Bolt app options and receiver options. The receiver options may change based on the receiver your app uses. The following receiver options are for the default `HTTPReceiver` (so they'll work as long as you aren't using a custom receiver).
84124

src/middleware/builtin.ts

+13
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,11 @@ export function matchEventType(pattern: EventTypePattern): Middleware<SlackEvent
288288
};
289289
}
290290

291+
// TODO: breaking change: why does this method have to be invoked as a function with no args, while other similar
292+
// method like the `only*` ones do not require that? should make this consistent.
293+
/**
294+
* Filters out any event originating from the handling app.
295+
*/
291296
export function ignoreSelf(): Middleware<AnyMiddlewareArgs> {
292297
return async (args) => {
293298
const botId = args.context.botId as string;
@@ -321,6 +326,9 @@ export function ignoreSelf(): Middleware<AnyMiddlewareArgs> {
321326
};
322327
}
323328

329+
/**
330+
* Filters out any message events whose subtype does not match the provided subtype.
331+
*/
324332
export function subtype(subtype1: string): Middleware<SlackEventMiddlewareArgs<'message'>> {
325333
return async ({ message, next }) => {
326334
if (message.subtype === subtype1) {
@@ -331,6 +339,11 @@ export function subtype(subtype1: string): Middleware<SlackEventMiddlewareArgs<'
331339

332340
const slackLink = /<(?<type>[@#!])?(?<link>[^>|]+)(?:\|(?<label>[^>]+))?>/;
333341

342+
// TODO: breaking change: why does this method have to be invoked as a function with no args, while other similar
343+
// method like the `only*` ones do not require that? should make this consistent.
344+
/**
345+
* Filters out any message event whose text does not start with an @-mention of the handling app.
346+
*/
334347
export function directMention(): Middleware<SlackEventMiddlewareArgs<'message'>> {
335348
return async ({ message, context, next }) => {
336349
// When context does not have a botUserId in it, then this middleware cannot perform its job. Bail immediately.

0 commit comments

Comments
 (0)