@openclaw/slack 2026.7.2-beta.2 → 2026.7.2-beta.3
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/dist/{account-configured-DzC407uv.js → account-configured-BwfXBo_F.js} +1 -1
- package/dist/{account-inspect-Di7ditqZ.js → account-inspect-Bvbtu3iH.js} +9 -2
- package/dist/account-inspect-api.js +1 -1
- package/dist/{accounts-BOJJiHSr.js → accounts-DQEbYKh9.js} +9 -0
- package/dist/accounts.runtime-BIKmJdtJ.js +2 -0
- package/dist/{action-runtime-Cee2ih0s.js → action-runtime-DqkRwO3Z.js} +10 -16
- package/dist/action-runtime.runtime-DEWOcFM4.js +2 -0
- package/dist/{actions-BZiuSTIq.js → actions-CF0tUY5q.js} +4 -4
- package/dist/{actions.runtime-DoD0-gxw.js → actions.runtime-hCbx4RXg.js} +1 -1
- package/dist/api.js +13 -14
- package/dist/{approval-handler.runtime-CUPtIM4k.js → approval-handler.runtime-Em8I1-8-.js} +2 -2
- package/dist/{channel-DaIiGUOp.js → channel-4-TRi1D6.js} +72 -40
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-type-Cfm6_6n1.js → channel-type-Cu1yjNg2.js} +3 -3
- package/dist/{channel.setup-C-mLz50O.js → channel.setup-CgkADtZg.js} +6 -4
- package/dist/{config-schema-xPSnK2VK.js → config-schema-XjJGfwQC.js} +6 -5
- package/dist/{directory-config-DRkFujwG.js → directory-config-Bv0lcUlH.js} +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-D_yZhjgp.js → directory-live-CzUIB7th.js} +2 -2
- package/dist/{doctor-contract-DddfkMlF.js → doctor-contract-DKpe5VBr.js} +80 -12
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{group-policy-85UWiriS.js → group-policy-Bw-65m3V.js} +67 -121
- package/dist/{interactive-replies-BilWUdcI.js → interactive-replies-Dm_t2R9S.js} +1 -1
- package/dist/interactive-replies-api.js +1 -1
- package/dist/{message-tool-api-CA9jZrCY.js → message-tool-api-C2pcf5du.js} +3 -3
- package/dist/message-tool-api.js +1 -1
- package/dist/{monitor-CalGciTs.js → monitor-CNFeF30h.js} +3 -3
- package/dist/{outbound-adapter-BiLKcnyH.js → outbound-adapter-CVi2uok0.js} +49 -5
- package/dist/{pipeline.runtime-DofAvTtb.js → pipeline.runtime-CTvokbty.js} +391 -279
- package/dist/{policy-BVs4LiSa.js → policy-b_dOPDCq.js} +1 -1
- package/dist/probe-Borhn9PQ.js +340 -0
- package/dist/{provider-CmeoUiIM.js → provider-B-HVL5ZE.js} +573 -306
- package/dist/{relay-source-DMmgtvg4.js → relay-source-Ea_P9VcO.js} +6 -11
- package/dist/{replies-CJJCp6qz.js → replies-B4bOdrYb.js} +3 -3
- package/dist/{resolve-channels-Rfts6POK.js → resolve-channels-KTc568SU.js} +1 -1
- package/dist/{resolve-users-y6wAxR8E.js → resolve-users-DeGJf1yp.js} +1 -1
- package/dist/{runtime-api-BGDyOt1D.js → runtime-api-BFfNpzDe.js} +1 -1
- package/dist/runtime-api.js +11 -11
- package/dist/{scopes-CuxNQZ6v.js → scopes-lx08L56K.js} +1 -2
- package/dist/{secret-contract-CMohXFWS.js → secret-contract-DxmvbxBF.js} +1 -0
- package/dist/secret-contract-api.js +1 -1
- package/dist/{send-DYp8ca-l.js → send-KuTDky7i.js} +28 -11
- package/dist/send.runtime-CXyxws1D.js +2 -0
- package/dist/{setup-core-CkwVLzFO.js → setup-core-CeiAVwQ3.js} +218 -53
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-oSd3NX9J.js → setup-surface-DLA0vHXp.js} +23 -13
- package/dist/{shared-D9yz5Otg.js → shared-C4yVB0Q-.js} +55 -9
- package/dist/{slash-dispatch.runtime-CSja9VuD.js → slash-dispatch.runtime-BT-mMm-f.js} +1 -1
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +66 -10
- package/package.json +4 -4
- package/dist/accounts.runtime-KvftRRek.js +0 -2
- package/dist/action-runtime.runtime-DZfd7IFr.js +0 -2
- package/dist/client-WIPAS3Yr.js +0 -160
- package/dist/probe-CN0ssfLN.js +0 -48
- package/dist/send.runtime-CJLxAt26.js +0 -2
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "./
|
|
3
|
-
import
|
|
4
|
-
import { t as
|
|
5
|
-
import { t as
|
|
1
|
+
import { i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom } from "./accounts-DQEbYKh9.js";
|
|
2
|
+
import { t as inspectSlackAccount } from "./account-inspect-Bvbtu3iH.js";
|
|
3
|
+
import "./shared-C4yVB0Q-.js";
|
|
4
|
+
import { i as SLACK_CHANNEL, t as createSlackSetupWizardBase } from "./setup-core-CeiAVwQ3.js";
|
|
5
|
+
import { t as resolveSlackChannelAllowlist } from "./resolve-channels-KTc568SU.js";
|
|
6
|
+
import { t as resolveSlackUserAllowlist } from "./resolve-users-DeGJf1yp.js";
|
|
6
7
|
import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
8
|
import { adaptScopedAccountAccessor } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
8
9
|
import { createSetupTranslator, noteChannelLookupFailure, noteChannelLookupSummary, parseMentionOrPrefixedId, promptLegacyChannelAllowFromForAccount, resolveEntriesWithOptionalToken } from "openclaw/plugin-sdk/setup-runtime";
|
|
9
10
|
import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
|
|
10
11
|
//#region extensions/slack/src/setup-surface.ts
|
|
11
12
|
const t = createSetupTranslator();
|
|
13
|
+
function resolveSlackSetupAuth(account, credentialValues) {
|
|
14
|
+
if (account.config.identity === "user") return credentialValues.userToken || account.userToken;
|
|
15
|
+
return credentialValues.botToken || account.botToken;
|
|
16
|
+
}
|
|
12
17
|
async function resolveSlackAllowFromEntries(params) {
|
|
13
18
|
return await resolveEntriesWithOptionalToken({
|
|
14
19
|
token: params.token,
|
|
@@ -42,7 +47,7 @@ async function promptSlackAllowFrom(params) {
|
|
|
42
47
|
prompter: params.prompter,
|
|
43
48
|
accountId: params.accountId,
|
|
44
49
|
defaultAccountId: resolveDefaultSlackAccountId(params.cfg),
|
|
45
|
-
resolveAccount: adaptScopedAccountAccessor(
|
|
50
|
+
resolveAccount: adaptScopedAccountAccessor(inspectSlackAccount),
|
|
46
51
|
resolveExisting: (account, cfg) => resolveSlackAccountAllowFrom({
|
|
47
52
|
cfg,
|
|
48
53
|
accountId: account.accountId
|
|
@@ -73,13 +78,13 @@ async function promptSlackAllowFrom(params) {
|
|
|
73
78
|
}
|
|
74
79
|
async function resolveSlackGroupAllowlist(params) {
|
|
75
80
|
let keys = params.entries;
|
|
76
|
-
const
|
|
81
|
+
const auth = resolveSlackSetupAuth(inspectSlackAccount({
|
|
77
82
|
cfg: params.cfg,
|
|
78
83
|
accountId: params.accountId
|
|
79
|
-
})
|
|
84
|
+
}), params.credentialValues) || "";
|
|
80
85
|
if (params.entries.length > 0) try {
|
|
81
86
|
const resolved = await resolveEntriesWithOptionalToken({
|
|
82
|
-
token:
|
|
87
|
+
token: auth,
|
|
83
88
|
entries: params.entries,
|
|
84
89
|
buildWithoutToken: (input) => ({
|
|
85
90
|
input,
|
|
@@ -114,10 +119,15 @@ async function resolveSlackGroupAllowlist(params) {
|
|
|
114
119
|
}
|
|
115
120
|
const slackSetupWizard = createSlackSetupWizardBase({
|
|
116
121
|
promptAllowFrom: promptSlackAllowFrom,
|
|
117
|
-
resolveAllowFromEntries: async ({ credentialValues, entries }) =>
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
resolveAllowFromEntries: async ({ cfg, accountId, credentialValues, entries }) => {
|
|
123
|
+
return await resolveSlackAllowFromEntries({
|
|
124
|
+
token: resolveSlackSetupAuth(inspectSlackAccount({
|
|
125
|
+
cfg,
|
|
126
|
+
accountId
|
|
127
|
+
}), credentialValues),
|
|
128
|
+
entries
|
|
129
|
+
});
|
|
130
|
+
},
|
|
121
131
|
resolveGroupAllowlist: async ({ cfg, accountId, credentialValues, entries, prompter }) => await resolveSlackGroupAllowlist({
|
|
122
132
|
cfg,
|
|
123
133
|
accountId,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { a as resolveSlackAccount, c as resolveSlackConfigAccessorAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig, s as resolveSlackAccountDmPolicy } from "./accounts-
|
|
2
|
-
import { t as inspectSlackAccount } from "./account-inspect-
|
|
3
|
-
import { t as isSlackPluginAccountConfigured } from "./account-configured-
|
|
4
|
-
import { n as isSlackInteractiveRepliesEnabled } from "./interactive-replies-
|
|
5
|
-
import {
|
|
6
|
-
import { i as SLACK_CHANNEL } from "./setup-core-
|
|
7
|
-
import { t as SlackChannelConfigSchema } from "./config-schema-
|
|
8
|
-
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-
|
|
9
|
-
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-
|
|
1
|
+
import { a as resolveSlackAccount, c as resolveSlackConfigAccessorAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig, s as resolveSlackAccountDmPolicy } from "./accounts-DQEbYKh9.js";
|
|
2
|
+
import { t as inspectSlackAccount } from "./account-inspect-Bvbtu3iH.js";
|
|
3
|
+
import { t as isSlackPluginAccountConfigured } from "./account-configured-BwfXBo_F.js";
|
|
4
|
+
import { n as isSlackInteractiveRepliesEnabled } from "./interactive-replies-Dm_t2R9S.js";
|
|
5
|
+
import { t as probeSlack, v as getChatChannelMeta } from "./probe-Borhn9PQ.js";
|
|
6
|
+
import { i as SLACK_CHANNEL } from "./setup-core-CeiAVwQ3.js";
|
|
7
|
+
import { t as SlackChannelConfigSchema } from "./config-schema-XjJGfwQC.js";
|
|
8
|
+
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-DKpe5VBr.js";
|
|
9
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-DxmvbxBF.js";
|
|
10
10
|
import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter, createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
11
11
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
12
12
|
import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
|
|
@@ -135,6 +135,46 @@ function collectSlackNameKeyedChannelWarnings({ cfg }) {
|
|
|
135
135
|
}
|
|
136
136
|
return [...warnings];
|
|
137
137
|
}
|
|
138
|
+
function slackAccountConfigPath(accountId) {
|
|
139
|
+
return accountId === "default" ? "channels.slack" : `channels.slack.accounts.${accountId}`;
|
|
140
|
+
}
|
|
141
|
+
async function collectSlackUserIdentityWarnings(params) {
|
|
142
|
+
const warnings = [];
|
|
143
|
+
for (const accountId of listSlackAccountIds(params.cfg)) {
|
|
144
|
+
const account = inspectSlackAccount({
|
|
145
|
+
cfg: params.cfg,
|
|
146
|
+
accountId,
|
|
147
|
+
envBotToken: params.env?.SLACK_BOT_TOKEN,
|
|
148
|
+
envAppToken: params.env?.SLACK_APP_TOKEN,
|
|
149
|
+
envUserToken: params.env?.SLACK_USER_TOKEN
|
|
150
|
+
});
|
|
151
|
+
if (!account.enabled || account.identity !== "user") continue;
|
|
152
|
+
const path = slackAccountConfigPath(accountId);
|
|
153
|
+
const mode = account.mode ?? "socket";
|
|
154
|
+
if (mode === "socket" && account.appTokenStatus === "missing") warnings.push(`- ${path}: identity "user" in Socket Mode requires appToken for companion-app events.`);
|
|
155
|
+
else if (mode === "http" && account.signingSecretStatus === "missing") warnings.push(`- ${path}: identity "user" in HTTP mode requires signingSecret for companion-app events.`);
|
|
156
|
+
if (!account.userToken) {
|
|
157
|
+
warnings.push(account.userTokenStatus === "configured_unavailable" ? `- ${path}: userToken is configured but unavailable; Slack auth.test validation was skipped.` : `- ${path}: identity "user" requires userToken for the authorizing human.`);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const probe = await probeSlack(account.userToken, 2500, {
|
|
161
|
+
accountId,
|
|
162
|
+
identity: "user"
|
|
163
|
+
});
|
|
164
|
+
if (!probe.ok) {
|
|
165
|
+
warnings.push(`- ${path}: userToken auth.test failed: ${probe.error ?? "unknown error"}.`);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const userId = probe.user?.id?.trim();
|
|
169
|
+
const userName = probe.user?.name?.trim();
|
|
170
|
+
if (!userId) {
|
|
171
|
+
warnings.push(`- ${path}: userToken auth.test succeeded but returned no human user_id.`);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
warnings.push(`- ${path}: user identity authenticated as ${userName ? `@${userName} ` : ""}(${userId}).`);
|
|
175
|
+
}
|
|
176
|
+
return warnings;
|
|
177
|
+
}
|
|
138
178
|
const slackDoctor = {
|
|
139
179
|
dmAllowFromMode: "topOnly",
|
|
140
180
|
groupModel: "route",
|
|
@@ -142,6 +182,10 @@ const slackDoctor = {
|
|
|
142
182
|
warnOnEmptyGroupSenderAllowlist: false,
|
|
143
183
|
legacyConfigRules,
|
|
144
184
|
normalizeCompatibilityConfig,
|
|
185
|
+
collectPreviewWarnings: async ({ cfg, env }) => await collectSlackUserIdentityWarnings({
|
|
186
|
+
cfg,
|
|
187
|
+
env
|
|
188
|
+
}),
|
|
145
189
|
collectMutableAllowlistWarnings: ({ cfg }) => [...collectSlackMutableAllowlistWarnings({ cfg }), ...collectSlackNameKeyedChannelWarnings({ cfg })]
|
|
146
190
|
};
|
|
147
191
|
//#endregion
|
|
@@ -156,6 +200,8 @@ const slackConfigAdapter = createScopedChannelConfigAdapter({
|
|
|
156
200
|
clearBaseFields: [
|
|
157
201
|
"botToken",
|
|
158
202
|
"appToken",
|
|
203
|
+
"userToken",
|
|
204
|
+
"signingSecret",
|
|
159
205
|
"name"
|
|
160
206
|
],
|
|
161
207
|
resolveAllowFrom: (account) => account.allowFrom,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as deliverSlackSlashReplies$1 } from "./replies-
|
|
1
|
+
import { r as deliverSlackSlashReplies$1 } from "./replies-B4bOdrYb.js";
|
|
2
2
|
import { resolveAgentRoute as resolveAgentRoute$1 } from "openclaw/plugin-sdk/routing";
|
|
3
3
|
import { resolveMarkdownTableMode as resolveMarkdownTableMode$1 } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
4
4
|
import { recordInboundSessionMetaSafe as recordInboundSessionMetaSafe$1, resolveConversationLabel as resolveConversationLabel$1 } from "openclaw/plugin-sdk/conversation-runtime";
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/slack",
|
|
3
|
-
"version": "2026.7.2-beta.
|
|
3
|
+
"version": "2026.7.2-beta.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/slack",
|
|
9
|
-
"version": "2026.7.2-beta.
|
|
9
|
+
"version": "2026.7.2-beta.3",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@slack/bolt": "4.7.3",
|
|
12
12
|
"@slack/types": "2.21.1",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"zod": "4.4.3"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"openclaw": ">=2026.7.2-beta.
|
|
20
|
+
"openclaw": ">=2026.7.2-beta.3"
|
|
21
21
|
},
|
|
22
22
|
"peerDependenciesMeta": {
|
|
23
23
|
"openclaw": {
|
package/openclaw.plugin.json
CHANGED
|
@@ -20,6 +20,14 @@
|
|
|
20
20
|
"name": {
|
|
21
21
|
"type": "string"
|
|
22
22
|
},
|
|
23
|
+
"identity": {
|
|
24
|
+
"default": "bot",
|
|
25
|
+
"type": "string",
|
|
26
|
+
"enum": [
|
|
27
|
+
"bot",
|
|
28
|
+
"user"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
23
31
|
"mode": {
|
|
24
32
|
"default": "socket",
|
|
25
33
|
"type": "string",
|
|
@@ -620,6 +628,21 @@
|
|
|
620
628
|
"requireMention": {
|
|
621
629
|
"type": "boolean"
|
|
622
630
|
},
|
|
631
|
+
"implicitMentions": {
|
|
632
|
+
"type": "object",
|
|
633
|
+
"properties": {
|
|
634
|
+
"replyToBot": {
|
|
635
|
+
"type": "boolean"
|
|
636
|
+
},
|
|
637
|
+
"quotedBot": {
|
|
638
|
+
"type": "boolean"
|
|
639
|
+
},
|
|
640
|
+
"threadParticipation": {
|
|
641
|
+
"type": "boolean"
|
|
642
|
+
}
|
|
643
|
+
},
|
|
644
|
+
"additionalProperties": false
|
|
645
|
+
},
|
|
623
646
|
"groupPolicy": {
|
|
624
647
|
"default": "allowlist",
|
|
625
648
|
"type": "string",
|
|
@@ -996,9 +1019,6 @@
|
|
|
996
1019
|
"type": "integer",
|
|
997
1020
|
"minimum": 0,
|
|
998
1021
|
"maximum": 9007199254740991
|
|
999
|
-
},
|
|
1000
|
-
"requireExplicitMention": {
|
|
1001
|
-
"type": "boolean"
|
|
1002
1022
|
}
|
|
1003
1023
|
},
|
|
1004
1024
|
"additionalProperties": false
|
|
@@ -1367,6 +1387,13 @@
|
|
|
1367
1387
|
"name": {
|
|
1368
1388
|
"type": "string"
|
|
1369
1389
|
},
|
|
1390
|
+
"identity": {
|
|
1391
|
+
"type": "string",
|
|
1392
|
+
"enum": [
|
|
1393
|
+
"bot",
|
|
1394
|
+
"user"
|
|
1395
|
+
]
|
|
1396
|
+
},
|
|
1370
1397
|
"mode": {
|
|
1371
1398
|
"type": "string",
|
|
1372
1399
|
"enum": [
|
|
@@ -1965,6 +1992,21 @@
|
|
|
1965
1992
|
"requireMention": {
|
|
1966
1993
|
"type": "boolean"
|
|
1967
1994
|
},
|
|
1995
|
+
"implicitMentions": {
|
|
1996
|
+
"type": "object",
|
|
1997
|
+
"properties": {
|
|
1998
|
+
"replyToBot": {
|
|
1999
|
+
"type": "boolean"
|
|
2000
|
+
},
|
|
2001
|
+
"quotedBot": {
|
|
2002
|
+
"type": "boolean"
|
|
2003
|
+
},
|
|
2004
|
+
"threadParticipation": {
|
|
2005
|
+
"type": "boolean"
|
|
2006
|
+
}
|
|
2007
|
+
},
|
|
2008
|
+
"additionalProperties": false
|
|
2009
|
+
},
|
|
1968
2010
|
"groupPolicy": {
|
|
1969
2011
|
"type": "string",
|
|
1970
2012
|
"enum": [
|
|
@@ -2340,9 +2382,6 @@
|
|
|
2340
2382
|
"type": "integer",
|
|
2341
2383
|
"minimum": 0,
|
|
2342
2384
|
"maximum": 9007199254740991
|
|
2343
|
-
},
|
|
2344
|
-
"requireExplicitMention": {
|
|
2345
|
-
"type": "boolean"
|
|
2346
2385
|
}
|
|
2347
2386
|
},
|
|
2348
2387
|
"additionalProperties": false
|
|
@@ -2712,6 +2751,7 @@
|
|
|
2712
2751
|
}
|
|
2713
2752
|
},
|
|
2714
2753
|
"required": [
|
|
2754
|
+
"identity",
|
|
2715
2755
|
"mode",
|
|
2716
2756
|
"webhookPath",
|
|
2717
2757
|
"userTokenReadOnly",
|
|
@@ -2730,6 +2770,10 @@
|
|
|
2730
2770
|
"label": "Slack Enterprise Grid Org Install",
|
|
2731
2771
|
"help": "Enable only for an Enterprise Grid org-wide bot installation. OpenClaw verifies the token with Slack auth.test at startup; DMs must be disabled or use dmPolicy=\"open\" with allowFrom=[\"*\"]."
|
|
2732
2772
|
},
|
|
2773
|
+
"identity": {
|
|
2774
|
+
"label": "Slack Identity",
|
|
2775
|
+
"help": "Select \"bot\" (default) for the classic Slack app/bot identity or \"user\" to post as the authorizing human through a user token while the app carries event transport."
|
|
2776
|
+
},
|
|
2733
2777
|
"dm.policy": {
|
|
2734
2778
|
"label": "Slack DM Policy",
|
|
2735
2779
|
"help": "Direct message access control (\"pairing\" recommended). \"open\" requires channels.slack.allowFrom=[\"*\"] (legacy: channels.slack.dm.allowFrom)."
|
|
@@ -2766,6 +2810,22 @@
|
|
|
2766
2810
|
"label": "Slack Native Skill Commands",
|
|
2767
2811
|
"help": "Override native skill commands for Slack (bool or \"auto\")."
|
|
2768
2812
|
},
|
|
2813
|
+
"implicitMentions": {
|
|
2814
|
+
"label": "Slack Implicit Mentions",
|
|
2815
|
+
"help": "Control which Slack reply, quote, and thread-participation signals count as mentions. Unset flags preserve the channel defaults."
|
|
2816
|
+
},
|
|
2817
|
+
"implicitMentions.replyToBot": {
|
|
2818
|
+
"label": "Slack Replies to Bot",
|
|
2819
|
+
"help": "Treat replies to the bot's own messages as implicit mentions when the channel reports that signal."
|
|
2820
|
+
},
|
|
2821
|
+
"implicitMentions.quotedBot": {
|
|
2822
|
+
"label": "Slack Quoted Bot Messages",
|
|
2823
|
+
"help": "Treat messages quoting the bot as implicit mentions when the channel reports that signal."
|
|
2824
|
+
},
|
|
2825
|
+
"implicitMentions.threadParticipation": {
|
|
2826
|
+
"label": "Slack Thread Participation",
|
|
2827
|
+
"help": "Treat follow-ups in threads where the bot participated as implicit mentions when the channel reports that signal."
|
|
2828
|
+
},
|
|
2769
2829
|
"allowBots": {
|
|
2770
2830
|
"label": "Slack Allow Bot Messages",
|
|
2771
2831
|
"help": "Allow bot-authored messages to trigger Slack replies (default: false)."
|
|
@@ -2953,10 +3013,6 @@
|
|
|
2953
3013
|
"thread.initialHistoryLimit": {
|
|
2954
3014
|
"label": "Slack Thread Initial History Limit",
|
|
2955
3015
|
"help": "Maximum number of existing Slack thread messages to fetch when starting a new thread session (default: 20, set to 0 to disable)."
|
|
2956
|
-
},
|
|
2957
|
-
"thread.requireExplicitMention": {
|
|
2958
|
-
"label": "Slack Thread Require Explicit Mention",
|
|
2959
|
-
"help": "If true, require an explicit @mention even inside threads where the bot has participated. Suppresses implicit thread mention behavior so the bot only responds to explicit @bot mentions in threads (default: false)."
|
|
2960
3016
|
}
|
|
2961
3017
|
}
|
|
2962
3018
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/slack",
|
|
3
|
-
"version": "2026.7.2-beta.
|
|
3
|
+
"version": "2026.7.2-beta.3",
|
|
4
4
|
"description": "OpenClaw Slack channel plugin for channels, DMs, commands, and app events.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"zod": "4.4.3"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"openclaw": ">=2026.7.2-beta.
|
|
20
|
+
"openclaw": ">=2026.7.2-beta.3"
|
|
21
21
|
},
|
|
22
22
|
"peerDependenciesMeta": {
|
|
23
23
|
"openclaw": {
|
|
@@ -60,13 +60,13 @@
|
|
|
60
60
|
"allowInvalidConfigRecovery": true
|
|
61
61
|
},
|
|
62
62
|
"compat": {
|
|
63
|
-
"pluginApi": ">=2026.7.2-beta.
|
|
63
|
+
"pluginApi": ">=2026.7.2-beta.3"
|
|
64
64
|
},
|
|
65
65
|
"startup": {
|
|
66
66
|
"deferConfiguredChannelFullLoadUntilAfterListen": true
|
|
67
67
|
},
|
|
68
68
|
"build": {
|
|
69
|
-
"openclawVersion": "2026.7.2-beta.
|
|
69
|
+
"openclawVersion": "2026.7.2-beta.3",
|
|
70
70
|
"bundledDist": false
|
|
71
71
|
},
|
|
72
72
|
"release": {
|
package/dist/client-WIPAS3Yr.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import "./target-parsing-N6lHogYZ.js";
|
|
2
|
-
import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1 } from "openclaw/plugin-sdk/account-id";
|
|
3
|
-
import { PAIRING_APPROVED_MESSAGE, projectCredentialSnapshotFields, resolveConfiguredFromRequiredCredentialStatuses } from "openclaw/plugin-sdk/channel-status";
|
|
4
|
-
import { createHash } from "node:crypto";
|
|
5
|
-
import { WebClient } from "@slack/web-api";
|
|
6
|
-
import { createNodeProxyAgent } from "openclaw/plugin-sdk/fetch-runtime";
|
|
7
|
-
//#region extensions/slack/src/channel-api.ts
|
|
8
|
-
const SLACK_CHANNEL_META = {
|
|
9
|
-
id: "slack",
|
|
10
|
-
label: "Slack",
|
|
11
|
-
selectionLabel: "Slack",
|
|
12
|
-
docsPath: "/channels/slack",
|
|
13
|
-
docsLabel: "slack",
|
|
14
|
-
blurb: "supports bot + app tokens, channels, threads, and interactive replies.",
|
|
15
|
-
systemImage: "number.square",
|
|
16
|
-
markdownCapable: true
|
|
17
|
-
};
|
|
18
|
-
function getChatChannelMeta(id) {
|
|
19
|
-
if (id !== SLACK_CHANNEL_META.id) throw new Error(`Unsupported Slack channel meta lookup: ${id}`);
|
|
20
|
-
return SLACK_CHANNEL_META;
|
|
21
|
-
}
|
|
22
|
-
//#endregion
|
|
23
|
-
//#region extensions/slack/src/client-options.ts
|
|
24
|
-
const SLACK_DEFAULT_RETRY_OPTIONS = {
|
|
25
|
-
retries: 2,
|
|
26
|
-
factor: 2,
|
|
27
|
-
minTimeout: 500,
|
|
28
|
-
maxTimeout: 3e3,
|
|
29
|
-
randomize: true
|
|
30
|
-
};
|
|
31
|
-
const SLACK_WRITE_RETRY_OPTIONS = { retries: 0 };
|
|
32
|
-
const SLACK_LOOKUP_TIMEOUT_MS = 3e4;
|
|
33
|
-
const SLACK_LOOKUP_RETRY_OPTIONS = { retries: 0 };
|
|
34
|
-
/**
|
|
35
|
-
* Build an HTTPS proxy agent from env vars (HTTPS_PROXY, HTTP_PROXY, etc.)
|
|
36
|
-
* for use as the `agent` option in Slack WebClient and Socket Mode connections.
|
|
37
|
-
*
|
|
38
|
-
* When set, this agent is forwarded through @slack/bolt -> @slack/socket-mode ->
|
|
39
|
-
* SlackWebSocket as the `httpAgent`, which the `ws` library uses to tunnel the
|
|
40
|
-
* WebSocket upgrade request through the proxy. This fixes Socket Mode in
|
|
41
|
-
* environments where outbound traffic must go through an HTTP CONNECT proxy.
|
|
42
|
-
*
|
|
43
|
-
* Respects `NO_PROXY` / `no_proxy`; if `*.slack.com` (or a matching pattern)
|
|
44
|
-
* appears in the exclusion list, returns `undefined` so the connection is direct.
|
|
45
|
-
*
|
|
46
|
-
* Returns `undefined` when no proxy env var is configured or when Slack hosts
|
|
47
|
-
* are excluded by `NO_PROXY`.
|
|
48
|
-
*/
|
|
49
|
-
function resolveSlackProxyAgent(targetUrl) {
|
|
50
|
-
try {
|
|
51
|
-
return createNodeProxyAgent({
|
|
52
|
-
mode: "env",
|
|
53
|
-
targetUrl
|
|
54
|
-
});
|
|
55
|
-
} catch {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
function resolveSlackApiUrlFromEnv() {
|
|
60
|
-
return process.env.SLACK_API_URL?.trim() || void 0;
|
|
61
|
-
}
|
|
62
|
-
function applySlackApiUrlAndProxyOptions(options) {
|
|
63
|
-
const slackApiUrl = options.slackApiUrl ?? resolveSlackApiUrlFromEnv();
|
|
64
|
-
options.agent ??= resolveSlackProxyAgent(slackApiUrl ?? "https://slack.com/");
|
|
65
|
-
if (slackApiUrl !== void 0) options.slackApiUrl = slackApiUrl;
|
|
66
|
-
else delete options.slackApiUrl;
|
|
67
|
-
}
|
|
68
|
-
function resolveSlackWebClientOptions(options = {}) {
|
|
69
|
-
const resolved = Object.assign({}, options);
|
|
70
|
-
applySlackApiUrlAndProxyOptions(resolved);
|
|
71
|
-
resolved.retryConfig ??= SLACK_DEFAULT_RETRY_OPTIONS;
|
|
72
|
-
return resolved;
|
|
73
|
-
}
|
|
74
|
-
function resolveSlackWriteClientOptions(options = {}) {
|
|
75
|
-
const resolved = Object.assign({}, options);
|
|
76
|
-
applySlackApiUrlAndProxyOptions(resolved);
|
|
77
|
-
resolved.retryConfig ??= SLACK_WRITE_RETRY_OPTIONS;
|
|
78
|
-
return resolved;
|
|
79
|
-
}
|
|
80
|
-
function resolveSlackLookupClientOptions(options = {}) {
|
|
81
|
-
const resolved = Object.assign({}, options);
|
|
82
|
-
applySlackApiUrlAndProxyOptions(resolved);
|
|
83
|
-
resolved.rejectRateLimitedCalls = true;
|
|
84
|
-
resolved.retryConfig = SLACK_LOOKUP_RETRY_OPTIONS;
|
|
85
|
-
resolved.timeout ??= SLACK_LOOKUP_TIMEOUT_MS;
|
|
86
|
-
return resolved;
|
|
87
|
-
}
|
|
88
|
-
//#endregion
|
|
89
|
-
//#region extensions/slack/src/client.ts
|
|
90
|
-
const SLACK_WRITE_CLIENT_CACHE_MAX = 32;
|
|
91
|
-
const slackWriteClientCache = /* @__PURE__ */ new Map();
|
|
92
|
-
let slackListenerUploadCompletionClientCache = /* @__PURE__ */ new WeakMap();
|
|
93
|
-
function createSlackWebClient(token, options = {}) {
|
|
94
|
-
return new WebClient(token, resolveSlackWebClientOptions(options));
|
|
95
|
-
}
|
|
96
|
-
function createSlackStartupAuthClient(token, options = {}) {
|
|
97
|
-
return createSlackWebClient(token, {
|
|
98
|
-
...options,
|
|
99
|
-
rejectRateLimitedCalls: true,
|
|
100
|
-
retryConfig: { retries: 0 },
|
|
101
|
-
timeout: 1e4
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
function createSlackLookupClient(token, options = {}) {
|
|
105
|
-
return new WebClient(token, resolveSlackLookupClientOptions(options));
|
|
106
|
-
}
|
|
107
|
-
function createSlackWriteClient(token, options = {}) {
|
|
108
|
-
return new WebClient(token, resolveSlackWriteClientOptions(options));
|
|
109
|
-
}
|
|
110
|
-
function createSlackTokenCacheKey(token) {
|
|
111
|
-
return `sha256:${createHash("sha256").update(token).digest("base64url")}`;
|
|
112
|
-
}
|
|
113
|
-
function slackWriteClientCacheKey(token, options) {
|
|
114
|
-
const tokenKey = createSlackTokenCacheKey(token);
|
|
115
|
-
return options.slackApiUrl ? `${tokenKey}:api:${options.slackApiUrl}` : tokenKey;
|
|
116
|
-
}
|
|
117
|
-
function getSlackWriteClient(token, options = {}) {
|
|
118
|
-
const resolvedOptions = resolveSlackWriteClientOptions(options);
|
|
119
|
-
const tokenKey = slackWriteClientCacheKey(token, resolvedOptions);
|
|
120
|
-
const cached = slackWriteClientCache.get(tokenKey);
|
|
121
|
-
if (cached) {
|
|
122
|
-
slackWriteClientCache.delete(tokenKey);
|
|
123
|
-
slackWriteClientCache.set(tokenKey, cached);
|
|
124
|
-
return cached;
|
|
125
|
-
}
|
|
126
|
-
const client = new WebClient(token, resolvedOptions);
|
|
127
|
-
if (slackWriteClientCache.size >= SLACK_WRITE_CLIENT_CACHE_MAX) {
|
|
128
|
-
const oldestTokenKey = slackWriteClientCache.keys().next().value;
|
|
129
|
-
if (oldestTokenKey) slackWriteClientCache.delete(oldestTokenKey);
|
|
130
|
-
}
|
|
131
|
-
slackWriteClientCache.set(tokenKey, client);
|
|
132
|
-
return client;
|
|
133
|
-
}
|
|
134
|
-
function getSlackListenerUploadCompletionClient(params) {
|
|
135
|
-
const token = params.listenerClient.token?.trim();
|
|
136
|
-
const teamId = params.teamId.trim().toUpperCase();
|
|
137
|
-
if (!token || !teamId) return;
|
|
138
|
-
const cached = slackListenerUploadCompletionClientCache.get(params.listenerClient);
|
|
139
|
-
if (cached) return cached.teamId === teamId ? cached.client : void 0;
|
|
140
|
-
const headers = Object.fromEntries(Object.entries(params.clientOptions?.headers ?? {}).filter(([name]) => name.toLowerCase() !== "authorization"));
|
|
141
|
-
const client = new WebClient(token, resolveSlackWriteClientOptions({
|
|
142
|
-
...params.clientOptions,
|
|
143
|
-
headers,
|
|
144
|
-
slackApiUrl: params.listenerClient.slackApiUrl,
|
|
145
|
-
teamId,
|
|
146
|
-
retryConfig: SLACK_WRITE_RETRY_OPTIONS,
|
|
147
|
-
timeout: 0
|
|
148
|
-
}));
|
|
149
|
-
slackListenerUploadCompletionClientCache.set(params.listenerClient, {
|
|
150
|
-
teamId,
|
|
151
|
-
client
|
|
152
|
-
});
|
|
153
|
-
return client;
|
|
154
|
-
}
|
|
155
|
-
function clearSlackWriteClientCacheForTest() {
|
|
156
|
-
slackWriteClientCache.clear();
|
|
157
|
-
slackListenerUploadCompletionClientCache = /* @__PURE__ */ new WeakMap();
|
|
158
|
-
}
|
|
159
|
-
//#endregion
|
|
160
|
-
export { resolveConfiguredFromRequiredCredentialStatuses as _, createSlackWebClient as a, getSlackWriteClient as c, resolveSlackWebClientOptions as d, resolveSlackWriteClientOptions as f, projectCredentialSnapshotFields as g, getChatChannelMeta as h, createSlackTokenCacheKey as i, SLACK_DEFAULT_RETRY_OPTIONS as l, PAIRING_APPROVED_MESSAGE as m, createSlackLookupClient as n, createSlackWriteClient as o, DEFAULT_ACCOUNT_ID$1 as p, createSlackStartupAuthClient as r, getSlackListenerUploadCompletionClient as s, clearSlackWriteClientCacheForTest as t, SLACK_WRITE_RETRY_OPTIONS as u };
|
package/dist/probe-CN0ssfLN.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { d as formatSlackBotTokenIdentityWarning } from "./accounts-BOJJiHSr.js";
|
|
3
|
-
import { i as formatSlackError } from "./group-policy-85UWiriS.js";
|
|
4
|
-
import { a as createSlackWebClient } from "./client-WIPAS3Yr.js";
|
|
5
|
-
import { withTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
6
|
-
//#region extensions/slack/src/probe.ts
|
|
7
|
-
var probe_exports = /* @__PURE__ */ __exportAll({ probeSlack: () => probeSlack });
|
|
8
|
-
async function probeSlack(token, timeoutMs = 2500, opts) {
|
|
9
|
-
const client = createSlackWebClient(token);
|
|
10
|
-
const start = Date.now();
|
|
11
|
-
try {
|
|
12
|
-
const result = await withTimeout(client.auth.test(), timeoutMs);
|
|
13
|
-
if (!result.ok) return {
|
|
14
|
-
ok: false,
|
|
15
|
-
status: 200,
|
|
16
|
-
error: result.error ?? "unknown",
|
|
17
|
-
elapsedMs: Date.now() - start
|
|
18
|
-
};
|
|
19
|
-
const warning = formatSlackBotTokenIdentityWarning({
|
|
20
|
-
auth: result,
|
|
21
|
-
accountId: opts?.accountId
|
|
22
|
-
});
|
|
23
|
-
return {
|
|
24
|
-
ok: true,
|
|
25
|
-
status: 200,
|
|
26
|
-
elapsedMs: Date.now() - start,
|
|
27
|
-
bot: {
|
|
28
|
-
id: result.user_id,
|
|
29
|
-
name: result.user
|
|
30
|
-
},
|
|
31
|
-
team: {
|
|
32
|
-
id: result.team_id,
|
|
33
|
-
name: result.team
|
|
34
|
-
},
|
|
35
|
-
...warning ? { warning } : {}
|
|
36
|
-
};
|
|
37
|
-
} catch (err) {
|
|
38
|
-
const message = formatSlackError(err);
|
|
39
|
-
return {
|
|
40
|
-
ok: false,
|
|
41
|
-
status: typeof err.statusCode === "number" ? err.statusCode : null,
|
|
42
|
-
error: message,
|
|
43
|
-
elapsedMs: Date.now() - start
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
//#endregion
|
|
48
|
-
export { probe_exports as n, probeSlack as t };
|