Migrating to V4
This guide will walk you through the process of updating your app from using @slack/bolt@3.x
to @slack/bolt@4.x
. There may be a few changes you'll need to make depending on which features you use, but for most apps, these changes can be applied in a few minutes. Some apps may need no changes at all.
🚨 Breaking Changes
- ⬆️ Support for node v14 and v16 have been officially dropped, as these node versions have been EOL'ed.
- 🚥
*MiddlewareArgs
interfaces, modeling middleware arguments for different kinds of Slack event payloads processed by bolt apps, have been improved. - 🌐 The Web API client,
@slack/web-api
, has been upgraded from v6 to v7. - 🔌 The Socket Mode handler package,
@slack/socket-mode
, has been upgraded from v1 to v2. - 🚅 For those using the
ExpressReceiver
,express
has been upgraded from v4 to v5. - 🍽️ The
@slack/types
package is no longer exported without a namespace; it is now exported under the namedtypes
export. - 🧘 The
SocketModeFunctions
class with a single static method instead now directly exports the singledefaultProcessEventErrorHandler
method from it. - 🏭 Some of the built-in middleware functions like
ignoreSelf
anddirectMention
have had their APIs changed to create a consistent middleware style. - 🌩️ The
AwsEvent
interface has changed. - 🧹 Deprecated methods, modules and properties in v3 were removed.
✨ Other Changes
- 🚳 Steps From Apps related types, methods and constants were marked as deprecated.
- 📦 The
@slack/web-api
package leveraged within bolt-js is now exported under thewebApi
namespace.
⬆️ Minimum Node version
@slack/bolt@4.x
requires a minimum Node version of 18
and minimum npm version of 8.6.0
.
🚥 Changes to middleware argument types
This change primarily applies to TypeScript users.
Many middleware argument types, for example the SlackEventMiddlewareArgs
type, previously used a conditional to sometimes define particular additional helper utilities on the middleware arguments. For example, the say
utility, or tacking on a convenience message
property for message-event-related payloads. This was problematic: when the payload was not of a type that required the extra utility, these properties would be required to exist on the middleware arguments but have a type of undefined
. Those of us trying to build generic middleware utilities would have to deal with TypeScript compilation errors and needing to liberally type-cast to avoid these conditional mismatches with undefined
.
Instead, these MiddlewareArgs
types now conditionally create a type intersection when appropriate in order to provide this conditional-utility-extension mechanism. That looks something like:
type SomeMiddlewareArgs<EventType extends string = string> = {
// some type in here
} & (EventType extends 'message'
// If this is a message event, add a `message` property
? { message: EventFromType<EventType> }
: unknown
)
With the above, now when a message payload is wrapped in middleware arguments, it will contain an appropriate message
property, whereas a non-message payload will be intersected with unknown
- effectively a type "noop." No more e.g. say: undefined
or message: undefined
to deal with!