experimental-ash 0.8.3 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/dist/docs/public/channels/slack.md +53 -25
- package/dist/src/compiled/.vendor-stamp.json +14 -14
- package/dist/src/compiled/@ai-sdk/anthropic/index.js +2 -2
- package/dist/src/compiled/@ai-sdk/google/index.js +4 -4
- package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/openai/index.js +6 -6
- package/dist/src/compiled/@ai-sdk/otel/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/provider/_json-schema.d.ts +5 -0
- package/dist/src/compiled/@ai-sdk/provider/index.d.ts +6632 -1
- package/dist/src/compiled/@chat-adapter/slack/_chat-adapter-shared.d.ts +9 -0
- package/dist/src/compiled/@chat-adapter/slack/index.d.ts +632 -54
- package/dist/src/compiled/@chat-adapter/slack/index.js +25 -29
- package/dist/src/compiled/@chat-adapter/slack/package.json +1 -1
- package/dist/src/compiled/@chat-adapter/state-memory/index.d.ts +41 -25
- package/dist/src/compiled/@chat-adapter/state-memory/package.json +1 -1
- package/dist/src/compiled/@standard-schema/spec/index.d.ts +115 -62
- package/dist/src/compiled/@vercel/sandbox/index.d.ts +4 -1
- package/dist/src/compiled/@vercel/sandbox/index.js +5 -5
- package/dist/src/compiled/@workflow/core/index.js +1 -1
- package/dist/src/compiled/@workflow/core/runtime.d.ts +6 -2
- package/dist/src/compiled/@workflow/core/runtime.js +4 -4
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/errors/_ms.d.ts +4 -0
- package/dist/src/compiled/@workflow/errors/error-codes.d.ts +17 -0
- package/dist/src/compiled/@workflow/errors/index.d.ts +438 -56
- package/dist/src/compiled/@workflow/errors/index.js +1 -1
- package/dist/src/compiled/_chunks/node/{auth-CdwuOxMs.js → auth-vbe4XEEK.js} +2 -2
- package/dist/src/compiled/_chunks/node/{dist-B6IOtzm1.js → dist-BdWHjlRQ.js} +12 -12
- package/dist/src/compiled/_chunks/node/retry-BOcy5BbJ.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{context-errors-CXifqq6a.js → context-errors-zbKocOyk.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{dist-BuELZxm6.js → dist-Ci2brnHh.js} +3 -3
- package/dist/src/compiled/_chunks/workflow/{resume-hook-CgfgCU87.js → resume-hook-CL8Ed91K.js} +2 -2
- package/dist/src/compiled/_chunks/workflow/sleep-Dn3i9nxI.js +1 -0
- package/dist/src/compiled/chat/_mdast.d.ts +24 -0
- package/dist/src/compiled/chat/_workflow-serde.d.ts +5 -0
- package/dist/src/compiled/chat/index.d.ts +3851 -72
- package/dist/src/compiled/chat/index.js +1 -1
- package/dist/src/compiled/chat/jsx-runtime-DxGwoLu2.d.ts +782 -0
- package/dist/src/compiled/chat/package.json +1 -1
- package/dist/src/compiled/just-bash/index.js +1 -1
- package/dist/src/execution/authorization-challenge-defaults.d.ts +1 -1
- package/dist/src/execution/authorization-challenge-defaults.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/public/channels/slack/slack.js +4 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +47 -4
- package/dist/src/public/channels/slack/slackChannel.js +49 -12
- package/dist/src/runtime/connections/authorization-tokens.d.ts +1 -1
- package/dist/src/runtime/connections/authorization-tokens.js +1 -1
- package/package.json +16 -16
- package/dist/src/compiled/_chunks/node/ms-B2k_qBoq.js +0 -1
- package/dist/src/compiled/_chunks/workflow/sleep-BzS_cSYx.js +0 -1
- /package/dist/src/compiled/_chunks/workflow/{dist-C9DdsXoK.js → dist-0iNBqPYp.js} +0 -0
- /package/dist/src/compiled/_chunks/workflow/{dist-BHbmiLmM.js → dist-D774SUM4.js} +0 -0
- /package/dist/src/compiled/_chunks/workflow/{src-CidBwKAD.js → src-ClRYdO4-.js} +0 -0
- /package/dist/src/compiled/_chunks/workflow/{symbols-BC0BVTM7.js → symbols-D-4tVV8x.js} +0 -0
|
@@ -1,63 +1,641 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { CardElement, BaseFormatConverter, Root, AdapterPostableMessage, Logger, Adapter, ChatInstance, UserInfo, WebhookOptions, Attachment, RawMessage, EphemeralMessage, ScheduledMessage, ModalElement, EmojiValue, StreamChunk, StreamOptions, FetchOptions, FetchResult, ThreadInfo, Message, ChannelVisibility, ListThreadsOptions, ListThreadsResult, ChannelInfo, FormattedContent } from '#compiled/chat/index.js';
|
|
2
|
+
export { EncryptedTokenData, decodeKey } from './_chat-adapter-shared.js';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Slack Block Kit converter for cross-platform cards.
|
|
6
|
+
*
|
|
7
|
+
* Converts CardElement to Slack Block Kit blocks.
|
|
8
|
+
* @see https://api.slack.com/block-kit
|
|
9
|
+
*/
|
|
5
10
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
botUserId?: string | undefined;
|
|
11
|
-
clientId?: string | undefined;
|
|
12
|
-
clientSecret?: string | undefined;
|
|
13
|
-
encryptionKey?: string | undefined;
|
|
14
|
-
installationKeyPrefix?: string | undefined;
|
|
15
|
-
logger?: Logger | undefined;
|
|
16
|
-
mode?: SlackAdapterMode | undefined;
|
|
17
|
-
signingSecret?: string | undefined;
|
|
18
|
-
socketForwardingSecret?: string | undefined;
|
|
19
|
-
userName?: string | undefined;
|
|
20
|
-
webhookVerifier?: ((request: Request, body: string) => unknown | Promise<unknown>) | undefined;
|
|
11
|
+
interface SlackBlock {
|
|
12
|
+
block_id?: string;
|
|
13
|
+
type: string;
|
|
14
|
+
[key: string]: unknown;
|
|
21
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Convert a CardElement to Slack Block Kit blocks.
|
|
18
|
+
*/
|
|
19
|
+
declare function cardToBlockKit(card: CardElement): SlackBlock[];
|
|
20
|
+
/**
|
|
21
|
+
* Generate fallback text from a card element.
|
|
22
|
+
* Used when blocks aren't supported or for notifications.
|
|
23
|
+
*/
|
|
24
|
+
declare function cardToFallbackText(card: CardElement): string;
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Slack format conversion.
|
|
28
|
+
*
|
|
29
|
+
* Outgoing: Slack now natively renders markdown via the `markdown_text` field
|
|
30
|
+
* on chat.postMessage / postEphemeral / update / scheduleMessage. We pass
|
|
31
|
+
* markdown through there and let Slack handle it. Interactive `response_url`
|
|
32
|
+
* payloads do not accept `markdown_text`, so those still use Slack mrkdwn text.
|
|
33
|
+
*
|
|
34
|
+
* Incoming: Slack `message` events still deliver text as mrkdwn
|
|
35
|
+
* (`*bold*`, `<@U123>`, `<url|text>`), so the toAst parser stays.
|
|
36
|
+
*/
|
|
27
37
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
38
|
+
type SlackTextPayload = {
|
|
39
|
+
text: string;
|
|
40
|
+
} | {
|
|
41
|
+
markdown_text: string;
|
|
42
|
+
};
|
|
43
|
+
declare class SlackFormatConverter extends BaseFormatConverter {
|
|
44
|
+
/**
|
|
45
|
+
* Render an AST to standard markdown. Slack accepts this directly via
|
|
46
|
+
* `markdown_text` and the `markdown` block.
|
|
47
|
+
*/
|
|
48
|
+
fromAst(ast: Root): string;
|
|
49
|
+
/**
|
|
50
|
+
* Parse Slack mrkdwn into an AST. Used for incoming `message` events.
|
|
51
|
+
*/
|
|
52
|
+
toAst(mrkdwn: string): Root;
|
|
53
|
+
/**
|
|
54
|
+
* Build the Slack API payload fields for a message.
|
|
55
|
+
*
|
|
56
|
+
* - `string` / `{ raw }` → `{ text }` (plain — preserves literal `*`, `_`, etc.)
|
|
57
|
+
* - `{ markdown }` / `{ ast }` → `{ markdown_text }` (Slack renders natively)
|
|
58
|
+
*
|
|
59
|
+
* Bare `@user` mentions are rewritten to `<@user>` and `:emoji:` placeholders
|
|
60
|
+
* are normalized for Slack in all branches.
|
|
61
|
+
*
|
|
62
|
+
* Note: `markdown_text` has a 12,000 character limit; `text` allows ~40,000.
|
|
63
|
+
* Note: `markdown_text` is mutually exclusive with `text` and `blocks`.
|
|
64
|
+
*/
|
|
65
|
+
toSlackPayload(message: AdapterPostableMessage): SlackTextPayload;
|
|
66
|
+
/**
|
|
67
|
+
* Build text for Slack response_url payloads.
|
|
68
|
+
*
|
|
69
|
+
* Slack rejects `markdown_text` on response_url (`no_text`), so markdown/AST
|
|
70
|
+
* messages are rendered to Slack's legacy mrkdwn format for this surface.
|
|
71
|
+
*/
|
|
72
|
+
toResponseUrlText(message: AdapterPostableMessage): string;
|
|
73
|
+
private finalize;
|
|
74
|
+
private astToMrkdwn;
|
|
75
|
+
private nodeToMrkdwn;
|
|
57
76
|
}
|
|
58
77
|
|
|
59
|
-
|
|
60
|
-
|
|
78
|
+
type SlackAdapterMode = "webhook" | "socket";
|
|
79
|
+
/**
|
|
80
|
+
* Bot token configuration. Can be a static string, or a function that returns
|
|
81
|
+
* a token (optionally asynchronously). The function is invoked each time a
|
|
82
|
+
* token is needed, enabling rotation or lazy retrieval from a secret manager.
|
|
83
|
+
*/
|
|
84
|
+
type SlackBotToken = string | (() => string | Promise<string>);
|
|
85
|
+
interface SlackAdapterConfig {
|
|
86
|
+
/** Override the Slack API base URL (e.g. "https://slack-gov.com/api/" for GovSlack). Defaults to SLACK_API_URL env var. */
|
|
87
|
+
apiUrl?: string;
|
|
88
|
+
/** App-level token (xapp-...). Required for socket mode. */
|
|
89
|
+
appToken?: string;
|
|
90
|
+
/**
|
|
91
|
+
* Bot token (xoxb-...). Required for single-workspace mode. Omit for multi-workspace.
|
|
92
|
+
* May be a string, or a function returning a string or Promise<string> (called
|
|
93
|
+
* on each use to support rotation or deferred resolution).
|
|
94
|
+
*/
|
|
95
|
+
botToken?: SlackBotToken;
|
|
96
|
+
/** Bot user ID (will be fetched if not provided) */
|
|
97
|
+
botUserId?: string;
|
|
98
|
+
/** Slack app client ID (required for OAuth / multi-workspace) */
|
|
99
|
+
clientId?: string;
|
|
100
|
+
/** Slack app client secret (required for OAuth / multi-workspace) */
|
|
101
|
+
clientSecret?: string;
|
|
102
|
+
/**
|
|
103
|
+
* Base64-encoded 32-byte AES-256-GCM encryption key.
|
|
104
|
+
* If provided, bot tokens stored via setInstallation() will be encrypted at rest.
|
|
105
|
+
*/
|
|
106
|
+
encryptionKey?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Prefix for the state key used to store workspace installations.
|
|
109
|
+
* Defaults to `slack:installation`. The full key will be `{prefix}:{teamId}`.
|
|
110
|
+
*/
|
|
111
|
+
installationKeyPrefix?: string;
|
|
112
|
+
/** Logger instance for error reporting. Defaults to ConsoleLogger. */
|
|
113
|
+
logger?: Logger;
|
|
114
|
+
/** Connection mode: "webhook" (default) or "socket" */
|
|
115
|
+
mode?: SlackAdapterMode;
|
|
116
|
+
/** Signing secret for webhook verification. Defaults to SLACK_SIGNING_SECRET env var. */
|
|
117
|
+
signingSecret?: string;
|
|
118
|
+
/** Shared secret for authenticating forwarded socket mode events. Auto-detected from SLACK_SOCKET_FORWARDING_SECRET. Falls back to appToken if not set. */
|
|
119
|
+
socketForwardingSecret?: string;
|
|
120
|
+
/** Override bot username (optional) */
|
|
121
|
+
userName?: string;
|
|
122
|
+
/**
|
|
123
|
+
* Custom webhook verifier. Used in place of `signingSecret`.
|
|
124
|
+
* Receives the incoming `Request` and the raw body text already
|
|
125
|
+
* read by the adapter. To reject the request, either
|
|
126
|
+
* return a falsy value (sync or async) or throw/reject; the adapter will
|
|
127
|
+
* respond with `401 Invalid signature`. Any truthy return value is treated
|
|
128
|
+
* as a successful verification. If a string is returned, it replaces the
|
|
129
|
+
* raw body for downstream parsing — useful when the verifier needs to
|
|
130
|
+
* canonicalize or substitute the verified payload.
|
|
131
|
+
*
|
|
132
|
+
* When both `signingSecret` and `webhookVerifier` are specified,
|
|
133
|
+
* `signingSecret` takes precedence.
|
|
134
|
+
*
|
|
135
|
+
* SECURITY: When this is used in place of `signingSecret`, the built-in
|
|
136
|
+
* Slack timestamp tolerance check is NOT performed. Implementations are
|
|
137
|
+
* responsible for verifying the `x-slack-request-timestamp` header (or an
|
|
138
|
+
* equivalent freshness signal) to prevent replay of captured signed
|
|
139
|
+
* requests.
|
|
140
|
+
*/
|
|
141
|
+
webhookVerifier?: (request: Request, body: string) => unknown | Promise<unknown>;
|
|
142
|
+
}
|
|
143
|
+
interface SlackOAuthCallbackOptions {
|
|
144
|
+
/** Redirect URI to send to Slack during the OAuth code exchange. */
|
|
145
|
+
redirectUri?: string;
|
|
146
|
+
}
|
|
147
|
+
/** Data stored per Slack workspace installation */
|
|
148
|
+
interface SlackInstallation {
|
|
149
|
+
botToken: string;
|
|
150
|
+
botUserId?: string;
|
|
151
|
+
teamName?: string;
|
|
152
|
+
}
|
|
153
|
+
/** Slack-specific thread ID data */
|
|
154
|
+
interface SlackThreadId {
|
|
155
|
+
channel: string;
|
|
156
|
+
threadTs: string;
|
|
157
|
+
}
|
|
158
|
+
/** Slack event payload (raw message format) */
|
|
159
|
+
interface SlackEvent {
|
|
160
|
+
/** Legacy attachments (unfurl previews, app unfurls, etc.) */
|
|
161
|
+
attachments?: Array<{
|
|
162
|
+
from_url?: string;
|
|
163
|
+
image_url?: string;
|
|
164
|
+
is_msg_unfurl?: boolean;
|
|
165
|
+
original_url?: string;
|
|
166
|
+
service_icon?: string;
|
|
167
|
+
service_name?: string;
|
|
168
|
+
text?: string;
|
|
169
|
+
thumb_url?: string;
|
|
170
|
+
title?: string;
|
|
171
|
+
title_link?: string;
|
|
172
|
+
}>;
|
|
173
|
+
/** Rich text blocks containing structured elements (links, mentions, etc.) */
|
|
174
|
+
blocks?: Array<{
|
|
175
|
+
type: string;
|
|
176
|
+
elements?: Array<{
|
|
177
|
+
type: string;
|
|
178
|
+
elements?: Array<{
|
|
179
|
+
type: string;
|
|
180
|
+
url?: string;
|
|
181
|
+
text?: string;
|
|
182
|
+
}>;
|
|
183
|
+
}>;
|
|
184
|
+
}>;
|
|
185
|
+
bot_id?: string;
|
|
186
|
+
channel?: string;
|
|
187
|
+
/** Channel type: "channel", "group", "mpim", or "im" (DM) */
|
|
188
|
+
channel_type?: string;
|
|
189
|
+
edited?: {
|
|
190
|
+
ts: string;
|
|
191
|
+
};
|
|
192
|
+
files?: Array<{
|
|
193
|
+
id?: string;
|
|
194
|
+
mimetype?: string;
|
|
195
|
+
url_private?: string;
|
|
196
|
+
name?: string;
|
|
197
|
+
size?: number;
|
|
198
|
+
original_w?: number;
|
|
199
|
+
original_h?: number;
|
|
200
|
+
}>;
|
|
201
|
+
/** Hidden flag on message_changed events (true for unfurl-only updates) */
|
|
202
|
+
hidden?: boolean;
|
|
203
|
+
/** Timestamp of the latest reply (present on thread parent messages) */
|
|
204
|
+
latest_reply?: string;
|
|
205
|
+
/** Inner message on message_changed events */
|
|
206
|
+
message?: SlackEvent;
|
|
207
|
+
/** Number of replies in the thread (present on thread parent messages) */
|
|
208
|
+
reply_count?: number;
|
|
209
|
+
subtype?: string;
|
|
210
|
+
team?: string;
|
|
211
|
+
team_id?: string;
|
|
212
|
+
text?: string;
|
|
213
|
+
thread_ts?: string;
|
|
214
|
+
ts?: string;
|
|
215
|
+
type: string;
|
|
216
|
+
user?: string;
|
|
217
|
+
username?: string;
|
|
218
|
+
}
|
|
219
|
+
/** Slack reaction event payload */
|
|
220
|
+
interface SlackReactionEvent {
|
|
221
|
+
event_ts: string;
|
|
222
|
+
item: {
|
|
223
|
+
type: string;
|
|
224
|
+
channel: string;
|
|
225
|
+
ts: string;
|
|
226
|
+
};
|
|
227
|
+
item_user?: string;
|
|
228
|
+
reaction: string;
|
|
229
|
+
type: "reaction_added" | "reaction_removed";
|
|
230
|
+
user: string;
|
|
231
|
+
}
|
|
232
|
+
declare class SlackAdapter implements Adapter<SlackThreadId, unknown> {
|
|
233
|
+
readonly name = "slack";
|
|
234
|
+
readonly userName: string;
|
|
235
|
+
private readonly client;
|
|
236
|
+
private readonly signingSecret;
|
|
237
|
+
private readonly webhookVerifier;
|
|
238
|
+
private readonly defaultBotTokenProvider;
|
|
239
|
+
private chat;
|
|
240
|
+
private readonly logger;
|
|
241
|
+
private _botUserId;
|
|
242
|
+
private _botId;
|
|
243
|
+
private readonly formatConverter;
|
|
244
|
+
private static USER_CACHE_TTL_MS;
|
|
245
|
+
private static CHANNEL_CACHE_TTL_MS;
|
|
246
|
+
private static REVERSE_INDEX_TTL_MS;
|
|
247
|
+
/**
|
|
248
|
+
* Cache of channel IDs known to be external/shared (Slack Connect).
|
|
249
|
+
* Populated from `is_ext_shared_channel` in incoming webhook payloads.
|
|
250
|
+
*/
|
|
251
|
+
private readonly _externalChannels;
|
|
252
|
+
private readonly appToken;
|
|
253
|
+
private readonly mode;
|
|
254
|
+
private readonly socketForwardingSecret;
|
|
255
|
+
private socketClient;
|
|
256
|
+
private readonly clientId;
|
|
257
|
+
private readonly clientSecret;
|
|
258
|
+
private readonly encryptionKey;
|
|
259
|
+
private readonly installationKeyPrefix;
|
|
260
|
+
private readonly requestContext;
|
|
261
|
+
/** Bot user ID (e.g., U_BOT_123) used for mention detection */
|
|
262
|
+
get botUserId(): string | undefined;
|
|
263
|
+
get isSocketMode(): boolean;
|
|
264
|
+
constructor(config?: SlackAdapterConfig);
|
|
265
|
+
/**
|
|
266
|
+
* Get the current bot token for API calls.
|
|
267
|
+
* Checks request context (multi-workspace) → default token provider
|
|
268
|
+
* (single-workspace) → throws.
|
|
269
|
+
*/
|
|
270
|
+
private getToken;
|
|
271
|
+
/**
|
|
272
|
+
* Add the current token to API call options.
|
|
273
|
+
* Workaround for Slack WebClient types not including `token` in per-method args.
|
|
274
|
+
*/
|
|
275
|
+
private withToken;
|
|
276
|
+
initialize(chat: ChatInstance): Promise<void>;
|
|
277
|
+
private installationKey;
|
|
278
|
+
/**
|
|
279
|
+
* Save a Slack workspace installation.
|
|
280
|
+
* Call this from your OAuth callback route after a successful installation.
|
|
281
|
+
*/
|
|
282
|
+
setInstallation(teamId: string, installation: SlackInstallation): Promise<void>;
|
|
283
|
+
/**
|
|
284
|
+
* Retrieve a Slack workspace installation.
|
|
285
|
+
*/
|
|
286
|
+
getInstallation(teamId: string): Promise<SlackInstallation | null>;
|
|
287
|
+
/**
|
|
288
|
+
* Handle the Slack OAuth V2 callback.
|
|
289
|
+
* Accepts the incoming request, extracts the authorization code,
|
|
290
|
+
* exchanges it for tokens, and saves the installation.
|
|
291
|
+
*/
|
|
292
|
+
handleOAuthCallback(request: Request, options?: SlackOAuthCallbackOptions): Promise<{
|
|
293
|
+
teamId: string;
|
|
294
|
+
installation: SlackInstallation;
|
|
295
|
+
}>;
|
|
296
|
+
/**
|
|
297
|
+
* Remove a Slack workspace installation.
|
|
298
|
+
*/
|
|
299
|
+
deleteInstallation(teamId: string): Promise<void>;
|
|
300
|
+
/**
|
|
301
|
+
* Run a function with a specific bot token in context.
|
|
302
|
+
* Use this for operations outside webhook handling (cron jobs, workflows).
|
|
303
|
+
*/
|
|
304
|
+
withBotToken<T>(token: string, fn: () => T): T;
|
|
305
|
+
/**
|
|
306
|
+
* Resolve the bot token for a team from the state adapter.
|
|
307
|
+
*/
|
|
308
|
+
private resolveTokenForTeam;
|
|
309
|
+
/**
|
|
310
|
+
* Extract team_id from an interactive payload (form-urlencoded).
|
|
311
|
+
*/
|
|
312
|
+
private extractTeamIdFromInteractive;
|
|
313
|
+
/**
|
|
314
|
+
* Look up user info from Slack API with caching via state adapter.
|
|
315
|
+
* Returns null when the API call fails.
|
|
316
|
+
*/
|
|
317
|
+
private lookupUser;
|
|
318
|
+
/**
|
|
319
|
+
* Look up channel name from Slack API with caching via state adapter.
|
|
320
|
+
* Returns channel name, or falls back to channel ID.
|
|
321
|
+
*/
|
|
322
|
+
private lookupChannel;
|
|
323
|
+
getUser(userId: string): Promise<UserInfo | null>;
|
|
324
|
+
handleWebhook(request: Request, options?: WebhookOptions): Promise<Response>;
|
|
325
|
+
/** Extract and dispatch events from a validated payload */
|
|
326
|
+
private processEventPayload;
|
|
327
|
+
/**
|
|
328
|
+
* Handle Slack interactive payloads (button clicks, view submissions, etc.).
|
|
329
|
+
* These are sent as form-urlencoded with a `payload` JSON field.
|
|
330
|
+
*/
|
|
331
|
+
private handleInteractivePayload;
|
|
332
|
+
/**
|
|
333
|
+
* Dispatch a pre-parsed interactive payload to the correct handler.
|
|
334
|
+
* Used by both webhook and socket mode paths.
|
|
335
|
+
*/
|
|
336
|
+
private dispatchInteractivePayload;
|
|
337
|
+
/**
|
|
338
|
+
* Handle Slack slash command payloads.
|
|
339
|
+
* Slash commands are sent as form-urlencoded with command, text, user_id, channel_id, etc.
|
|
340
|
+
*/
|
|
341
|
+
private handleSlashCommand;
|
|
342
|
+
/**
|
|
343
|
+
* Handle block_actions payload (button clicks in Block Kit).
|
|
344
|
+
*/
|
|
345
|
+
private handleBlockActions;
|
|
346
|
+
private handleBlockSuggestion;
|
|
347
|
+
private optionsLoadResponse;
|
|
348
|
+
private handleViewSubmission;
|
|
349
|
+
private handleViewClosed;
|
|
350
|
+
private modalResponseToSlack;
|
|
351
|
+
private convertModalJSX;
|
|
352
|
+
/**
|
|
353
|
+
* Start Socket Mode connection.
|
|
354
|
+
* Creates a SocketModeClient, registers event handlers, and connects.
|
|
355
|
+
*/
|
|
356
|
+
private startSocketMode;
|
|
357
|
+
/**
|
|
358
|
+
* Route a socket mode event to the appropriate handler.
|
|
359
|
+
*/
|
|
360
|
+
private routeSocketEvent;
|
|
361
|
+
/**
|
|
362
|
+
* Start a transient Socket Mode listener for serverless environments.
|
|
363
|
+
* The listener maintains a WebSocket for `durationMs`, acks events, and
|
|
364
|
+
* forwards them via HTTP POST to the webhook endpoint (or processes directly).
|
|
365
|
+
*
|
|
366
|
+
* @param options - Webhook options with waitUntil function
|
|
367
|
+
* @param durationMs - How long to keep listening (default: 180000ms = 3 minutes)
|
|
368
|
+
* @param abortSignal - Optional signal to stop the listener early
|
|
369
|
+
* @param webhookUrl - URL to forward socket events to (required for forwarding mode)
|
|
370
|
+
*/
|
|
371
|
+
startSocketModeListener(options: WebhookOptions, durationMs?: number, abortSignal?: AbortSignal, webhookUrl?: string): Promise<Response>;
|
|
372
|
+
/**
|
|
373
|
+
* Run the socket mode listener for a specified duration.
|
|
374
|
+
*/
|
|
375
|
+
private runSocketModeListener;
|
|
376
|
+
/**
|
|
377
|
+
* Forward a socket mode event to the webhook endpoint.
|
|
378
|
+
*/
|
|
379
|
+
private forwardSocketEvent;
|
|
380
|
+
/**
|
|
381
|
+
* Disconnect the socket mode client.
|
|
382
|
+
* No-op if not connected.
|
|
383
|
+
*/
|
|
384
|
+
disconnect(): Promise<void>;
|
|
385
|
+
private verifySignature;
|
|
386
|
+
/**
|
|
387
|
+
* Handle message events from Slack.
|
|
388
|
+
* Bot message filtering (isMe) is handled centrally by the Chat class.
|
|
389
|
+
*/
|
|
390
|
+
private handleMessageEvent;
|
|
391
|
+
private handleMessageChanged;
|
|
392
|
+
/**
|
|
393
|
+
* Handle reaction events from Slack (reaction_added, reaction_removed).
|
|
394
|
+
*/
|
|
395
|
+
private handleReactionEvent;
|
|
396
|
+
/**
|
|
397
|
+
* Handle assistant_thread_started events from Slack's Assistants API.
|
|
398
|
+
* Fires when a user opens a new assistant thread (DM with the bot).
|
|
399
|
+
*/
|
|
400
|
+
private handleAssistantThreadStarted;
|
|
401
|
+
/**
|
|
402
|
+
* Handle assistant_thread_context_changed events from Slack's Assistants API.
|
|
403
|
+
* Fires when a user navigates to a different channel with the assistant panel open.
|
|
404
|
+
*/
|
|
405
|
+
private handleAssistantContextChanged;
|
|
406
|
+
/**
|
|
407
|
+
* Handle app_home_opened events from Slack.
|
|
408
|
+
* Fires when a user opens the bot's Home tab.
|
|
409
|
+
*/
|
|
410
|
+
private handleAppHomeOpened;
|
|
411
|
+
/**
|
|
412
|
+
* Handle member_joined_channel events from Slack.
|
|
413
|
+
* Fires when a user (including the bot) joins a channel.
|
|
414
|
+
*/
|
|
415
|
+
private handleMemberJoinedChannel;
|
|
416
|
+
private handleUserChange;
|
|
417
|
+
/**
|
|
418
|
+
* Publish a Home tab view for a user.
|
|
419
|
+
* Slack API: views.publish
|
|
420
|
+
*/
|
|
421
|
+
publishHomeView(userId: string, view: Record<string, unknown>): Promise<void>;
|
|
422
|
+
/**
|
|
423
|
+
* Set suggested prompts for an assistant thread.
|
|
424
|
+
* Slack Assistants API: assistant.threads.setSuggestedPrompts
|
|
425
|
+
*/
|
|
426
|
+
setSuggestedPrompts(channelId: string, threadTs: string, prompts: Array<{
|
|
427
|
+
title: string;
|
|
428
|
+
message: string;
|
|
429
|
+
}>, title?: string): Promise<void>;
|
|
430
|
+
/**
|
|
431
|
+
* Set status/thinking indicator for an assistant thread.
|
|
432
|
+
* Slack Assistants API: assistant.threads.setStatus
|
|
433
|
+
*/
|
|
434
|
+
setAssistantStatus(channelId: string, threadTs: string, status: string, loadingMessages?: string[]): Promise<void>;
|
|
435
|
+
/**
|
|
436
|
+
* Set title for an assistant thread (shown in History tab).
|
|
437
|
+
* Slack Assistants API: assistant.threads.setTitle
|
|
438
|
+
*/
|
|
439
|
+
setAssistantTitle(channelId: string, threadTs: string, title: string): Promise<void>;
|
|
440
|
+
/**
|
|
441
|
+
* Resolve inline user mentions in Slack mrkdwn text.
|
|
442
|
+
* Converts <@U123> to <@U123|displayName> so that toAst/extractPlainText
|
|
443
|
+
* renders them as @displayName instead of @U123.
|
|
444
|
+
*
|
|
445
|
+
* @param skipSelfMention - When true, skips the bot's own user ID so that
|
|
446
|
+
* mention detection (which looks for @botUserId in the text) continues to
|
|
447
|
+
* work. Uses the effective request-scoped bot user ID in multi-workspace
|
|
448
|
+
* mode, not only the adapter's default bot user ID. Set to false when
|
|
449
|
+
* parsing historical/channel messages where mention detection doesn't
|
|
450
|
+
* apply.
|
|
451
|
+
*/
|
|
452
|
+
private resolveInlineMentions;
|
|
453
|
+
/**
|
|
454
|
+
* Extract link URLs from a Slack event.
|
|
455
|
+
* Uses the `blocks` field (rich_text blocks with link elements) when available,
|
|
456
|
+
* falling back to parsing `<url>` patterns from the text field.
|
|
457
|
+
*/
|
|
458
|
+
private extractLinks;
|
|
459
|
+
/**
|
|
460
|
+
* Create a LinkPreview for a URL. If the URL points to a Slack message,
|
|
461
|
+
* includes a `fetchMessage` callback that fetches and parses the linked message.
|
|
462
|
+
*/
|
|
463
|
+
private createLinkPreview;
|
|
464
|
+
private parseSlackMessage;
|
|
465
|
+
private enrichLinks;
|
|
466
|
+
/**
|
|
467
|
+
* Create an Attachment object from a Slack file.
|
|
468
|
+
* Includes a fetchData method that uses the bot token for auth.
|
|
469
|
+
*/
|
|
470
|
+
private createAttachment;
|
|
471
|
+
private fetchSlackFile;
|
|
472
|
+
rehydrateAttachment(attachment: Attachment): Attachment;
|
|
473
|
+
/**
|
|
474
|
+
* Resolve @name mentions in text to Slack <@USER_ID> format using the
|
|
475
|
+
* reverse user cache. When multiple users share a display name, prefers
|
|
476
|
+
* the one who is a participant in the given thread.
|
|
477
|
+
*/
|
|
478
|
+
private resolveOutgoingMentions;
|
|
479
|
+
/**
|
|
480
|
+
* Pre-process an outgoing message to resolve @name mentions before rendering.
|
|
481
|
+
*/
|
|
482
|
+
private resolveMessageMentions;
|
|
483
|
+
postMessage(threadId: string, _message: AdapterPostableMessage): Promise<RawMessage<unknown>>;
|
|
484
|
+
postEphemeral(threadId: string, userId: string, _message: AdapterPostableMessage): Promise<EphemeralMessage>;
|
|
485
|
+
scheduleMessage(threadId: string, _message: AdapterPostableMessage, options: {
|
|
486
|
+
postAt: Date;
|
|
487
|
+
}): Promise<ScheduledMessage>;
|
|
488
|
+
openModal(triggerId: string, modal: ModalElement, contextId?: string): Promise<{
|
|
489
|
+
viewId: string;
|
|
490
|
+
}>;
|
|
491
|
+
updateModal(viewId: string, modal: ModalElement): Promise<{
|
|
492
|
+
viewId: string;
|
|
493
|
+
}>;
|
|
494
|
+
/**
|
|
495
|
+
* Upload files to Slack and share them to a channel.
|
|
496
|
+
* Returns the file IDs of uploaded files.
|
|
497
|
+
*/
|
|
498
|
+
private uploadFiles;
|
|
499
|
+
editMessage(threadId: string, messageId: string, _message: AdapterPostableMessage): Promise<RawMessage<unknown>>;
|
|
500
|
+
postObject(threadId: string, kind: string, data: unknown): Promise<RawMessage<unknown>>;
|
|
501
|
+
editObject(threadId: string, messageId: string, kind: string, data: unknown): Promise<RawMessage<unknown>>;
|
|
502
|
+
private renderPlanFallbackText;
|
|
503
|
+
private planToBlockKit;
|
|
504
|
+
private planContentToPlainText;
|
|
505
|
+
private planContentToRichText;
|
|
506
|
+
deleteMessage(threadId: string, messageId: string): Promise<void>;
|
|
507
|
+
addReaction(threadId: string, messageId: string, emoji: EmojiValue | string): Promise<void>;
|
|
508
|
+
removeReaction(threadId: string, messageId: string, emoji: EmojiValue | string): Promise<void>;
|
|
509
|
+
/**
|
|
510
|
+
* Show typing indicator with optional custom status.
|
|
511
|
+
*
|
|
512
|
+
* When status is provided, uses Slack's assistant.threads.setStatus API
|
|
513
|
+
* to show custom loading text (requires Agents & AI Apps feature and assistant:write scope).
|
|
514
|
+
* The status auto-clears when a message is posted to the thread.
|
|
515
|
+
*
|
|
516
|
+
* When status is not provided, defaults to "Typing..." with default loading messages.
|
|
517
|
+
*
|
|
518
|
+
* @param threadId - The thread to show the indicator in
|
|
519
|
+
* @param status - Optional custom status message (e.g., "Searching documents...")
|
|
520
|
+
*/
|
|
521
|
+
startTyping(threadId: string, status?: string): Promise<void>;
|
|
522
|
+
/**
|
|
523
|
+
* Stream a message using Slack's native streaming API.
|
|
524
|
+
*
|
|
525
|
+
* Consumes an async iterable of text chunks and/or structured StreamChunk
|
|
526
|
+
* objects (task_update, plan_update, markdown_text) and streams them to Slack.
|
|
527
|
+
*
|
|
528
|
+
* Plain strings are rendered through StreamingMarkdownRenderer for safe
|
|
529
|
+
* incremental markdown. StreamChunk objects are passed directly to Slack's
|
|
530
|
+
* streaming API as chunk payloads, enabling native task progress cards
|
|
531
|
+
* and plan displays in the Slack AI Assistant UI.
|
|
532
|
+
*
|
|
533
|
+
* Requires `recipientUserId` and `recipientTeamId` in options.
|
|
534
|
+
*/
|
|
535
|
+
stream(threadId: string, textStream: AsyncIterable<string | StreamChunk>, options?: StreamOptions): Promise<RawMessage<unknown>>;
|
|
536
|
+
/**
|
|
537
|
+
* Open a direct message conversation with a user.
|
|
538
|
+
* Returns a thread ID that can be used to post messages.
|
|
539
|
+
*/
|
|
540
|
+
openDM(userId: string): Promise<string>;
|
|
541
|
+
fetchMessages(threadId: string, options?: FetchOptions): Promise<FetchResult<unknown>>;
|
|
542
|
+
/**
|
|
543
|
+
* Fetch messages in forward direction (oldest first, efficient).
|
|
544
|
+
* Uses native Slack cursor pagination.
|
|
545
|
+
*/
|
|
546
|
+
private fetchMessagesForward;
|
|
547
|
+
/**
|
|
548
|
+
* Fetch messages in backward direction (most recent first).
|
|
549
|
+
*
|
|
550
|
+
* Slack's API returns oldest-first, so for backward direction we:
|
|
551
|
+
* 1. Use `latest` parameter to fetch messages before a timestamp (cursor)
|
|
552
|
+
* 2. Fetch up to 1000 messages (API limit) and take the last N
|
|
553
|
+
* 3. Return messages in chronological order (oldest first within the page)
|
|
554
|
+
*
|
|
555
|
+
* Note: For very large threads (>1000 messages), the first backward call
|
|
556
|
+
* may not return the absolute most recent messages. This is a Slack API limitation.
|
|
557
|
+
*/
|
|
558
|
+
private fetchMessagesBackward;
|
|
559
|
+
fetchThread(threadId: string): Promise<ThreadInfo>;
|
|
560
|
+
/**
|
|
561
|
+
* Fetch a single message by ID (timestamp).
|
|
562
|
+
*/
|
|
563
|
+
fetchMessage(threadId: string, messageId: string): Promise<Message<unknown> | null>;
|
|
564
|
+
encodeThreadId(platformData: SlackThreadId): string;
|
|
565
|
+
/**
|
|
566
|
+
* Check if a thread is a direct message conversation.
|
|
567
|
+
* Slack DM channel IDs start with 'D'.
|
|
568
|
+
*/
|
|
569
|
+
isDM(threadId: string): boolean;
|
|
570
|
+
/**
|
|
571
|
+
* Get the visibility scope of a channel containing the thread.
|
|
572
|
+
*
|
|
573
|
+
* - `external`: Slack Connect channel shared with external organizations
|
|
574
|
+
* - `private`: Private channel (starts with G) or DM (starts with D)
|
|
575
|
+
* - `workspace`: Public channel visible to all workspace members
|
|
576
|
+
* - `unknown`: Visibility cannot be determined (not yet cached)
|
|
577
|
+
*/
|
|
578
|
+
getChannelVisibility(threadId: string): ChannelVisibility;
|
|
579
|
+
decodeThreadId(threadId: string): SlackThreadId;
|
|
580
|
+
parseMessage(raw: SlackEvent): Message<unknown>;
|
|
581
|
+
/**
|
|
582
|
+
* Synchronous message parsing without user lookup.
|
|
583
|
+
* Used for parseMessage interface - falls back to user ID for username.
|
|
584
|
+
*/
|
|
585
|
+
private parseSlackMessageSync;
|
|
586
|
+
/**
|
|
587
|
+
* Derive channel ID from a Slack thread ID.
|
|
588
|
+
* Slack thread IDs are "slack:CHANNEL:THREAD_TS", channel ID is "slack:CHANNEL".
|
|
589
|
+
*/
|
|
590
|
+
channelIdFromThreadId(threadId: string): string;
|
|
591
|
+
/**
|
|
592
|
+
* Fetch channel-level messages (conversations.history, not thread replies).
|
|
593
|
+
*/
|
|
594
|
+
fetchChannelMessages(channelId: string, options?: FetchOptions): Promise<FetchResult<unknown>>;
|
|
595
|
+
private fetchChannelMessagesForward;
|
|
596
|
+
private fetchChannelMessagesBackward;
|
|
597
|
+
/**
|
|
598
|
+
* List threads in a Slack channel.
|
|
599
|
+
* Fetches channel history and filters for messages with replies.
|
|
600
|
+
*/
|
|
601
|
+
listThreads(channelId: string, options?: ListThreadsOptions): Promise<ListThreadsResult<unknown>>;
|
|
602
|
+
/**
|
|
603
|
+
* Fetch Slack channel info/metadata.
|
|
604
|
+
*/
|
|
605
|
+
fetchChannelInfo(channelId: string): Promise<ChannelInfo>;
|
|
606
|
+
/**
|
|
607
|
+
* Post a top-level message to a channel (not in a thread).
|
|
608
|
+
*/
|
|
609
|
+
postChannelMessage(channelId: string, message: AdapterPostableMessage): Promise<RawMessage<unknown>>;
|
|
610
|
+
renderFormatted(content: FormattedContent): string;
|
|
611
|
+
/**
|
|
612
|
+
* Check if a Slack event is from this bot.
|
|
613
|
+
*
|
|
614
|
+
* Slack messages can come from:
|
|
615
|
+
* - User messages: have `user` field (U_xxx format)
|
|
616
|
+
* - Bot messages: have `bot_id` field (B_xxx format)
|
|
617
|
+
*
|
|
618
|
+
* We check both because:
|
|
619
|
+
* - _botUserId is the user ID (U_xxx) - matches event.user
|
|
620
|
+
* - _botId is the bot ID (B_xxx) - matches event.bot_id
|
|
621
|
+
*/
|
|
622
|
+
private isMessageFromSelf;
|
|
623
|
+
private handleSlackError;
|
|
624
|
+
/**
|
|
625
|
+
* Encode response_url and userId into messageId for ephemeral messages.
|
|
626
|
+
* This allows edit/delete operations to work via response_url.
|
|
627
|
+
*/
|
|
628
|
+
private encodeEphemeralMessageId;
|
|
629
|
+
/**
|
|
630
|
+
* Decode ephemeral messageId to extract messageTs, responseUrl, and userId.
|
|
631
|
+
* Returns null if the messageId is not an ephemeral encoding.
|
|
632
|
+
*/
|
|
633
|
+
private decodeEphemeralMessageId;
|
|
634
|
+
/**
|
|
635
|
+
* Send a request to Slack's response_url to modify an ephemeral message.
|
|
636
|
+
*/
|
|
637
|
+
private sendToResponseUrl;
|
|
61
638
|
}
|
|
639
|
+
declare function createSlackAdapter(config?: Partial<SlackAdapterConfig>): SlackAdapter;
|
|
62
640
|
|
|
63
|
-
export
|
|
641
|
+
export { SlackAdapter, type SlackAdapterConfig, type SlackAdapterMode, type SlackBotToken, type SlackEvent, SlackFormatConverter, type SlackInstallation, SlackFormatConverter as SlackMarkdownConverter, type SlackOAuthCallbackOptions, type SlackReactionEvent, type SlackThreadId, cardToBlockKit, cardToFallbackText, createSlackAdapter };
|