-
Notifications
You must be signed in to change notification settings - Fork 678
Docs: migration guides for new package versions #2606
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
Open
lukegalbraithrussell
wants to merge
11
commits into
v8
Choose a base branch
from
docs-package-migration
base: v8
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
bbb5d76
go
lukegalbraithrussell 83ca6ee
go
lukegalbraithrussell 8357991
go
lukegalbraithrussell 3a5486a
go
lukegalbraithrussell ce3fbda
go
lukegalbraithrussell 308e662
go
lukegalbraithrussell 9c2f52a
sidebar
lukegalbraithrussell ced8131
Apply suggestions from code review
lukegalbraithrussell 171eef1
Apply suggestions from code review
lukegalbraithrussell a5f630c
go
lukegalbraithrussell 35aac2f
Merge branch 'docs-package-migration' of https://github.com/slackapi/…
lukegalbraithrussell File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # Migrating packages | ||
|
|
||
| The Node Slack SDK exists as a single repo containing a confederation of independent packages (`@slack/web-api`, `@slack/webhook`, `@slack/socket-mode`, etc.). Each package can be upgraded independently on its own schedule. | ||
|
|
||
| :::tip[For info on how long each Node version is supported, see the [support schedule](/tools/node-slack-sdk/support-schedule).] | ||
| ::: | ||
|
|
||
| ## Legacy migration guides | ||
|
|
||
| The **Legacy** section contains migration guides for old major versions of the Node Slack SDK. These guides reflect an outdated approach where all packages in the SDK were released together as a coordinated release. Today, each package evolves independently. For example, the `@slack/web-api` package may be at v8 while `@slack/socket-mode` may be at v3. | ||
|
|
||
| If you're upgrading from very old versions, the legacy guides provide historical context, but you'll likely want to follow the package-specific guides below for current migrations. | ||
|
|
6 changes: 5 additions & 1 deletion
6
...on/migrating-socket-mode-package-to-v2.md → ...de/migrating-socket-mode-package-to-v2.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
257 changes: 257 additions & 0 deletions
257
docs/english/migration/socket-mode/migrating-socket-mode-package-to-v3.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,257 @@ | ||
| --- | ||
| sidebar_label: Migrating to v3 | ||
| --- | ||
|
|
||
| # Migrating the `socket-mode` package from v2 to v3 | ||
|
|
||
| _Minimum Node.js version: 20_ | ||
|
|
||
| This major release switches from the [`ws`](https://www.npmjs.com/package/ws) library to the [`undici`](https://undici.nodejs.org/) library's [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) implementation. | ||
|
|
||
| If you're not using a proxy or custom TLS, we hope no action is needed beyond bumping the version number. | ||
|
|
||
| The main thing you'll notice: `httpAgent` is gone. You'll use a `dispatcher` option instead, which handles both WebSocket connections and HTTP API calls in one place. Or, if you're on a recent Node.js version, you can set an environment variable and skip manual proxy config entirely. | ||
|
|
||
|
|
||
| ## Installation | ||
|
|
||
| ``` | ||
| npm i @slack/socket-mode | ||
| ``` | ||
|
|
||
| ## Breaking changes | ||
|
|
||
| ### We've removed the `httpAgent` option | ||
|
|
||
| **Before (v2):** | ||
|
|
||
| ```typescript | ||
| import { SocketModeClient } from '@slack/socket-mode'; | ||
| import { HttpsProxyAgent } from 'https-proxy-agent'; | ||
|
|
||
| const agent = new HttpsProxyAgent('http://corporate.proxy:8080'); | ||
|
|
||
| const client = new SocketModeClient({ | ||
| appToken: process.env.SLACK_APP_TOKEN, | ||
| httpAgent: agent, | ||
| }); | ||
| ``` | ||
|
|
||
| #### Preferred: Built-in proxy support | ||
|
|
||
| Node.js can read your proxy environment variables (`HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`) and route traffic automatically via [`http.setGlobalProxyFromEnv()`](https://nodejs.org/docs/latest/api/http.html#httpsetglobalproxyfromenvproxyenv). Both WebSocket and HTTP traffic respect this. | ||
|
|
||
| ##### Option A: programmatically call once at startup | ||
|
|
||
| ```typescript | ||
| import http from 'node:http'; | ||
| import { SocketModeClient } from '@slack/socket-mode'; | ||
|
|
||
| http.setGlobalProxyFromEnv(); | ||
|
|
||
| // Both WebSocket and HTTP API calls route through the proxy automatically | ||
| const client = new SocketModeClient({ | ||
| appToken: process.env.SLACK_APP_TOKEN, | ||
| }); | ||
| ``` | ||
|
|
||
| ##### Option B: use an environment variable | ||
|
|
||
| ```bash | ||
| NODE_USE_ENV_PROXY=1 HTTPS_PROXY=http://corporate.proxy:8080 node app.js | ||
| ``` | ||
|
|
||
| ```typescript | ||
| import { SocketModeClient } from '@slack/socket-mode'; | ||
|
|
||
| // No proxy configuration needed — both WebSocket and HTTP use the proxy | ||
| const client = new SocketModeClient({ | ||
| appToken: process.env.SLACK_APP_TOKEN, | ||
| }); | ||
| ``` | ||
|
|
||
| #### Alternative: use the undici `dispatcher` | ||
|
|
||
| If you need per-client proxy configuration or separate WebSocket vs HTTP proxy routing, use the `dispatcher` option with an undici `Dispatcher` (like `ProxyAgent` or `Agent`). | ||
|
|
||
| The `dispatcher` is used for both WebSocket connections and HTTP API calls (via the internal `WebClient`): | ||
|
|
||
| ```typescript | ||
| import { SocketModeClient } from '@slack/socket-mode'; | ||
| import { ProxyAgent } from 'undici'; | ||
|
|
||
| const dispatcher = new ProxyAgent('http://corporate.proxy:8080'); | ||
|
|
||
| const client = new SocketModeClient({ | ||
| appToken: process.env.SLACK_APP_TOKEN, | ||
| dispatcher, | ||
| }); | ||
| ``` | ||
|
|
||
|
|
||
| --- | ||
|
|
||
| ### We've updated the dependency on `@slack/web-api@^8` | ||
|
|
||
| This package now uses `@slack/web-api@^8` internally. If you're passing `clientOptions`, the web-api breaking changes apply there too. Check the [web-api v8 migration guide](./web-api-v8-migration.md) for details. | ||
|
|
||
| ```diff | ||
| const client = new SocketModeClient({ | ||
| appToken: process.env.SLACK_APP_TOKEN, | ||
| clientOptions: { | ||
| - agent: myAgent, | ||
| - tls: { cert, key }, | ||
| + fetch: (url, init) => fetch(url, { ...init, dispatcher }), | ||
| }, | ||
| }); | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### We've removed the `ws` library and added the `undici@^7` library. | ||
|
|
||
| Learn more about the `undici` library [here](https://www.npmjs.com/package/undici). | ||
|
|
||
| --- | ||
|
|
||
| ### We've raised the minimum Node.js version to 20 | ||
|
|
||
| We've dropped support for Node.js 18. Node.js 20 or later is required. | ||
|
|
||
| --- | ||
|
|
||
| ### We've overhauled error handling | ||
|
|
||
| Errors are now proper `Error` subclasses instead of interfaces. This means `instanceof` checks work, TypeScript narrows types correctly, and error names are descriptive. | ||
|
|
||
| **Your existing `error.code` checks still work.** The `ErrorCode` enum values are unchanged. But `instanceof` is now the recommended pattern. | ||
|
|
||
| #### New error classes | ||
|
|
||
| | Class | When it's thrown | | ||
| | --- | --- | | ||
| | `SMWebsocketError` | WebSocket connection or protocol failure | | ||
| | `SMPlatformError` | Slack API returned an error (e.g., `apps.connections.open` failed) | | ||
| | `SMNoReplyReceivedError` | Server didn't acknowledge a message in time | | ||
| | `SMSendWhileDisconnectedError` | Attempted to send while the WebSocket is disconnected | | ||
| | `SMSendWhileNotReadyError` | Attempted to send before the client is fully ready | | ||
|
|
||
| #### How `instanceof` checks work | ||
|
|
||
| **Before (v2):** | ||
|
|
||
| ```typescript | ||
| import { SocketModeClient, ErrorCode } from '@slack/socket-mode'; | ||
|
|
||
| const client = new SocketModeClient({ appToken: process.env.SLACK_APP_TOKEN }); | ||
|
|
||
| client.on('error', (error) => { | ||
| if (error.code === ErrorCode.SendWhileDisconnectedError) { | ||
| console.log('Not connected, will retry...'); | ||
| } else if (error.code === ErrorCode.WebsocketError) { | ||
| console.log('WebSocket issue:', error.message); | ||
| } | ||
| }); | ||
| ``` | ||
|
|
||
| **After (v3):** | ||
|
|
||
| ```typescript | ||
| import { | ||
| SocketModeClient, | ||
| SMSendWhileDisconnectedError, | ||
| SMWebsocketError, | ||
| } from '@slack/socket-mode'; | ||
|
|
||
| const client = new SocketModeClient({ appToken: process.env.SLACK_APP_TOKEN }); | ||
|
|
||
| client.on('error', (error) => { | ||
| if (error instanceof SMSendWhileDisconnectedError) { | ||
| console.log('Not connected, will retry...'); | ||
| } else if (error instanceof SMWebsocketError) { | ||
| console.log('WebSocket issue:', error.cause); | ||
| } | ||
| }); | ||
| ``` | ||
|
|
||
| The `error.code` pattern still works if you prefer not to change your error handling: | ||
|
|
||
| ```typescript | ||
| import { SocketModeClient, ErrorCode } from '@slack/socket-mode'; | ||
|
|
||
| const client = new SocketModeClient({ appToken: process.env.SLACK_APP_TOKEN }); | ||
|
|
||
| client.on('error', (error) => { | ||
| if (error.code === ErrorCode.SendWhileDisconnectedError) { | ||
| console.log('Not connected, will retry...'); | ||
| } | ||
| }); | ||
| ``` | ||
|
|
||
| #### `error.name` values changed | ||
|
|
||
| | Error class | v2 `error.name` | v3 `error.name` | | ||
| | --- | --- | --- | | ||
| | `SMWebsocketError` | `'Error'` | `'SMWebsocketError'` | | ||
| | `SMPlatformError` | `'Error'` | `'SMPlatformError'` | | ||
| | `SMNoReplyReceivedError` | `'Error'` | `'SMNoReplyReceivedError'` | | ||
| | `SMSendWhileDisconnectedError` | `'Error'` | `'SMSendWhileDisconnectedError'` | | ||
| | `SMSendWhileNotReadyError` | `'Error'` | `'SMSendWhileNotReadyError'` | | ||
|
|
||
| If your logging or error monitoring tools filter on `error.name`, update those filters. | ||
|
|
||
| --- | ||
|
|
||
| ## New features | ||
|
|
||
| ### `dispatcher` option for unified proxy/TLS configuration | ||
|
|
||
| :::tip[You can skip manual dispatcher configuration entirely by using `http.setGlobalProxyFromEnv()` or `NODE_USE_ENV_PROXY=1`] | ||
| See [the `httpAgent` option removed section](#we-removed-the-httpagent-option) above for more detail. | ||
| ::: | ||
|
|
||
| Pass any undici `Dispatcher` and it'll handle both WebSocket and HTTP traffic: | ||
|
|
||
| ```typescript | ||
| import { SocketModeClient, LogLevel } from '@slack/socket-mode'; | ||
| import { ProxyAgent } from 'undici'; | ||
|
|
||
| const dispatcher = new ProxyAgent('http://corporate.proxy:8080'); | ||
|
|
||
| const client = new SocketModeClient({ | ||
| appToken: process.env.SLACK_APP_TOKEN, | ||
| logLevel: LogLevel.DEBUG, | ||
| dispatcher, | ||
| }); | ||
|
|
||
| client.on('message', async ({ event, ack }) => { | ||
| await ack(); | ||
| console.log(event); | ||
| }); | ||
|
|
||
| await client.start(); | ||
| ``` | ||
|
|
||
| ### Separate dispatchers for WebSocket and HTTP traffic | ||
|
|
||
| For advanced cases where WebSocket and HTTP traffic need different proxy configurations: | ||
|
|
||
| ```typescript | ||
| import { SocketModeClient } from '@slack/socket-mode'; | ||
| import { fetch, ProxyAgent } from 'undici'; | ||
|
|
||
| const wsProxy = new ProxyAgent('http://ws-proxy:8080'); | ||
| const httpProxy = new ProxyAgent('http://http-proxy:9090'); | ||
|
|
||
| const client = new SocketModeClient({ | ||
| appToken: process.env.SLACK_APP_TOKEN, | ||
| // WebSocket connections use this dispatcher | ||
| dispatcher: wsProxy, | ||
| clientOptions: { | ||
| // HTTP API calls use a separate custom fetch | ||
| fetch: (url, init) => fetch(url, { ...init, dispatcher: httpProxy }), | ||
| }, | ||
| }); | ||
| ``` | ||
|
|
||
| When you provide `clientOptions.fetch`, the `dispatcher` only handles WebSocket connections; HTTP calls go through your custom fetch instead. | ||
10 changes: 6 additions & 4 deletions
10
...ration/migrating-web-api-package-to-v7.md → ...eb-api/migrating-web-api-package-to-v7.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.