Skip to content

Releases: slackapi/node-slack-sdk

@slack/[email protected]

25 Nov 21:28
5d4092a

Choose a tag to compare

What's Changed

👾 Enhancements

🍿 Expand for a slackLists API method example
 const list = await app.client.slackLists.create({
      name: 'Test List - SlackLists API',
      description_blocks: [
        {
          type: 'rich_text',
          elements: [
            {
              type: 'rich_text_section',
              elements: [
                {
                  type: 'text',
                  text: 'List to keep track of tasks!',
                },
              ],
            },
          ],
        },
      ],
      schema: [
        {
          key: 'task_name',
          name: 'Task Name',
          type: 'text',
          is_primary_column: true,
        },
        {
          key: 'due_date',
          name: 'Due Date',
          type: 'date',
        },
        {
          key: 'status',
          name: 'Status',
          type: 'select',
          options: {
            choices: [
              { value: 'not_started', label: 'Not Started', color: 'red' },
              { value: 'in_progress', label: 'In Progress', color: 'yellow' },
              { value: 'completed', label: 'Completed', color: 'green' },
            ],
          },
        },
        {
          key: 'assignee',
          name: 'Assignee',
          type: 'user',
        },
      ],
    });
    console.log('List created:', list);
    const listId = list.list_id;

    // extract column IDs from the response (map key -> id)
    const keyToId = {};
    if (list.list_metadata?.schema) {
      for (const col of list.list_metadata.schema) {
        keyToId[col.key] = col.id;
      }
    }
    const taskNameColId = keyToId['task_name'];
    console.log('Column IDs:', keyToId);

    const response = await app.client.slackLists.access.set({
      list_id: listId,
      access_level: 'write',
      user_ids: ['U09G4FG3TRN'],
    });
    console.log('Access set:', response);

    const createItemResponse = await app.client.slackLists.items.create({
      list_id: listId,
      initial_fields: [
        {
          column_id: taskNameColId,
          rich_text: [
            {
              type: 'rich_text',
              elements: [
                {
                  type: 'rich_text_section',
                  elements: [
                    {
                      type: 'text',
                      text: 'CLI app unlink command',
                    },
                  ],
                },
              ],
            },
          ],
        },
      ],
    });
    console.log('Item created:', createItemResponse);
    const itemId = createItemResponse.id;

    if (itemId) {
      await app.client.slackLists.items.info({
        list_id: listId,
        id: itemId,
        include_is_subscribed: true,
      });
      console.log('Item info retrieved');

      await app.client.slackLists.items.update({
        list_id: listId,
        cells: [
          {
            row_id: itemId,
            column_id: taskNameColId,
            checkbox: true,
          },
        ],
      });
      console.log('Item updated');
    }

    const listItemsResponse = await app.client.slackLists.items.list({
      list_id: listId,
      limit: 50,
    });
    console.log('Items listed:', listItemsResponse);

    const downloadStartResponse = await app.client.slackLists.download.start({
      list_id: listId,
      include_archived: false,
    });
    console.log('Download started:', downloadStartResponse);
    const jobId = downloadStartResponse.job_id;

    if (jobId) {
      await app.client.slackLists.download.get({
        list_id: listId,
        job_id: jobId,
      });
      console.log('Download status retrieved');
    }

    if (itemId) {
      await app.client.slackLists.items.delete({
        list_id: listId,
        id: itemId,
      });
      console.log('Item deleted');
    }

    await app.client.slackLists.items.deleteMultiple({
      list_id: listId,
      ids: ['item1', 'item2'],
    });
    console.log('Multiple items deleted');

    await app.client.slackLists.access.delete({
      list_id: listId,
      user_ids: ['U09G4FG3TRN'],
    });
    console.log('Access removed');

📚 Documentation

🧰 Maintenance

New Contributors

Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/[email protected]...@slack/[email protected]
Milestone: https://github.com/slackapi/node-slack-sdk/milestone/159
npm Release: https://www.npmjs.com/package/@slack/web-api/v/7.13.0

@slack/[email protected]

21 Nov 23:32
533acb2

Choose a tag to compare

What's Changed

👾 Enhancements

feat(types): add underline to rich text section block element in #2414 - Thanks @zimeg!
feat(types): add table block in #2426 - Thanks @zimeg!
feat(types): update work object types in #2431 - Thanks @vegeris!

📚 Documentation

docs: link to streaming methods and context actions block reference in #2429 - Thanks @zimeg!
docs(types): remove note of maximum length for raw_text in #2440 - Thanks @zimeg!

🧰 Maintenance

chore(types): release @slack/[email protected] in #2441 - Thanks @mwbrooks!

Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/[email protected]...@slack/[email protected]
Milestone: https://github.com/slackapi/node-slack-sdk/milestone/158?closed=1
npm Release: https://www.npmjs.com/package/@slack/types/v/2.19.0

@slack/[email protected]

03 Nov 18:55
9e73506

Choose a tag to compare

What's Changed

👾 Enhancements

  • feat: add support to @slack/web-api for work objects by @vegeris in #2231
  • web-api(fix): Update SearchMessagesArguments to support cursor pagination by @vegeris in #2361

🧰 Maintenance

📚 Changelog
https://docs.slack.dev/changelog/2025/10/22/work-objects/

Package: https://www.npmjs.com/package/@slack/[email protected]
Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/[email protected]...@slack/[email protected]
Milestone: https://github.com/slackapi/node-slack-sdk/milestone/156?closed=1

@slack/[email protected]

03 Nov 18:45
7c60024

Choose a tag to compare

@slack/[email protected]

07 Oct 04:11
ff03f78

Choose a tag to compare

AI-Enabled Features: Loading States, Text Streaming, and Feedback Buttons

🍿 Preview

2025-10-06-loading-state-text-streaming-feedback.mov

📚 Changelog

⚡ Getting Started

Try the AI Agent Sample app to explore the AI-enabled features and existing Assistant helper:

# Create a new AI Agent app
$ slack create slack-ai-agent-app --template slack-samples/bolt-js-assistant-template
$ cd slack-ai-agent-app/

# Add your OPENAI_API_KEY
$ export OPENAI_API_KEY=sk-proj-ahM...

# Run the local dev server
$ slack run

After the app starts, send a message to the "slack-ai-agent-app" bot for a unique response.

⌛ Loading States

Loading states allows you to not only set the status (e.g. "My app is typing...") but also sprinkle some personality by cycling through a collection of loading messages:

app.event('message', async ({ client, context, event, logger }) => {
    // ...
    await client.assistant.threads.setStatus({
        channel_id: channelId,
        thread_ts: threadTs,
        status: 'thinking...',
        loading_messages: [
            'Teaching the hamsters to type faster…',
            'Untangling the internet cables…',
            'Consulting the office goldfish…',
            'Polishing up the response just for you…',
            'Convincing the AI to stop overthinking…',
        ],
    });

    // Start a new message stream
});

🔮 Text Streaming Helper

The client.chatStream() helper utility can be used to streamline calling the 3 text streaming methods:

app.event('message', async ({ client, context, event, logger }) => {
    // ...

    // Start a new message stream
    const streamer = client.chatStream({
        channel: channelId,
        recipient_team_id: teamId,
        recipient_user_id: userId,
        thread_ts: threadTs,
    });

    // Loop over OpenAI response stream
    // https://platform.openai.com/docs/api-reference/responses/create
    for await (const chunk of llmResponse) {
        if (chunk.type === 'response.output_text.delta') {
            await streamer.append({
                markdown_text: chunk.delta,
            });
        }
    }

    // Stop the stream and attach feedback buttons
    await streamer.stop({ blocks: [feedbackBlock] });
});

🔠 Text Streaming Methods

Alternative to the Text Streaming Helper is to call the individual methods.

1) client.chat.startStream

First, start a chat text stream to stream a response to any message:

app.event('message', async ({ client, context, event, logger }) => {
    // ...
    const streamResponse = await client.chat.startStream({
        channel: channelId,
        recipient_team_id: teamId,
        recipient_user_id: userId,
        thread_ts: threadTs,
    });

    const streamTs = streamResponse.ts

2) client.chat.appendStream

After starting a chat text stream, you can then append text to it in chunks (often from your favourite LLM SDK) to convey a streaming effect:

for await (const chunk of llmResponse) {
    if (chunk.type === 'response.output_text.delta') {
        await client.chat.appendSteam({
            channel: channelId,
            markdown_text: chunk.delta,
            ts: streamTs,
        });
    }
}

3) client.chat.stopStream

Lastly, you can stop the chat text stream to finalize your message:

await client.chat.stopStream({
    blocks: [feedbackBlock],
    channel: channelId,
    ts: streamTs,
});

👍🏻 Feedback Buttons

Add feedback buttons to the bottom of a message, after stopping a text stream, to gather user feedback:

const feedbackBlock = {
    type: 'context_actions',
    elements: [{
        type: 'feedback_buttons',
        action_id: 'feedback',
        positive_button: {
            text: { type: 'plain_text', text: 'Good Response' },
            accessibility_label: 'Submit positive feedback on this response',
            value: 'good-feedback',
        },
        negative_button: {
            text: { type: 'plain_text', text: 'Bad Response' },
            accessibility_label: 'Submit negative feedback on this response',
            value: 'bad-feedback',
        },
    }],
};

// Using the Text Streaming Helper
await streamer.stop({ blocks: [feedbackBlock] });
// Or, using the Text Streaming Method
await client.chat.stopStream({
    blocks: [feedbackBlock],
    channel: channelId,
    ts: streamTs,
});

What's Changed

👾 Enhancements

  • feat: add ai-enabled features text streaming methods, feedback blocks, and loading state in #2399 - Thanks @zimeg!

📚 Documentation

  • docs: update package homepage to docs.slack.dev tools reference in #2369 - Thanks @zimeg!
  • docs: autogenerate package reference to language specific paths in #2337 - Thanks @zimeg!

🤖 Dependencies

🧰 Maintenance

Milestone: https://github.com/slackapi/node-slack-sdk/milestone/147?closed=1
Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/[email protected]...@slack/[email protected]
Package: https://www.npmjs.com/package/@slack/web-api/v/7.11.0

@slack/[email protected]

07 Oct 04:10
fa52a28

Choose a tag to compare

What's Changed

👾 Enhancements

  • feat: add ai-enabled features text streaming methods, feedback blocks, and loading state in #2399 - Thanks @zimeg!

📚 Documentation

  • docs: autogenerate package reference to language specific paths in #2337 - Thanks @zimeg!
  • docs: update package homepage to docs.slack.dev tools reference in #2369 - Thanks @zimeg!

🧰 Maintenance

Milestone: https://github.com/slackapi/node-slack-sdk/milestone/149?closed=1
Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/[email protected]...@slack/[email protected]
Package: https://www.npmjs.com/package/@slack/types/v/2.17.0

@slack/[email protected]+cli.2.32.2

27 Aug 19:16
06a3dcf

Choose a tag to compare

What's Changed

This release adds the version command to Slack CLI testing utilities for testing the output of the version command.

👾 Enhancements

  • feat(cli-test): add version command in #2353 - Thanks @zimeg!

📚 Documentation

🤖 Dependencies

  • chore(deps-dev): bump @biomejs/biome to v2 for all packages in #2281 - Thanks @mwbrooks!
  • chore(deps-dev): bump @types/node from 22.15.32 to 24.0.3 in /packages/cli-test in #2262 - Thanks @dependabot!
  • chore(deps-dev): bump cross-env from 7.0.3 to 10.0.0 in /packages/cli-test in #2325 - Thanks @dependabot!
  • chore(deps-dev): bump shx from 0.3.4 to 0.4.0 in /packages/cli-test in #2181 - Thanks @dependabot!
  • chore(deps-dev): bump sinon from 19.0.5 to 20.0.0 in /packages/cli-test in the dev-sinon group in #2199 - Thanks @dependabot!
  • chore(deps-dev): bump sinon from 20.0.0 to 21.0.0 in /packages/cli-test in the dev-sinon group in #2264 - Thanks @dependabot!
  • chore(deps-dev): bump typescript from 5.7.3 to 5.8.2 in /packages/cli-test in #2160 - Thanks @dependabot!
  • chore(deps-dev): bump typescript from 5.8.2 to 5.8.3 in /packages/cli-test in #2224 - Thanks @dependabot!
  • chore(deps-dev): bump typescript from 5.8.3 to 5.9.2 in /packages/cli-test in #2324 - Thanks @dependabot!

🧰 Maintenance

Package: https://www.npmjs.com/package/@slack/cli-test/v/2.2.0
Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/[email protected]+cli.2.32.2...@slack/[email protected]+cli.2.32.2
Milestone: https://github.com/slackapi/node-slack-sdk/milestone/136?closed=1

@slack/[email protected]

25 Aug 21:09
dab6705

Choose a tag to compare

What's Changed

This release updates internal dependencies to use more secure versions 🔏

📚 Documentation

🤖 Dependencies

  • chore(socket-mode): bump @slack/web-api to 7.10.0 in #2343 - Thanks @zimeg!
  • chore(deps-dev): bump typescript from 5.7.3 to 5.8.3 in /packages/socket-mode in #2163 - Thanks @dependabot!
  • chore(deps-dev): bump sinon from 20.0.0 to 21.0.0 in /packages/socket-mode in the dev-sinon group in #2263 - Thanks @dependabot!
  • chore(deps-dev): bump @biomejs/biome to v2 for all packages in #2281 - Thanks @mwbrooks!
  • chore(deps-dev): bump typescript from 5.8.3 to 5.9.2 in /packages/socket-mode in #2326 - Thanks @dependabot!

🧰 Maintenance

Package: https://www.npmjs.com/package/@slack/socket-mode/v/2.0.5
Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/[email protected]...@slack/[email protected]
Milestone: https://github.com/slackapi/node-slack-sdk/milestone/87?closed=1

@slack/[email protected]

25 Aug 21:20
18c4af4

Choose a tag to compare

What's Changed

This release updates internal dependencies to use more secure versions 🔏

📚 Documentation

🤖 Dependencies

  • chore(rtm-api): bump @slack/web-api to 7.10.0 in #2342 - Thanks @zimeg!
  • chore(deps-dev): bump @biomejs/biome to v2 for all packages in #2281 - Thanks @mwbrooks!

🧰 Maintenance

Package: https://www.npmjs.com/package/@slack/rtm-api/v/7.0.4
Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/[email protected]...@slack/[email protected]
Milestone: https://github.com/slackapi/node-slack-sdk/milestone/150?closed=1

@slack/[email protected]

25 Aug 20:15
00b7d18

Choose a tag to compare

What's Changed

This release removes unused dependencies and updates internal dependencies to use more secure versions 🔏

📚 Documentation

🤖 Dependencies

  • refactor(oauth): remove lodash.isstring from dependencies in #2293 - Thanks @zimeg!
  • chore(oauth): bump @slack/web-api to 7.10.0 in #2341 - Thanks @zimeg!
  • chore(deps-dev): bump typescript from 5.8.2 to 5.8.3 in /packages/oauth in #2225 - Thanks @dependabot!
  • chore(deps-dev): bump typescript from 5.8.3 to 5.9.2 in /packages/oauth in #2328 - Thanks @dependabot!
  • chore(deps-dev): bump sinon from 20.0.0 to 21.0.0 in /packages/oauth in the dev-sinon group in #2268 - Thanks @dependabot!
  • chore(deps-dev): bump @biomejs/biome to v2 for all packages in #2281 - Thanks @mwbrooks!

🧰 Maintenance

Package: https://www.npmjs.com/package/@slack/oauth/v/3.0.4
Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/[email protected]...@slack/[email protected]
Milestone: https://github.com/slackapi/node-slack-sdk/milestone/121?closed=1