Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/late-clouds-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@slack/types": minor
---

feat: add the `app_context_changed` event type for the agent DM experience
34 changes: 34 additions & 0 deletions packages/types/src/events/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,40 @@ export interface AppRateLimitedEvent {
// export interface AppRateLimitedEvent {
// }

export interface AppContextChangedEvent {
type: 'app_context_changed';
channel: string;
user: string;
context: {
entities?: ((
| {
type: 'slack#/types/channel_id';
value: string;
}
| {
type: 'slack#/types/canvas_id';
value: string;
}
| {
type: 'slack#/types/list_id';
value: string;
}
| {
type: 'slack#/types/message_context';
value: {
message_ts: string;
channel_id: string;
};
}
) & {
score?: number;
team_id?: string;
enterprise_id?: string;
})[];
};
event_ts: string;
}

export interface AppUninstalledEvent {
type: 'app_uninstalled';
}
2 changes: 2 additions & 0 deletions packages/types/src/events/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {
AppContextChangedEvent,
AppDeletedEvent,
AppHomeOpenedEvent,
AppInstalledEvent,
Expand Down Expand Up @@ -120,6 +121,7 @@ export * from './user';
* This is a discriminated union. The discriminant is the `type` property.
*/
export type SlackEvent =
| AppContextChangedEvent
| AppDeletedEvent
| AppHomeOpenedEvent
| AppInstalledEvent
Expand Down
3 changes: 3 additions & 0 deletions packages/types/src/events/message.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Block, KnownBlock } from '../block-kit/blocks';
import type { BotProfile } from '../common/bot-profile';
import type { MessageAttachment } from '../message-attachments';
import type { AppContextChangedEvent } from './app';

type ChannelTypes = 'channel' | 'group' | 'im' | 'mpim' | 'app_home';

Expand Down Expand Up @@ -60,6 +61,8 @@ export interface GenericMessageEvent {

// TODO: add properties to this field once it's publicly released
assistant_thread?: Record<string, unknown>;

app_context?: AppContextChangedEvent['context'];
}

export interface BotMessageEvent {
Expand Down
75 changes: 75 additions & 0 deletions packages/types/test/events/app.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { expectAssignable, expectError } from 'tsd';
import type { AppContextChangedEvent, SlackEvent } from '../../src/index';

// a channel_id context entity
const channelContextChangedEvent: AppContextChangedEvent = {
type: 'app_context_changed',
channel: 'D0123456789',
user: 'U0123456789',
context: {
entities: [
{
type: 'slack#/types/channel_id',
value: 'C0123456789',
team_id: 'T0123456789',
score: 75,
enterprise_id: 'E0123456789',
},
],
},
event_ts: '1234567890.123456',
};
expectAssignable<SlackEvent>(channelContextChangedEvent);

// canvas_id and list_id entities share the string `value` shape
expectAssignable<AppContextChangedEvent>({
type: 'app_context_changed',
channel: 'D0123456789',
user: 'U0123456789',
context: {
entities: [
{ type: 'slack#/types/canvas_id', value: 'F0123456789' },
{ type: 'slack#/types/list_id', value: 'F0123456780' },
],
},
event_ts: '1234567890.123456',
});

// a message_context entity carries an object `value` with message_ts and channel_id
expectAssignable<AppContextChangedEvent>({
type: 'app_context_changed',
channel: 'D0123456789',
user: 'U0123456789',
context: {
entities: [
{
type: 'slack#/types/message_context',
value: { message_ts: '1234567890.123456', channel_id: 'C0123456789' },
team_id: 'T0123456789',
score: 75,
enterprise_id: 'E0123456789',
},
],
},
event_ts: '1234567890.123456',
});

// `entities` is optional — the context can be empty
expectAssignable<AppContextChangedEvent>({
type: 'app_context_changed',
channel: 'D0123456789',
user: 'U0123456789',
context: {},
event_ts: '1234567890.123456',
});

// a message_context entity requires channel_id alongside message_ts
expectError<AppContextChangedEvent>({
type: 'app_context_changed',
channel: 'D0123456789',
user: 'U0123456789',
context: {
entities: [{ type: 'slack#/types/message_context', value: { message_ts: '1234567890.123456' } }],
},
event_ts: '1234567890.123456',
});
24 changes: 24 additions & 0 deletions packages/types/test/events/message.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,27 @@ const messageDeletedEvent: MessageDeletedEvent = {
previous_message: anyMessageEvent,
};
expectAssignable<MessageEvent>(messageDeletedEvent.previous_message);

// the agent DM context is delivered inline on messages via the `app_context` field
const messageWithAppContext: GenericMessageEvent = {
type: 'message',
subtype: undefined,
channel_type: 'im',
channel: 'D0123456789',
user: 'U0123456789',
ts: '1234567890.123456',
event_ts: '1234567890.123456',
text: 'hi',
app_context: {
entities: [
{
type: 'slack#/types/channel_id',
value: 'C0123456789',
team_id: 'T0123456789',
score: 75,
enterprise_id: 'E0123456789',
},
],
},
};
expectAssignable<GenericMessageEvent>(messageWithAppContext);