@zhin.js/adapter-slack 1.1.18 → 1.1.20
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 +45 -0
- package/README.md +12 -5
- package/adapters/slack/index.js +3 -23
- package/adapters/slack/index.ts +2 -23
- package/agents/slack/skills/slack-messages/tools/edit_message/index.js +3 -3
- package/agents/slack/skills/slack-messages/tools/edit_message/index.ts +2 -2
- package/commands/slack/endpoint/definition.js +0 -2
- package/commands/slack/endpoint/definition.ts +0 -2
- package/lib/adapter.d.ts +16 -0
- package/lib/adapter.js +54 -0
- package/lib/client.d.ts +3 -7
- package/lib/client.js +1 -2
- package/lib/console-spec.js +6 -0
- package/lib/console.d.ts +1 -7
- package/lib/console.js +2 -5
- package/lib/endpoint.d.ts +12 -115
- package/lib/endpoint.js +237 -183
- package/lib/index.d.ts +2 -1
- package/lib/index.js +1 -1
- package/lib/protocol.d.ts +8 -2
- package/lib/slack-outbound.d.ts +16 -12
- package/lib/slack-outbound.js +28 -19
- package/lib/web-client.d.ts +1 -0
- package/lib/web-client.js +4 -1
- package/package.json +18 -18
- package/plugin.js +1 -4
- package/src/adapter.ts +38 -0
- package/src/client.ts +2 -10
- package/src/console-spec.ts +6 -0
- package/src/console.ts +2 -6
- package/src/endpoint.ts +239 -226
- package/src/index.ts +1 -1
- package/src/protocol.ts +7 -4
- package/src/slack-outbound.ts +50 -37
- package/src/web-client.ts +5 -1
- package/lib/slack-runtime-state.d.ts +0 -1
- package/lib/slack-runtime-state.js +0 -6
- package/src/slack-runtime-state.ts +0 -7
package/lib/protocol.d.ts
CHANGED
|
@@ -109,6 +109,12 @@ export interface SlackWireSegment {
|
|
|
109
109
|
readonly type: string;
|
|
110
110
|
readonly data?: Record<string, unknown>;
|
|
111
111
|
}
|
|
112
|
+
/** Every block emitted by the encoder has Slack's required native block discriminator. */
|
|
113
|
+
export interface SlackBlock {
|
|
114
|
+
readonly type: string;
|
|
115
|
+
readonly block_id?: string;
|
|
116
|
+
readonly [key: string]: unknown;
|
|
117
|
+
}
|
|
112
118
|
export declare function resolveSlackConfig(config: SlackEndpointConfig): ResolvedSlackConfig;
|
|
113
119
|
export declare function normalizeWebhookPath(path: string): string;
|
|
114
120
|
export declare function resolveSlackChannelType(event: Pick<SlackEvent, 'channel_type'>): 'private' | 'group';
|
|
@@ -133,7 +139,7 @@ export declare function formatSlashContent(cmd: SlackSlashCommand): string;
|
|
|
133
139
|
export declare function formatOutboundWire(payload: unknown): {
|
|
134
140
|
replyTo?: string;
|
|
135
141
|
text: string;
|
|
136
|
-
blocks:
|
|
142
|
+
blocks: SlackBlock[];
|
|
137
143
|
attachments: Record<string, unknown>[];
|
|
138
144
|
files: Array<{
|
|
139
145
|
buffer?: Buffer;
|
|
@@ -142,7 +148,7 @@ export declare function formatOutboundWire(payload: unknown): {
|
|
|
142
148
|
name?: string;
|
|
143
149
|
}>;
|
|
144
150
|
};
|
|
145
|
-
export declare function keyboardToBlockKitBlocks(data: Record<string, unknown>):
|
|
151
|
+
export declare function keyboardToBlockKitBlocks(data: Record<string, unknown>): SlackBlock[];
|
|
146
152
|
export declare function verifySlackSignature(signingSecret: string, rawBody: string, timestamp: string, signature: string): boolean;
|
|
147
153
|
export declare function readTextBody(request: IncomingMessage, options?: {
|
|
148
154
|
readonly limit?: number;
|
package/lib/slack-outbound.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Slack outbound — chat.postMessage + Block Kit + files.uploadV2
|
|
3
|
-
*/
|
|
4
1
|
import type { Logger } from '@zhin.js/logger';
|
|
2
|
+
import type { WebClient } from '@slack/web-api';
|
|
5
3
|
import { keyboardToBlockKitBlocks } from './protocol.js';
|
|
6
4
|
export interface SlackOutboundResult {
|
|
7
5
|
ts: string;
|
|
@@ -11,14 +9,20 @@ export interface SlackSendOptions {
|
|
|
11
9
|
threadTs?: string;
|
|
12
10
|
}
|
|
13
11
|
export interface SlackChatClient {
|
|
14
|
-
chat:
|
|
15
|
-
|
|
16
|
-
ts?: string;
|
|
17
|
-
}>;
|
|
18
|
-
update(opts: Record<string, unknown>): Promise<unknown>;
|
|
19
|
-
};
|
|
20
|
-
filesUploadV2?(opts: Record<string, unknown>): Promise<unknown>;
|
|
12
|
+
chat: Pick<WebClient['chat'], 'postMessage' | 'update'>;
|
|
13
|
+
filesUploadV2?: WebClient['filesUploadV2'];
|
|
21
14
|
}
|
|
22
|
-
export
|
|
23
|
-
|
|
15
|
+
export interface SlackContentRequest extends SlackSendOptions {
|
|
16
|
+
readonly content: unknown;
|
|
17
|
+
readonly logger: Logger;
|
|
18
|
+
readonly signal?: AbortSignal;
|
|
19
|
+
}
|
|
20
|
+
export interface SlackEditRequest {
|
|
21
|
+
readonly channel: string;
|
|
22
|
+
readonly ts: string;
|
|
23
|
+
readonly content: unknown;
|
|
24
|
+
readonly signal?: AbortSignal;
|
|
25
|
+
}
|
|
26
|
+
export declare function sendSlackContent(client: SlackChatClient, { content, logger, signal, ...opts }: SlackContentRequest): Promise<SlackOutboundResult>;
|
|
27
|
+
export declare function editSlackContent(client: SlackChatClient, { channel, ts, content, signal }: SlackEditRequest): Promise<void>;
|
|
24
28
|
export { keyboardToBlockKitBlocks };
|
package/lib/slack-outbound.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slack outbound — chat.postMessage + Block Kit + files.uploadV2
|
|
3
|
+
*/
|
|
4
|
+
import { createEndpointOperation } from 'zhin.js/adapter';
|
|
1
5
|
import { markdownToMrkdwn, mrkdwnToPlainFallback, splitMrkdwnText } from './markdown-to-mrkdwn.js';
|
|
2
6
|
import { formatOutboundWire, keyboardToBlockKitBlocks } from './protocol.js';
|
|
3
7
|
const SLACK_MAX_BLOCKS_PER_MESSAGE = 48;
|
|
4
|
-
export async function sendSlackContent(client, content,
|
|
8
|
+
export async function sendSlackContent(client, { content, logger, signal, ...opts }) {
|
|
9
|
+
const operation = createEndpointOperation({ signal });
|
|
5
10
|
const wire = formatOutboundWire(content);
|
|
6
11
|
const threadTs = opts.threadTs ?? wire.replyTo;
|
|
7
12
|
const blocks = [...wire.blocks];
|
|
8
13
|
const textDelivery = applyTextMrkdwnBlocks(wire.text, blocks);
|
|
9
14
|
for (const pf of wire.files) {
|
|
10
15
|
try {
|
|
11
|
-
await uploadFile(client, opts.channel, pf, threadTs);
|
|
16
|
+
await uploadFile(client, { channel: opts.channel, file: pf, threadTs, operation });
|
|
12
17
|
}
|
|
13
18
|
catch (e) {
|
|
14
19
|
logger.error('Failed to upload file:', e);
|
|
@@ -18,12 +23,13 @@ export async function sendSlackContent(client, content, opts, logger) {
|
|
|
18
23
|
return postSlackMessage(client, {
|
|
19
24
|
channel: opts.channel,
|
|
20
25
|
threadTs,
|
|
26
|
+
operation,
|
|
21
27
|
blocks,
|
|
22
28
|
attachments: wire.attachments,
|
|
23
29
|
fallbackText: textDelivery.fallbackText,
|
|
24
30
|
});
|
|
25
31
|
}
|
|
26
|
-
export async function editSlackContent(client, channel, ts, content) {
|
|
32
|
+
export async function editSlackContent(client, { channel, ts, content, signal }) {
|
|
27
33
|
const wire = formatOutboundWire(content);
|
|
28
34
|
const blocks = [...wire.blocks];
|
|
29
35
|
const textDelivery = applyTextMrkdwnBlocks(wire.text, blocks);
|
|
@@ -35,7 +41,7 @@ export async function editSlackContent(client, channel, ts, content) {
|
|
|
35
41
|
};
|
|
36
42
|
if (payloadBlocks.length > 0)
|
|
37
43
|
updateOpts.blocks = payloadBlocks;
|
|
38
|
-
await client.chat.update(updateOpts);
|
|
44
|
+
await createEndpointOperation({ signal }).run(() => client.chat.update(updateOpts));
|
|
39
45
|
}
|
|
40
46
|
function applyTextMrkdwnBlocks(textContent, blocks) {
|
|
41
47
|
const trimmed = textContent.trim();
|
|
@@ -54,27 +60,27 @@ function applyTextMrkdwnBlocks(textContent, blocks) {
|
|
|
54
60
|
return { fallbackText: mrkdwnToPlainFallback(mrkdwn) };
|
|
55
61
|
}
|
|
56
62
|
async function postSlackMessage(client, opts) {
|
|
57
|
-
const { channel, blocks, attachments, fallbackText } = opts;
|
|
63
|
+
const { channel, blocks, attachments, fallbackText, operation } = opts;
|
|
58
64
|
let threadTs = opts.threadTs;
|
|
59
65
|
let firstTs = '';
|
|
60
66
|
if (blocks.length === 0) {
|
|
61
|
-
const result = await client.chat.postMessage({
|
|
67
|
+
const result = await operation.run(() => client.chat.postMessage({
|
|
62
68
|
channel,
|
|
63
69
|
text: fallbackText || 'Message',
|
|
64
70
|
...(threadTs ? { thread_ts: threadTs } : {}),
|
|
65
71
|
...(attachments.length > 0 ? { attachments } : {}),
|
|
66
|
-
});
|
|
72
|
+
}));
|
|
67
73
|
return { ts: requireMessageTimestamp(result) };
|
|
68
74
|
}
|
|
69
75
|
for (let offset = 0; offset < blocks.length; offset += SLACK_MAX_BLOCKS_PER_MESSAGE) {
|
|
70
76
|
const chunk = blocks.slice(offset, offset + SLACK_MAX_BLOCKS_PER_MESSAGE);
|
|
71
|
-
const result = await client.chat.postMessage({
|
|
77
|
+
const result = await operation.run(() => client.chat.postMessage({
|
|
72
78
|
channel,
|
|
73
79
|
text: offset === 0 ? (fallbackText || ' ') : ' ',
|
|
74
80
|
blocks: chunk,
|
|
75
81
|
...(threadTs ? { thread_ts: threadTs } : {}),
|
|
76
82
|
...(offset === 0 && attachments.length > 0 ? { attachments } : {}),
|
|
77
|
-
});
|
|
83
|
+
}));
|
|
78
84
|
const ts = requireMessageTimestamp(result);
|
|
79
85
|
if (!firstTs)
|
|
80
86
|
firstTs = ts;
|
|
@@ -89,24 +95,27 @@ function requireMessageTimestamp(result) {
|
|
|
89
95
|
}
|
|
90
96
|
return result.ts;
|
|
91
97
|
}
|
|
92
|
-
async function uploadFile(client, channel, file, threadTs) {
|
|
93
|
-
|
|
98
|
+
async function uploadFile(client, { channel, file, threadTs, operation }) {
|
|
99
|
+
const upload = client.filesUploadV2;
|
|
100
|
+
if (!upload)
|
|
94
101
|
throw new Error('Slack client does not support file uploads');
|
|
102
|
+
const { path, url } = file;
|
|
95
103
|
let buffer = file.buffer;
|
|
96
|
-
if (!buffer &&
|
|
97
|
-
const { readFile } = await import('node:fs/promises');
|
|
98
|
-
buffer = await readFile(
|
|
104
|
+
if (!buffer && path) {
|
|
105
|
+
const { readFile } = await operation.prepare(() => import('node:fs/promises'));
|
|
106
|
+
buffer = await operation.prepare(() => readFile(path));
|
|
99
107
|
}
|
|
100
|
-
if (!buffer &&
|
|
101
|
-
const res = await fetch(
|
|
108
|
+
if (!buffer && url) {
|
|
109
|
+
const res = await operation.prepare(() => fetch(url, { signal: operation.signal }));
|
|
102
110
|
if (!res.ok)
|
|
103
111
|
throw new Error(`fetch ${file.url}: ${res.status}`);
|
|
104
|
-
buffer = Buffer.from(await res.arrayBuffer());
|
|
112
|
+
buffer = Buffer.from(await operation.prepare(() => res.arrayBuffer()));
|
|
105
113
|
}
|
|
106
114
|
if (!buffer)
|
|
107
115
|
throw new Error('Slack file contains no uploadable content');
|
|
108
|
-
|
|
116
|
+
const options = threadTs
|
|
109
117
|
? { channel_id: channel, file: buffer, filename: file.name ?? 'file', thread_ts: threadTs }
|
|
110
|
-
: { channel_id: channel, file: buffer, filename: file.name ?? 'file' }
|
|
118
|
+
: { channel_id: channel, file: buffer, filename: file.name ?? 'file' };
|
|
119
|
+
await operation.run(() => upload.call(client, options));
|
|
111
120
|
}
|
|
112
121
|
export { keyboardToBlockKitBlocks };
|
package/lib/web-client.d.ts
CHANGED
|
@@ -2,4 +2,5 @@ import { WebClient, type WebClientOptions } from '@slack/web-api';
|
|
|
2
2
|
import { EndpointDeliveryError } from '@zhin.js/im-contract';
|
|
3
3
|
/** A non-idempotent outbound API call gets exactly one transport attempt. */
|
|
4
4
|
export declare function createSlackWebClient(token: string, options?: WebClientOptions): WebClient;
|
|
5
|
+
export declare function slackWebClientOptions(options?: WebClientOptions): WebClientOptions;
|
|
5
6
|
export declare function slackDeliveryError(error: unknown): EndpointDeliveryError;
|
package/lib/web-client.js
CHANGED
|
@@ -2,7 +2,10 @@ import { WebClient, ErrorCode } from '@slack/web-api';
|
|
|
2
2
|
import { EndpointDeliveryError } from '@zhin.js/im-contract';
|
|
3
3
|
/** A non-idempotent outbound API call gets exactly one transport attempt. */
|
|
4
4
|
export function createSlackWebClient(token, options = {}) {
|
|
5
|
-
return new WebClient(token,
|
|
5
|
+
return new WebClient(token, slackWebClientOptions(options));
|
|
6
|
+
}
|
|
7
|
+
export function slackWebClientOptions(options = {}) {
|
|
8
|
+
return { ...options, retryConfig: { retries: 0 }, rejectRateLimitedCalls: true };
|
|
6
9
|
}
|
|
7
10
|
export function slackDeliveryError(error) {
|
|
8
11
|
if (error instanceof EndpointDeliveryError)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-slack",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.20",
|
|
4
4
|
"description": "Zhin.js Slack adapter for Plugin Runtime (Socket Mode / HTTP Events)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -33,27 +33,27 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@slack/socket-mode": "^2.0.7",
|
|
35
35
|
"@slack/web-api": "^7.19.0",
|
|
36
|
-
"@zhin.js/adapter": "1.1.
|
|
37
|
-
"@zhin.js/agent-feature": "1.1.
|
|
38
|
-
"@zhin.js/client": "1.1.
|
|
36
|
+
"@zhin.js/adapter": "1.1.26",
|
|
37
|
+
"@zhin.js/agent-feature": "1.1.11",
|
|
38
|
+
"@zhin.js/client": "1.1.22",
|
|
39
39
|
"@zhin.js/console-contract": "1.1.3",
|
|
40
|
-
"@zhin.js/core": "1.1.
|
|
41
|
-
"@zhin.js/feature-kit": "1.1.
|
|
42
|
-
"@zhin.js/host-http": "1.1.
|
|
40
|
+
"@zhin.js/core": "1.1.54",
|
|
41
|
+
"@zhin.js/feature-kit": "1.1.10",
|
|
42
|
+
"@zhin.js/host-http": "1.1.12",
|
|
43
43
|
"@zhin.js/im-contract": "1.1.9",
|
|
44
44
|
"@zhin.js/logger": "1.1.2",
|
|
45
|
-
"@zhin.js/page": "1.1.
|
|
46
|
-
"@zhin.js/skill": "1.1.
|
|
47
|
-
"@zhin.js/tool": "1.1.
|
|
45
|
+
"@zhin.js/page": "1.1.12",
|
|
46
|
+
"@zhin.js/skill": "1.1.11",
|
|
47
|
+
"@zhin.js/tool": "1.1.13"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"zod": "^4.0.0",
|
|
51
|
-
"@zhin.js/adapter": "^1.1.
|
|
52
|
-
"@zhin.js/command": "^1.1.
|
|
53
|
-
"@zhin.js/core": "^1.1.
|
|
54
|
-
"@zhin.js/host-http": "^1.1.
|
|
55
|
-
"@zhin.js/permission": "^1.1.
|
|
56
|
-
"zhin.js": "^1.1.
|
|
51
|
+
"@zhin.js/adapter": "^1.1.26",
|
|
52
|
+
"@zhin.js/command": "^1.1.12",
|
|
53
|
+
"@zhin.js/core": "^1.1.54",
|
|
54
|
+
"@zhin.js/host-http": "^1.1.12",
|
|
55
|
+
"@zhin.js/permission": "^1.1.10",
|
|
56
|
+
"zhin.js": "^1.1.19"
|
|
57
57
|
},
|
|
58
58
|
"peerDependenciesMeta": {
|
|
59
59
|
"@zhin.js/command": {
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"typescript": "^6.0.3",
|
|
72
72
|
"vitest": "^4.1.10",
|
|
73
73
|
"zod": "^4.4.3",
|
|
74
|
-
"zhin.js": "1.1.
|
|
74
|
+
"zhin.js": "1.1.19"
|
|
75
75
|
},
|
|
76
76
|
"files": [
|
|
77
77
|
"adapters",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"features": [
|
|
104
104
|
{
|
|
105
105
|
"package": "@zhin.js/adapter",
|
|
106
|
-
"api": "^
|
|
106
|
+
"api": "^2.0.0"
|
|
107
107
|
},
|
|
108
108
|
{
|
|
109
109
|
"package": "@zhin.js/command",
|
package/plugin.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
-
import { createEndpointRuntimeState } from 'zhin.js/adapter';
|
|
3
2
|
import { definePlugin, pluginConsoleRpcToken } from 'zhin.js';
|
|
4
3
|
import { permissionHostToken } from '@zhin.js/permission';
|
|
5
4
|
import { checkSlackPlatformPermit } from "./lib/platform-permit.js";
|
|
6
|
-
import { slackRuntimeStateToken } from "./lib/slack-runtime-state.js";
|
|
7
5
|
import { createSlackConsoleRpc } from "./lib/console.js";
|
|
8
6
|
export default definePlugin({
|
|
9
7
|
name: 'slack',
|
|
@@ -11,8 +9,7 @@ export default definePlugin({
|
|
|
11
9
|
displayName: 'Slack Adapter',
|
|
12
10
|
},
|
|
13
11
|
setup(context) {
|
|
14
|
-
context.resources.provide(
|
|
15
|
-
context.resources.provide(pluginConsoleRpcToken, createSlackConsoleRpc(context.resources, () => context.config.get()));
|
|
12
|
+
context.resources.provide(pluginConsoleRpcToken, createSlackConsoleRpc(() => context.config.get()));
|
|
16
13
|
if (context.resources.has(permissionHostToken)) {
|
|
17
14
|
const host = context.resources.use(permissionHostToken);
|
|
18
15
|
return host.registerPlatform('slack', checkSlackPlatformPermit);
|
package/src/adapter.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Adapter, type AdapterContext, type EndpointCreationContext } from 'zhin.js/adapter';
|
|
2
|
+
import { httpHostToken } from '@zhin.js/host-http';
|
|
3
|
+
import { WebClient, type WebClientOptions } from '@slack/web-api';
|
|
4
|
+
import { SlackEndpoint } from './endpoint.js';
|
|
5
|
+
import { slackWebClientOptions } from './web-client.js';
|
|
6
|
+
import { createSlackWebApiAgent } from './web-api-proxy.js';
|
|
7
|
+
import { resolveSlackConfig, type SlackEndpointConfig } from './protocol.js';
|
|
8
|
+
import type { SlackClientEventMap } from './client.js';
|
|
9
|
+
|
|
10
|
+
export class SlackAdapter extends Adapter<SlackEndpoint, SlackEndpointConfig, SlackClientEventMap> {
|
|
11
|
+
constructor(private readonly context: AdapterContext<SlackEndpointConfig>, private readonly webOptions: WebClientOptions = {}) { super(); }
|
|
12
|
+
override get configurationIdentityFields(): readonly string[] { return ['id']; }
|
|
13
|
+
override get configurationIdentityProbeFields(): readonly string[] { return ['token', 'appToken', 'signingSecret']; }
|
|
14
|
+
override get configurationUpdateFields(): readonly string[] { return ['token', 'appToken', 'signingSecret', 'socketMode',
|
|
15
|
+
'webhookPath', 'clientPingTimeout', 'webApiProxy', 'webApiProxy.port', 'streamProxy', 'streamProxy.port', 'streamProxy.serverName']; }
|
|
16
|
+
protected override validateConfiguration(config: SlackEndpointConfig): void { resolveSlackConfig(config); }
|
|
17
|
+
protected override async identifyConfiguration(input: SlackEndpointConfig, signal: AbortSignal, changedFields: readonly string[]): Promise<string | undefined> {
|
|
18
|
+
// Neither the app-level token nor the callback signing secret has a readonly identity API.
|
|
19
|
+
if (changedFields.some(field => field !== 'token')) return undefined;
|
|
20
|
+
const config = resolveSlackConfig(input);
|
|
21
|
+
const agent = config.webApiProxy ? createSlackWebApiAgent(config.webApiProxy) : undefined;
|
|
22
|
+
const client = new WebClient(config.token, slackWebClientOptions({ ...this.webOptions, ...(agent ? { agent } : {}),
|
|
23
|
+
requestInterceptor: request => { request.signal = signal; return request; } }));
|
|
24
|
+
try {
|
|
25
|
+
const me = await client.auth.test();
|
|
26
|
+
if (typeof me.team_id !== 'string' || !me.team_id.trim()
|
|
27
|
+
|| typeof me.user_id !== 'string' || !me.user_id.trim()) throw new Error('Slack identity response is incomplete');
|
|
28
|
+
return JSON.stringify(['slack', me.team_id, me.user_id]);
|
|
29
|
+
} finally { agent?.destroy(); }
|
|
30
|
+
}
|
|
31
|
+
protected createEndpoint(input: SlackEndpointConfig, execution: EndpointCreationContext): SlackEndpoint {
|
|
32
|
+
const config = resolveSlackConfig(input);
|
|
33
|
+
const webApiAgent = config.webApiProxy ? createSlackWebApiAgent(config.webApiProxy) : undefined;
|
|
34
|
+
try { return new SlackEndpoint({ id: execution.canonicalId, config, webApiAgent, webOptions: this.webOptions,
|
|
35
|
+
...(config.mode === 'http' ? { http: this.context.use(httpHostToken) } : {}) }); }
|
|
36
|
+
catch (error) { webApiAgent?.destroy(); throw error; }
|
|
37
|
+
}
|
|
38
|
+
}
|
package/src/client.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { SlackWebClientLike } from './endpoint.js';
|
|
1
|
+
import type { SlackAdapter } from './adapter.js';
|
|
3
2
|
import type { SlackEvent } from './protocol.js';
|
|
4
3
|
|
|
5
4
|
/** Slack users.info response fields projected by the bundled tools. */
|
|
@@ -19,12 +18,5 @@ export interface SlackUserInfo {
|
|
|
19
18
|
export type SlackClientEventMap = Record<string, SlackEvent>;
|
|
20
19
|
|
|
21
20
|
declare module '@zhin.js/feature-kit' {
|
|
22
|
-
interface
|
|
23
|
-
readonly slack: {
|
|
24
|
-
readonly client: SlackWebClientLike;
|
|
25
|
-
readonly events: SlackClientEventMap;
|
|
26
|
-
};
|
|
27
|
-
}
|
|
21
|
+
interface AdapterRegistry { readonly slack: SlackAdapter; }
|
|
28
22
|
}
|
|
29
|
-
|
|
30
|
-
export const slackClient = defineEndpointClient<SlackWebClientLike, SlackClientEventMap>('slack');
|
package/src/console-spec.ts
CHANGED
|
@@ -10,6 +10,12 @@ export const slackConsoleSpec = {
|
|
|
10
10
|
{ key: 'token', required: true, env: true, description: 'Bot User OAuth Token(xoxb-...)' },
|
|
11
11
|
{ key: 'signingSecret', env: true, description: '签名密钥(HTTP Events,socketMode: false 必填)', descriptionI18n: { en: 'Signing secret (required for HTTP Events)' } },
|
|
12
12
|
{ key: 'appToken', env: true, description: 'App-Level Token(xapp-...,Socket Mode)', descriptionI18n: { en: 'App-level token (xapp-..., Socket Mode)' } },
|
|
13
|
+
{ key: 'socketMode', type: 'boolean', description: 'Socket Mode; false selects HTTP Events' },
|
|
14
|
+
{ key: 'webhookPath', description: 'HTTP Events route' },
|
|
15
|
+
{ key: 'clientPingTimeout', type: 'number', description: 'SDK client ping timeout in milliseconds' },
|
|
16
|
+
{ key: 'webApiProxy.port', type: 'number', description: 'Configured Web API loopback proxy port' },
|
|
17
|
+
{ key: 'streamProxy.port', type: 'number', description: 'Configured Socket Mode loopback proxy port' },
|
|
18
|
+
{ key: 'streamProxy.serverName', description: 'Expected Socket Mode TLS hostname' },
|
|
13
19
|
] as readonly AdapterConsoleField[],
|
|
14
20
|
docsUrl: 'https://zhin.js.org/adapters/slack',
|
|
15
21
|
readPermission: 'slack:read',
|
package/src/console.ts
CHANGED
|
@@ -3,19 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 页面绑定 `pages/index`,读取 / 写入分别要求 `<adapter>:read` / `<adapter>:write`。
|
|
5
5
|
*/
|
|
6
|
-
import { createAdapterConsoleRpc
|
|
6
|
+
import { createAdapterConsoleRpc } from 'zhin.js/adapter';
|
|
7
7
|
import type { PluginConsoleRpc } from 'zhin.js';
|
|
8
|
-
import { slackRuntimeStateToken } from './slack-runtime-state.js';
|
|
9
8
|
import { slackConsoleSpec } from './console-spec.js';
|
|
10
9
|
|
|
11
10
|
export function createSlackConsoleRpc(
|
|
12
|
-
resources: AdapterConsoleResources,
|
|
13
11
|
getConfig: () => unknown,
|
|
14
12
|
): PluginConsoleRpc {
|
|
15
|
-
const state = resources.use(slackRuntimeStateToken);
|
|
16
13
|
return createAdapterConsoleRpc({
|
|
17
14
|
...slackConsoleSpec,
|
|
18
|
-
running: () => state.endpoints.values(),
|
|
19
15
|
getConfig,
|
|
20
|
-
}
|
|
16
|
+
});
|
|
21
17
|
}
|