Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
c8c3482
Add support for flexpane API
vegeris Apr 8, 2025
a3f8922
feat-work-objects: version bump for types pkg (#2229)
vegeris Apr 9, 2025
dde54aa
Update
vegeris Apr 9, 2025
5813ae6
feat-work-objects: version bump 2 for the types pkg (#2234)
vegeris Apr 10, 2025
6892aef
feat-work-objects: version bump for the web-api pkg (#2232)
vegeris Apr 10, 2025
9e8988b
Merge branch 'main' of https://github.com/slackapi/node-slack-sdk int…
vegeris Aug 22, 2025
c3cef1f
update
vegeris Sep 8, 2025
67cc8b6
Merge branch 'main' of https://github.com/slackapi/node-slack-sdk int…
vegeris Sep 10, 2025
da092d5
update payload object, entity.presentDetails inputs, test, event
vegeris Sep 10, 2025
d4231dd
Merge branch 'main' of https://github.com/slackapi/node-slack-sdk int…
vegeris Sep 12, 2025
d889e07
feat-work-objects: beta version for the types pkg (#2366)
vegeris Sep 12, 2025
e6bd2ac
lint
vegeris Sep 12, 2025
c54c9b3
feat-work-objects: beta version for the web-api pkg (#2367)
vegeris Sep 12, 2025
24ecda6
Update entity metadata definitions
vegeris Oct 9, 2025
ba79b81
Merge branch 'main' of https://github.com/slackapi/node-slack-sdk int…
vegeris Oct 9, 2025
02e5360
feat-work-objects: beta version for the types pkg (#2404)
vegeris Oct 9, 2025
b983ca5
update test
vegeris Oct 9, 2025
8201026
feat-work-objects: beta version for the web-api pkg (#2405)
vegeris Oct 9, 2025
e4284e3
update schema
vegeris Oct 15, 2025
bb49dd5
feat-work-objects: beta version for the types pkg (#2406)
vegeris Oct 15, 2025
480cb1f
feat-work-objects: beta version for the web-api pkg (#2407)
vegeris Oct 15, 2025
c4992f6
Update URL in packages/web-api/src/types/request/chat.ts
vegeris Oct 16, 2025
d2a9d93
Update URL in packages/web-api/src/types/request/entity.ts
vegeris Oct 16, 2025
c4cb46c
alphabetical order
vegeris Oct 16, 2025
ec18401
update comments to jsdoc format
vegeris Oct 16, 2025
6f56034
update schema
vegeris Oct 16, 2025
eeef76d
feat-work-objects: beta version for the types pkg (#2408)
vegeris Oct 16, 2025
a44d4b3
whoops
vegeris Oct 16, 2025
1d4325b
feat-work-objects: version bump for the web-api pkg (#2409)
vegeris Oct 16, 2025
019cfd3
update comment
vegeris Oct 22, 2025
fae7b17
mv EntityAndEventMessageMetadata
vegeris Oct 22, 2025
a2eaa71
rename types for unfurls and metadata param of chat.unfurl
vegeris Oct 22, 2025
26e3aa5
biome fix
vegeris Oct 22, 2025
4eaeed8
make cli-test dependency versions exact
vegeris Oct 22, 2025
6d2ebc4
Revert "make cli-test dependency versions exact"
vegeris Oct 22, 2025
a9c5d4e
Merge branch 'main' of https://github.com/slackapi/node-slack-sdk int…
vegeris Oct 22, 2025
c0cc1f6
rm types pkg updates
vegeris Oct 23, 2025
d974164
feat-work-objects: version bump for the web-api pkg (#2416)
vegeris Oct 23, 2025
9b5ecf1
Merge branch 'main' of https://github.com/slackapi/node-slack-sdk int…
vegeris Oct 23, 2025
5c174bd
update types dependency and reset web-api package version
vegeris Oct 23, 2025
de9e02a
Merge branch 'main' of https://github.com/slackapi/node-slack-sdk int…
vegeris Oct 23, 2025
3ae9720
Update packages/web-api/package.json
vegeris Oct 23, 2025
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
2 changes: 1 addition & 1 deletion packages/web-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
},
"dependencies": {
"@slack/logger": "^4.0.0",
"@slack/types": "^2.17.0",
"@slack/types": "^2.18.0",
"@types/node": ">=18.0.0",
"@types/retry": "0.12.0",
"axios": "^1.11.0",
Expand Down
13 changes: 13 additions & 0 deletions packages/web-api/src/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ import type {
DndSetSnoozeArguments,
DndTeamInfoArguments,
EmojiListArguments,
EntityPresentDetailsArguments,
FilesCommentsDeleteArguments,
FilesCompleteUploadExternalArguments,
FilesDeleteArguments,
Expand Down Expand Up @@ -437,6 +438,7 @@ import type {
DndSetSnoozeResponse,
DndTeamInfoResponse,
EmojiListResponse,
EntityPresentDetailsResponse,
FilesCommentsDeleteResponse,
FilesCompleteUploadExternalResponse,
FilesDeleteResponse,
Expand Down Expand Up @@ -1879,6 +1881,17 @@ export abstract class Methods extends EventEmitter<WebClientEvent> {
list: bindApiCallWithOptionalArgument<EmojiListArguments, EmojiListResponse>(this, 'emoji.list'),
};

public readonly entity = {
/**
* @description Provide information about the entity to be displayed in the flexpane.
* @see {@link https://docs.slack.dev/reference/methods/entity.presentDetails}
*/
presentDetails: bindApiCall<EntityPresentDetailsArguments, EntityPresentDetailsResponse>(
this,
'entity.presentDetails',
),
};

public readonly files = {
/**
* @description Finishes an upload started with {@link https://docs.slack.dev/reference/methods/files.getUploadURLExternal `files.getUploadURLExternal`}.
Expand Down
48 changes: 40 additions & 8 deletions packages/web-api/src/types/request/chat.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {
Block, // TODO: these will be combined into one in a new types release
EntityMetadata,
KnownBlock,
LinkUnfurls,
MessageAttachment,
Expand Down Expand Up @@ -104,6 +105,19 @@ export interface BroadcastedThreadReply extends ThreadTS {
// or not broadcasted. Broadcasted replies are necessarily threaded, so `thread_ts` becomes required.
type ReplyInThread = WithinThreadReply | BroadcastedThreadReply;

export interface ChatPostMessageMetadata {
/**
* @description Object representing message metadata, entity and/or event data to attach to a Slack message.
* Provide 'entities' to set work object entity metadata.
* Provide 'event_type' and 'event_payload' to set event metadata.
*/
metadata?: Partial<MessageMetadata> & {
/**
* @description An array of work object entities.
*/
entities?: EntityMetadata[];
};
}
export interface Metadata {
/** @description Object representing message metadata, which will be made accessible to any user or app. */
metadata?: MessageMetadata;
Expand Down Expand Up @@ -191,7 +205,7 @@ export type ChatPostMessageArguments = TokenOverridable &
Authorship &
Parse &
LinkNames &
Metadata &
ChatPostMessageMetadata &
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Just want to validate that I'm understanding correctly, this updates ChatPostMessageArguments from

interface ChatPostMessageArguments {
  ...
  metadata?:  {
    event_type: string;
    event_payload: {
      [key: string]: string | number | boolean | MessageMetadataEventPayloadObject | MessageMetadataEventPayloadObject[];
    };
}

To

interface ChatPostMessageArguments {
  ...
  metadata?:  {
    event_type?: string;
    event_payload?: {
      [key: string]: string | number | boolean | MessageMetadataEventPayloadObject | MessageMetadataEventPayloadObject[];
    };
    entities?: EntityMetadata[];
}

Since this type is used to define and input for a function, making event_type and event_payload optional should not be a breaking change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup; what I'm trying to show is that one can provide event and / or entity metadata in chat.postMessage

interface ChatPostMessageArguments {
  ...
  metadata?:  {

   // if providing event metadata, both of these params are still required (but they're optional in the type bc one can provide entity metadata instead)
    event_type: string;
    event_payload: {
      [key: string]: string | number | boolean | MessageMetadataEventPayloadObject | MessageMetadataEventPayloadObject[];
    };


AND / OR

   // if providing entity metadata, this param is required (but it's optional in the type bc one can provide event metadata instead)
    entities: EntityMetadata[];
}

Since this type is used to define and input for a function, making event_type and event_payload optional should not be a breaking change?

Passing an object into the metadata param with just event_type and event_payload is still valid and should still be accepted by the SDK; if users are typing the object as Metadata though they would need to change that to ChatPostMessageMetadata. Similar thing came up for the Java update; changing the type of an existing field does seem like a breaking change 😅 Will work object support require a major version bump because of this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will work object support require a major version bump because of this?

The the Java SDK I need to take a look there might be a way around this

Unfurls & {
/** @description Disable Slack markup parsing by setting to `false`. Enabled by default. */
mrkdwn?: boolean;
Expand Down Expand Up @@ -256,13 +270,8 @@ export interface SourceAndUnfurlID {
type UnfurlTarget = ChannelAndTS | SourceAndUnfurlID;

// https://docs.slack.dev/reference/methods/chat.unfurl
export type ChatUnfurlArguments = {
/**
* @description URL-encoded JSON map with keys set to URLs featured in the the message, pointing to their unfurl
* blocks or message attachments.
*/
unfurls: LinkUnfurls;
} & UnfurlTarget &
export type ChatUnfurlArguments = (ChatUnfurlUnfurls | ChatUnfurlMetadata) &
UnfurlTarget &
TokenOverridable & {
/**
* @description Provide a simply-formatted string to send as an ephemeral message to the user as invitation to
Expand All @@ -286,6 +295,29 @@ export type ChatUnfurlArguments = {
user_auth_blocks?: (KnownBlock | Block)[];
};

/**
* @description The `unfurls` param of the `chat.unfurl` API.
*/
interface ChatUnfurlUnfurls {
/**
* @description Object with keys set to URLs featured in the message, pointing to their unfurl
* blocks or message attachments.
*/
unfurls: LinkUnfurls;
}

/**
* @description The `metadata` param of the `chat.unfurl` API.
*/
interface ChatUnfurlMetadata {
/**
* @description Unfurl metadata featuring an array of entities to attach to the message based on URLs featured in the message.
*/
metadata: Partial<MessageMetadata> & {
entities: EntityMetadata[];
};
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(One can also provide event metadata in chat.unfurl and it'll be persisted on the message but it's not a main use case)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QQ: In ChatPostMessageMetadata, entities is optional, just want to confirm that here is should be required

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, if metadata is provided to chat.unfurl, entities is required. For chat.postMessage, metadata can be provided with event metadata only

}

// https://docs.slack.dev/reference/methods/chat.update
export type ChatUpdateArguments = MessageContents & {
/** @description Timestamp of the message to be updated. */
Expand Down
47 changes: 47 additions & 0 deletions packages/web-api/src/types/request/entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { EntityActionButton, EntityMetadata } from '@slack/types';
import type { TokenOverridable } from './common';

// https://docs.slack.dev/reference/methods/entity.presentDetails
export type EntityPresentDetailsArguments = TokenOverridable & {
/**
* @description Entity metadata to be presented in the flexpane.
* */
metadata?: EntityMetadata;
/**
* @description A reference to the original user action that initated the request.
* */
trigger_id: string;
/**
* @description Set user_auth_required to true to indicate that the user must authenticate to view the full
* flexpane data. Defaults to false.
* */
user_auth_required?: boolean;
/**
* @description A custom URL to which users are directed for authentication if required.
* Example: "https://example.com/onboarding?user_id=xxx"
* */
user_auth_url?: string;
/** @description Error response preventing flexpane data from being returned. */
error?: {
/**
* @description Error status indicating why the entity could not be presented.
* */
status: string;
/**
* @description If status is 'custom', you can use this field to provide a message to the client.
* */
custom_message?: string;
/**
* @description String format, eg. 'markdown'.
* */
message_format?: string;
/**
* @description If status is 'custom', you can use this field to provide a title to the client.
* */
custom_title?: string;
/**
* @description Set of action buttons to be shown in case of a specific error.
* */
actions?: EntityActionButton[];
};
};
1 change: 1 addition & 0 deletions packages/web-api/src/types/request/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ export type {
DndTeamInfoArguments,
} from './dnd';
export type { EmojiListArguments } from './emoji';
export type { EntityPresentDetailsArguments } from './entity';
export type {
FilesCommentsDeleteArguments,
FilesCompleteUploadExternalArguments,
Expand Down
1 change: 1 addition & 0 deletions packages/web-api/src/types/request/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ type ManifestEvent =
| 'dnd_updated_user'
| 'email_domain_changed'
| 'emoji_changed'
| 'entity_details_requested'
| 'file_change'
| 'file_comment_added'
| 'file_comment_deleted'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/////////////////////////////////////////////////////////////////////////////////////////
// //
// !!! DO NOT EDIT THIS FILE !!! //
// //
// This file is auto-generated by scripts/generate-web-api-types.sh in the repository. //
// Please refer to the script code to learn how to update the source data. //
// //
/////////////////////////////////////////////////////////////////////////////////////////

import type { WebAPICallResult } from '../../WebClient';
export type EntityPresentDetailsResponse = WebAPICallResult & {
error?: string;
needed?: string;
ok?: boolean;
provided?: string;
warning?: string;
};
1 change: 1 addition & 0 deletions packages/web-api/src/types/response/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ export { DndInfoResponse } from './DndInfoResponse';
export { DndSetSnoozeResponse } from './DndSetSnoozeResponse';
export { DndTeamInfoResponse } from './DndTeamInfoResponse';
export { EmojiListResponse } from './EmojiListResponse';
export { EntityPresentDetailsResponse } from './EntityPresentDetailsResponse';
export { FilesCommentsAddResponse } from './FilesCommentsAddResponse';
export { FilesCommentsDeleteResponse } from './FilesCommentsDeleteResponse';
export { FilesCommentsEditResponse } from './FilesCommentsEditResponse';
Expand Down
62 changes: 60 additions & 2 deletions packages/web-api/test/types/methods/chat.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CustomFieldType, type EntityMetadata } from '@slack/types';
import { expectAssignable, expectError } from 'tsd';

import { WebClient } from '../../../src/WebClient';

const web = new WebClient('TOKEN');
Expand Down Expand Up @@ -441,6 +441,25 @@ expectAssignable<Parameters<typeof web.chat.postMessage>>([
reply_broadcast: false, // can send a threaded message and explicitly not broadcast it
},
]);
expectAssignable<Parameters<typeof web.chat.postMessage>>([
{
channel: 'C1234',
text: 'hello',
thread_ts: '1234.56',
metadata: {
entities: [
{
entity_type: 'slack#/entities/file',
entity_payload: {
attributes: { title: { text: 'My File' } },
},
external_ref: { id: '' },
url: '',
},
],
},
},
]);
// adding a test for when `reply_broadcast` specific boolean value is not known ahead of time
// https://github.com/slackapi/node-slack-sdk/issues/1859
function wideBooleanTest(b: boolean) {
Expand Down Expand Up @@ -663,7 +682,7 @@ expectError(
);
expectError(
web.chat.unfurl({
channel: 'C1234', // missing unfurls
channel: 'C1234', // missing both unfurls and metadata
ts: '1234.56',
}),
);
Expand Down Expand Up @@ -717,6 +736,45 @@ expectAssignable<Parameters<typeof web.chat.unfurl>>([
ts: '1234.56',
},
]);
const entityMetadata: EntityMetadata = {
entity_type: 'slack#/entities/task',
entity_payload: {
attributes: {
title: {
text: 'Important task',
},
},
fields: {
status: {
value: 'All clear',
},
description: {
value: 'Details of the task.',
},
},
custom_fields: [
{
label: 'My Field',
key: 'my-field',
type: CustomFieldType.Array,
item_type: 'slack#/types/channel_id',
value: [{ value: 'C0123ABC' }],
},
],
},
external_ref: { id: '1234' },
url: 'https://myappdomain.com/id/1234',
app_unfurl_url: 'https://myappdomain.com/id/1234?myquery=param',
};
expectAssignable<Parameters<typeof web.chat.unfurl>>([
{
channel: 'C1234',
ts: '1234.56',
metadata: {
entities: [entityMetadata],
},
},
]);

// chat.update
// -- sad path
Expand Down