@openclaw/slack 2026.7.1 → 2026.7.2-beta.2
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/accounts.runtime-KvftRRek.js +2 -0
- package/dist/{action-runtime-DoQGk_8D.js → action-runtime-Cee2ih0s.js} +209 -30
- package/dist/action-runtime.runtime-DZfd7IFr.js +2 -0
- package/dist/{actions-DMpDmKEA.js → actions-BZiuSTIq.js} +88 -143
- package/dist/{actions.runtime-C103_BPW.js → actions.runtime-DoD0-gxw.js} +1 -1
- package/dist/api.js +14 -13
- package/dist/{approval-handler.runtime-CIUbOt5T.js → approval-handler.runtime-CUPtIM4k.js} +3 -3
- package/dist/{channel-BjlsaGHn.js → channel-DaIiGUOp.js} +119 -141
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/channel-type-Cfm6_6n1.js +109 -0
- package/dist/{channel.setup-Dq6syTNU.js → channel.setup-C-mLz50O.js} +3 -3
- package/dist/{client-DGxwSL7f.js → client-WIPAS3Yr.js} +46 -2
- package/dist/config-api-Df9a1B8C.js +3 -0
- package/dist/{config-schema-BzqzFW__.js → config-schema-xPSnK2VK.js} +32 -37
- package/dist/cursor-pages-DSmTg0su.js +13 -0
- package/dist/{directory-config-BZuS8141.js → directory-config-DRkFujwG.js} +2 -2
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-BNsxCgqP.js → directory-live-D_yZhjgp.js} +2 -2
- package/dist/{doctor-contract-XL6HeNCb.js → doctor-contract-DddfkMlF.js} +25 -38
- package/dist/doctor-contract-api.js +1 -1
- package/dist/group-policy-85UWiriS.js +2345 -0
- package/dist/{interactive-replies-CXpT-vA_.js → interactive-replies-BilWUdcI.js} +5 -1
- package/dist/interactive-replies-api.js +1 -1
- package/dist/{message-tool-api-BgWKyu2r.js → message-tool-api-CA9jZrCY.js} +1 -1
- package/dist/message-tool-api.js +1 -1
- package/dist/{monitor-Ux-wzUWI.js → monitor-CalGciTs.js} +3 -3
- package/dist/outbound-adapter-BiLKcnyH.js +228 -0
- package/dist/{pipeline.runtime-rpVpay59.js → pipeline.runtime-DofAvTtb.js} +657 -221
- package/dist/{policy-Dj-puVPb.js → policy-BVs4LiSa.js} +7 -7
- package/dist/preflight-audio.runtime-D5Bgags0.js +3 -0
- package/dist/{probe-CuwRDE5j.js → probe-CN0ssfLN.js} +2 -2
- package/dist/{provider-C1-DFSpw.js → provider-CmeoUiIM.js} +907 -206
- package/dist/{relay-source-D2jv1iGg.js → relay-source-DMmgtvg4.js} +6 -17
- package/dist/replies-CJJCp6qz.js +420 -0
- package/dist/{resolve-channels-CstkChBE.js → resolve-channels-Rfts6POK.js} +17 -6
- package/dist/{resolve-users-C3NP2c-Q.js → resolve-users-y6wAxR8E.js} +11 -6
- package/dist/runtime-JSVZSWAj.js +8 -0
- package/dist/{runtime-api-CEmqYxR-.js → runtime-api-BGDyOt1D.js} +3 -3
- package/dist/runtime-api.js +11 -11
- package/dist/runtime-setter-api.js +1 -1
- package/dist/{scopes-DCWVD5-8.js → scopes-CuxNQZ6v.js} +2 -2
- package/dist/{secret-contract-C3ChHo5A.js → secret-contract-CMohXFWS.js} +18 -113
- package/dist/secret-contract-api.js +1 -1
- package/dist/{send-DKDXoeoV.js → send-DYp8ca-l.js} +662 -325
- package/dist/{send.runtime-GPRa63l1.js → send.runtime-CJLxAt26.js} +1 -1
- package/dist/{setup-core-fGd6Gquy.js → setup-core-CkwVLzFO.js} +15 -21
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-Dv2fIJNB.js → setup-surface-oSd3NX9J.js} +4 -4
- package/dist/{shared-CosfcFri.js → shared-D9yz5Otg.js} +17 -38
- package/dist/{slash-dispatch.runtime-CcMbbT3_.js → slash-dispatch.runtime-CSja9VuD.js} +1 -1
- package/dist/{streaming-compat-DjlgH-Be.js → streaming-compat-3_X-21wW.js} +1 -0
- package/dist/{target-parsing-3jYH8LfB.js → target-parsing-N6lHogYZ.js} +16 -3
- package/dist/{targets-Dll4NJgs.js → targets-KmjP2E8s.js} +1 -1
- package/node_modules/p-map/index.d.ts +155 -0
- package/node_modules/p-map/index.js +284 -0
- package/node_modules/p-map/license +9 -0
- package/node_modules/p-map/package.json +57 -0
- package/node_modules/p-map/readme.md +190 -0
- package/npm-shrinkwrap.json +16 -3
- package/openclaw.plugin.json +84 -0
- package/package.json +7 -7
- package/dist/accounts.runtime-DWvaCb-X.js +0 -2
- package/dist/action-runtime.runtime-BABj3aM-.js +0 -2
- package/dist/config-api-DnT9ohtE.js +0 -2
- package/dist/configured-state.js +0 -11
- package/dist/format-YCNoNkM2.js +0 -107
- package/dist/outbound-adapter-DVoBfBW5.js +0 -272
- package/dist/replies-DpF38e1y.js +0 -287
- package/dist/reply-blocks-BGQ6zSqM.js +0 -877
- package/dist/resolve-allowlist-common-CP8SH0Zf.js +0 -43
- package/dist/runtime-BOk7xkOl.js +0 -8
package/openclaw.plugin.json
CHANGED
|
@@ -29,6 +29,9 @@
|
|
|
29
29
|
"relay"
|
|
30
30
|
]
|
|
31
31
|
},
|
|
32
|
+
"enterpriseOrgInstall": {
|
|
33
|
+
"type": "boolean"
|
|
34
|
+
},
|
|
32
35
|
"socketMode": {
|
|
33
36
|
"type": "object",
|
|
34
37
|
"properties": {
|
|
@@ -819,6 +822,9 @@
|
|
|
819
822
|
"commentary": {
|
|
820
823
|
"type": "boolean"
|
|
821
824
|
},
|
|
825
|
+
"narration": {
|
|
826
|
+
"type": "boolean"
|
|
827
|
+
},
|
|
822
828
|
"nativeTaskCards": {
|
|
823
829
|
"type": "boolean"
|
|
824
830
|
}
|
|
@@ -997,6 +1003,20 @@
|
|
|
997
1003
|
},
|
|
998
1004
|
"additionalProperties": false
|
|
999
1005
|
},
|
|
1006
|
+
"presenceEvents": {
|
|
1007
|
+
"type": "object",
|
|
1008
|
+
"properties": {
|
|
1009
|
+
"mode": {
|
|
1010
|
+
"type": "string",
|
|
1011
|
+
"enum": [
|
|
1012
|
+
"off",
|
|
1013
|
+
"auto",
|
|
1014
|
+
"on"
|
|
1015
|
+
]
|
|
1016
|
+
}
|
|
1017
|
+
},
|
|
1018
|
+
"additionalProperties": false
|
|
1019
|
+
},
|
|
1000
1020
|
"actions": {
|
|
1001
1021
|
"type": "object",
|
|
1002
1022
|
"properties": {
|
|
@@ -1284,6 +1304,20 @@
|
|
|
1284
1304
|
},
|
|
1285
1305
|
"systemPrompt": {
|
|
1286
1306
|
"type": "string"
|
|
1307
|
+
},
|
|
1308
|
+
"presenceEvents": {
|
|
1309
|
+
"type": "object",
|
|
1310
|
+
"properties": {
|
|
1311
|
+
"mode": {
|
|
1312
|
+
"type": "string",
|
|
1313
|
+
"enum": [
|
|
1314
|
+
"off",
|
|
1315
|
+
"auto",
|
|
1316
|
+
"on"
|
|
1317
|
+
]
|
|
1318
|
+
}
|
|
1319
|
+
},
|
|
1320
|
+
"additionalProperties": false
|
|
1287
1321
|
}
|
|
1288
1322
|
},
|
|
1289
1323
|
"additionalProperties": false
|
|
@@ -1341,6 +1375,9 @@
|
|
|
1341
1375
|
"relay"
|
|
1342
1376
|
]
|
|
1343
1377
|
},
|
|
1378
|
+
"enterpriseOrgInstall": {
|
|
1379
|
+
"type": "boolean"
|
|
1380
|
+
},
|
|
1344
1381
|
"socketMode": {
|
|
1345
1382
|
"type": "object",
|
|
1346
1383
|
"properties": {
|
|
@@ -2129,6 +2166,9 @@
|
|
|
2129
2166
|
"commentary": {
|
|
2130
2167
|
"type": "boolean"
|
|
2131
2168
|
},
|
|
2169
|
+
"narration": {
|
|
2170
|
+
"type": "boolean"
|
|
2171
|
+
},
|
|
2132
2172
|
"nativeTaskCards": {
|
|
2133
2173
|
"type": "boolean"
|
|
2134
2174
|
}
|
|
@@ -2307,6 +2347,20 @@
|
|
|
2307
2347
|
},
|
|
2308
2348
|
"additionalProperties": false
|
|
2309
2349
|
},
|
|
2350
|
+
"presenceEvents": {
|
|
2351
|
+
"type": "object",
|
|
2352
|
+
"properties": {
|
|
2353
|
+
"mode": {
|
|
2354
|
+
"type": "string",
|
|
2355
|
+
"enum": [
|
|
2356
|
+
"off",
|
|
2357
|
+
"auto",
|
|
2358
|
+
"on"
|
|
2359
|
+
]
|
|
2360
|
+
}
|
|
2361
|
+
},
|
|
2362
|
+
"additionalProperties": false
|
|
2363
|
+
},
|
|
2310
2364
|
"actions": {
|
|
2311
2365
|
"type": "object",
|
|
2312
2366
|
"properties": {
|
|
@@ -2594,6 +2648,20 @@
|
|
|
2594
2648
|
},
|
|
2595
2649
|
"systemPrompt": {
|
|
2596
2650
|
"type": "string"
|
|
2651
|
+
},
|
|
2652
|
+
"presenceEvents": {
|
|
2653
|
+
"type": "object",
|
|
2654
|
+
"properties": {
|
|
2655
|
+
"mode": {
|
|
2656
|
+
"type": "string",
|
|
2657
|
+
"enum": [
|
|
2658
|
+
"off",
|
|
2659
|
+
"auto",
|
|
2660
|
+
"on"
|
|
2661
|
+
]
|
|
2662
|
+
}
|
|
2663
|
+
},
|
|
2664
|
+
"additionalProperties": false
|
|
2597
2665
|
}
|
|
2598
2666
|
},
|
|
2599
2667
|
"additionalProperties": false
|
|
@@ -2658,6 +2726,10 @@
|
|
|
2658
2726
|
"label": "Slack",
|
|
2659
2727
|
"help": "Slack channel provider configuration for bot/app tokens, streaming behavior, and DM policy controls. Keep token handling and thread behavior explicit to avoid noisy workspace interactions."
|
|
2660
2728
|
},
|
|
2729
|
+
"enterpriseOrgInstall": {
|
|
2730
|
+
"label": "Slack Enterprise Grid Org Install",
|
|
2731
|
+
"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
|
+
},
|
|
2661
2733
|
"dm.policy": {
|
|
2662
2734
|
"label": "Slack DM Policy",
|
|
2663
2735
|
"help": "Direct message access control (\"pairing\" recommended). \"open\" requires channels.slack.allowFrom=[\"*\"] (legacy: channels.slack.dm.allowFrom)."
|
|
@@ -2774,6 +2846,18 @@
|
|
|
2774
2846
|
"label": "Slack Exec Approvals",
|
|
2775
2847
|
"help": "Slack-native exec approval routing and approver authorization. When unset, OpenClaw auto-enables DM-first native approvals if approvers can be resolved for this workspace account."
|
|
2776
2848
|
},
|
|
2849
|
+
"presenceEvents": {
|
|
2850
|
+
"label": "Slack Presence Events",
|
|
2851
|
+
"help": "Poll observed human participants and wake the routed agent on away-to-active transitions. Default: \"off\"."
|
|
2852
|
+
},
|
|
2853
|
+
"presenceEvents.mode": {
|
|
2854
|
+
"label": "Slack Presence Event Mode",
|
|
2855
|
+
"help": "\"off\" disables polling; \"auto\" covers DMs, MPIMs, and recent threads with up to 8 observed people; \"on\" also covers larger threads and top-level channels."
|
|
2856
|
+
},
|
|
2857
|
+
"channels.*.presenceEvents.mode": {
|
|
2858
|
+
"label": "Slack Channel Presence Event Mode",
|
|
2859
|
+
"help": "Override presence events for one Slack channel. Use \"on\" to include large threads or top-level channel sessions."
|
|
2860
|
+
},
|
|
2777
2861
|
"execApprovals.enabled": {
|
|
2778
2862
|
"label": "Slack Exec Approvals Enabled",
|
|
2779
2863
|
"help": "Controls Slack native exec approvals for this account: unset or \"auto\" enables DM-first native approvals when approvers can be resolved, true forces native approvals on, and false disables them."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/slack",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.2-beta.2",
|
|
4
4
|
"description": "OpenClaw Slack channel plugin for channels, DMs, commands, and app events.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
"@slack/bolt": "4.7.3",
|
|
12
12
|
"@slack/types": "2.21.1",
|
|
13
13
|
"@slack/web-api": "7.18.0",
|
|
14
|
+
"p-map": "7.0.5",
|
|
14
15
|
"typebox": "1.3.3",
|
|
15
16
|
"ws": "8.21.0",
|
|
16
17
|
"zod": "4.4.3"
|
|
17
18
|
},
|
|
18
19
|
"peerDependencies": {
|
|
19
|
-
"openclaw": ">=2026.7.
|
|
20
|
+
"openclaw": ">=2026.7.2-beta.2"
|
|
20
21
|
},
|
|
21
22
|
"peerDependenciesMeta": {
|
|
22
23
|
"openclaw": {
|
|
@@ -49,9 +50,7 @@
|
|
|
49
50
|
"SLACK_BOT_TOKEN",
|
|
50
51
|
"SLACK_USER_TOKEN"
|
|
51
52
|
]
|
|
52
|
-
}
|
|
53
|
-
"specifier": "./configured-state",
|
|
54
|
-
"exportName": "hasSlackConfiguredState"
|
|
53
|
+
}
|
|
55
54
|
}
|
|
56
55
|
},
|
|
57
56
|
"install": {
|
|
@@ -61,13 +60,13 @@
|
|
|
61
60
|
"allowInvalidConfigRecovery": true
|
|
62
61
|
},
|
|
63
62
|
"compat": {
|
|
64
|
-
"pluginApi": ">=2026.7.
|
|
63
|
+
"pluginApi": ">=2026.7.2-beta.2"
|
|
65
64
|
},
|
|
66
65
|
"startup": {
|
|
67
66
|
"deferConfiguredChannelFullLoadUntilAfterListen": true
|
|
68
67
|
},
|
|
69
68
|
"build": {
|
|
70
|
-
"openclawVersion": "2026.7.
|
|
69
|
+
"openclawVersion": "2026.7.2-beta.2",
|
|
71
70
|
"bundledDist": false
|
|
72
71
|
},
|
|
73
72
|
"release": {
|
|
@@ -90,6 +89,7 @@
|
|
|
90
89
|
"@slack/bolt",
|
|
91
90
|
"@slack/types",
|
|
92
91
|
"@slack/web-api",
|
|
92
|
+
"p-map",
|
|
93
93
|
"typebox",
|
|
94
94
|
"ws",
|
|
95
95
|
"zod"
|
package/dist/configured-state.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
//#region extensions/slack/configured-state.ts
|
|
2
|
-
const SLACK_CONFIGURED_ENV_KEYS = [
|
|
3
|
-
"SLACK_APP_TOKEN",
|
|
4
|
-
"SLACK_BOT_TOKEN",
|
|
5
|
-
"SLACK_USER_TOKEN"
|
|
6
|
-
];
|
|
7
|
-
function hasSlackConfiguredState(params) {
|
|
8
|
-
return SLACK_CONFIGURED_ENV_KEYS.some((key) => typeof params.env?.[key] === "string" && params.env[key]?.trim().length > 0);
|
|
9
|
-
}
|
|
10
|
-
//#endregion
|
|
11
|
-
export { hasSlackConfiguredState };
|
package/dist/format-YCNoNkM2.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { markdownToIR, renderMarkdownIRChunksWithinLimit, renderMarkdownWithMarkers } from "openclaw/plugin-sdk/text-chunking";
|
|
2
|
-
//#region extensions/slack/src/format.ts
|
|
3
|
-
function escapeSlackMrkdwnSegment(text) {
|
|
4
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
5
|
-
}
|
|
6
|
-
const SLACK_ANGLE_TOKEN_RE = /<[^>\n]+>/g;
|
|
7
|
-
function isAllowedSlackAngleToken(token) {
|
|
8
|
-
if (!token.startsWith("<") || !token.endsWith(">")) return false;
|
|
9
|
-
const inner = token.slice(1, -1);
|
|
10
|
-
return inner.startsWith("@") || inner.startsWith("#") || inner.startsWith("!") || inner.startsWith("mailto:") || inner.startsWith("tel:") || inner.startsWith("http://") || inner.startsWith("https://") || inner.startsWith("slack://");
|
|
11
|
-
}
|
|
12
|
-
function escapeSlackMrkdwnContent(text) {
|
|
13
|
-
if (!text) return "";
|
|
14
|
-
if (!text.includes("&") && !text.includes("<") && !text.includes(">")) return text;
|
|
15
|
-
SLACK_ANGLE_TOKEN_RE.lastIndex = 0;
|
|
16
|
-
const out = [];
|
|
17
|
-
let lastIndex = 0;
|
|
18
|
-
for (let match = SLACK_ANGLE_TOKEN_RE.exec(text); match; match = SLACK_ANGLE_TOKEN_RE.exec(text)) {
|
|
19
|
-
const matchIndex = match.index ?? 0;
|
|
20
|
-
out.push(escapeSlackMrkdwnSegment(text.slice(lastIndex, matchIndex)));
|
|
21
|
-
const token = match[0] ?? "";
|
|
22
|
-
out.push(isAllowedSlackAngleToken(token) ? token : escapeSlackMrkdwnSegment(token));
|
|
23
|
-
lastIndex = matchIndex + token.length;
|
|
24
|
-
}
|
|
25
|
-
out.push(escapeSlackMrkdwnSegment(text.slice(lastIndex)));
|
|
26
|
-
return out.join("");
|
|
27
|
-
}
|
|
28
|
-
function escapeSlackMrkdwnText(text) {
|
|
29
|
-
if (!text) return "";
|
|
30
|
-
if (!text.includes("&") && !text.includes("<") && !text.includes(">")) return text;
|
|
31
|
-
return text.split("\n").map((line) => {
|
|
32
|
-
if (line.startsWith("> ")) return `> ${escapeSlackMrkdwnContent(line.slice(2))}`;
|
|
33
|
-
return escapeSlackMrkdwnContent(line);
|
|
34
|
-
}).join("\n");
|
|
35
|
-
}
|
|
36
|
-
function buildSlackLink(link, text) {
|
|
37
|
-
const href = link.href.trim();
|
|
38
|
-
if (!href) return null;
|
|
39
|
-
const trimmedLabel = text.slice(link.start, link.end).trim();
|
|
40
|
-
const comparableHref = href.startsWith("mailto:") ? href.slice(7) : href;
|
|
41
|
-
if (!(trimmedLabel.length > 0 && trimmedLabel !== href && trimmedLabel !== comparableHref)) return null;
|
|
42
|
-
const safeHref = escapeSlackMrkdwnSegment(href);
|
|
43
|
-
return {
|
|
44
|
-
start: link.start,
|
|
45
|
-
end: link.end,
|
|
46
|
-
open: `<${safeHref}|`,
|
|
47
|
-
close: ">"
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
function buildSlackRenderOptions() {
|
|
51
|
-
return {
|
|
52
|
-
styleMarkers: {
|
|
53
|
-
bold: {
|
|
54
|
-
open: "*",
|
|
55
|
-
close: "*"
|
|
56
|
-
},
|
|
57
|
-
italic: {
|
|
58
|
-
open: "_",
|
|
59
|
-
close: "_"
|
|
60
|
-
},
|
|
61
|
-
strikethrough: {
|
|
62
|
-
open: "~",
|
|
63
|
-
close: "~"
|
|
64
|
-
},
|
|
65
|
-
code: {
|
|
66
|
-
open: "`",
|
|
67
|
-
close: "`"
|
|
68
|
-
},
|
|
69
|
-
code_block: {
|
|
70
|
-
open: "```\n",
|
|
71
|
-
close: "```"
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
escapeText: escapeSlackMrkdwnText,
|
|
75
|
-
buildLink: buildSlackLink
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
function markdownToSlackMrkdwn(markdown, options = {}) {
|
|
79
|
-
return renderMarkdownWithMarkers(markdownToIR(markdown ?? "", {
|
|
80
|
-
linkify: false,
|
|
81
|
-
autolink: false,
|
|
82
|
-
headingStyle: "bold",
|
|
83
|
-
blockquotePrefix: "> ",
|
|
84
|
-
tableMode: options.tableMode
|
|
85
|
-
}), buildSlackRenderOptions());
|
|
86
|
-
}
|
|
87
|
-
function normalizeSlackOutboundText(markdown) {
|
|
88
|
-
return markdownToSlackMrkdwn(markdown ?? "");
|
|
89
|
-
}
|
|
90
|
-
function markdownToSlackMrkdwnChunks(markdown, limit, options = {}) {
|
|
91
|
-
const ir = markdownToIR(markdown ?? "", {
|
|
92
|
-
linkify: false,
|
|
93
|
-
autolink: false,
|
|
94
|
-
headingStyle: "bold",
|
|
95
|
-
blockquotePrefix: "> ",
|
|
96
|
-
tableMode: options.tableMode
|
|
97
|
-
});
|
|
98
|
-
const renderOptions = buildSlackRenderOptions();
|
|
99
|
-
return renderMarkdownIRChunksWithinLimit({
|
|
100
|
-
ir,
|
|
101
|
-
limit,
|
|
102
|
-
renderChunk: (chunk) => renderMarkdownWithMarkers(chunk, renderOptions),
|
|
103
|
-
measureRendered: (rendered) => rendered.length
|
|
104
|
-
}).map(({ rendered }) => rendered);
|
|
105
|
-
}
|
|
106
|
-
//#endregion
|
|
107
|
-
export { normalizeSlackOutboundText as n, markdownToSlackMrkdwnChunks as t };
|
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
import { T as SLACK_SECTION_TEXT_MAX, _ as buildSlackPresentationBlocks, a as SLACK_TEXT_LIMIT, g as buildSlackInteractiveBlocks, r as parseSlackBlocksInput, v as canRenderSlackPresentation, w as SLACK_PRESENTATION_CAPABILITIES, y as resolveSlackInteractiveBlockOffsets } from "./reply-blocks-BGQ6zSqM.js";
|
|
2
|
-
import { n as resolveSlackThreadTsValue } from "./thread-ts-DUGhaYKq.js";
|
|
3
|
-
import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-CXpT-vA_.js";
|
|
4
|
-
import { t as markdownToSlackMrkdwnChunks } from "./format-YCNoNkM2.js";
|
|
5
|
-
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
|
-
import { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-outbound";
|
|
7
|
-
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
8
|
-
import { renderMessagePresentationFallbackText, resolveInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
|
|
9
|
-
import { resolvePayloadMediaUrls, sendPayloadMediaSequenceAndFinalize, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
|
|
10
|
-
import { attachChannelToResult, createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
|
|
11
|
-
//#region extensions/slack/src/outbound-adapter.ts
|
|
12
|
-
const loadSlackSendRuntime = createLazyRuntimeModule(() => import("./send.runtime-GPRa63l1.js"));
|
|
13
|
-
function resolveRenderedInteractiveBlocks(interactive, previousBlocks) {
|
|
14
|
-
if (!interactive) return;
|
|
15
|
-
const blocks = buildSlackInteractiveBlocks(interactive, resolveSlackInteractiveBlockOffsets(previousBlocks));
|
|
16
|
-
return blocks.length > 0 ? blocks : void 0;
|
|
17
|
-
}
|
|
18
|
-
function resolveSlackSendIdentity(identity) {
|
|
19
|
-
if (!identity) return;
|
|
20
|
-
const username = normalizeOptionalString(identity.name);
|
|
21
|
-
const iconUrl = normalizeOptionalString(identity.avatarUrl);
|
|
22
|
-
const rawEmoji = normalizeOptionalString(identity.emoji);
|
|
23
|
-
const iconEmoji = !iconUrl ? rawEmoji : void 0;
|
|
24
|
-
if (!username && !iconUrl && !iconEmoji) return;
|
|
25
|
-
return {
|
|
26
|
-
username,
|
|
27
|
-
iconUrl,
|
|
28
|
-
iconEmoji
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
function buildSlackTextSectionBlocks(text) {
|
|
32
|
-
return markdownToSlackMrkdwnChunks(text.trim(), SLACK_SECTION_TEXT_MAX).map((chunk) => ({
|
|
33
|
-
type: "section",
|
|
34
|
-
text: {
|
|
35
|
-
type: "mrkdwn",
|
|
36
|
-
text: chunk
|
|
37
|
-
}
|
|
38
|
-
}));
|
|
39
|
-
}
|
|
40
|
-
function normalizeComparableSlackText(text) {
|
|
41
|
-
return text.trim().replace(/\s+/g, " ");
|
|
42
|
-
}
|
|
43
|
-
function isPayloadTextRepresentedInInteractive(text, interactive) {
|
|
44
|
-
const target = normalizeComparableSlackText(text);
|
|
45
|
-
const fragments = interactive?.blocks.flatMap((block) => block.type === "text" ? [normalizeComparableSlackText(block.text)] : []) ?? [];
|
|
46
|
-
for (let start = 0; start < fragments.length; start += 1) {
|
|
47
|
-
let combined = "";
|
|
48
|
-
for (let end = start; end < fragments.length; end += 1) {
|
|
49
|
-
combined = normalizeComparableSlackText(`${combined} ${fragments[end]}`);
|
|
50
|
-
if (combined === target) return true;
|
|
51
|
-
if (combined.length > target.length) break;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
function buildSlackVisiblePayloadTextBlocks(payload) {
|
|
57
|
-
const text = normalizeOptionalString(payload.text);
|
|
58
|
-
if (!text || isPayloadTextRepresentedInInteractive(text, payload.interactive)) return [];
|
|
59
|
-
return buildSlackTextSectionBlocks(text);
|
|
60
|
-
}
|
|
61
|
-
function buildSlackPresentationFallback(presentation) {
|
|
62
|
-
const text = renderMessagePresentationFallbackText({ presentation }).trim();
|
|
63
|
-
return {
|
|
64
|
-
blocks: buildSlackTextSectionBlocks(text),
|
|
65
|
-
text
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function withSlackPresentationData(payload, slackData, presentationData) {
|
|
69
|
-
const { presentationBlocks: _presentationBlocks, presentationFallbackText: _presentationFallbackText, ...rest } = slackData ?? {};
|
|
70
|
-
return {
|
|
71
|
-
...payload,
|
|
72
|
-
channelData: {
|
|
73
|
-
...payload.channelData,
|
|
74
|
-
slack: {
|
|
75
|
-
...rest,
|
|
76
|
-
...presentationData
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
async function sendSlackOutboundMessage(params) {
|
|
82
|
-
const send = resolveOutboundSendDep(params.deps, "slack") ?? (await loadSlackSendRuntime()).sendMessageSlack;
|
|
83
|
-
const slackIdentity = resolveSlackSendIdentity(params.identity);
|
|
84
|
-
const threadTs = resolveSlackThreadTsValue({
|
|
85
|
-
replyToId: params.replyToId,
|
|
86
|
-
threadId: params.threadId
|
|
87
|
-
});
|
|
88
|
-
return await send(params.to, params.text, {
|
|
89
|
-
cfg: params.cfg,
|
|
90
|
-
threadTs,
|
|
91
|
-
accountId: params.accountId ?? void 0,
|
|
92
|
-
...params.mediaUrl ? {
|
|
93
|
-
mediaUrl: params.mediaUrl,
|
|
94
|
-
mediaAccess: params.mediaAccess,
|
|
95
|
-
mediaLocalRoots: params.mediaLocalRoots,
|
|
96
|
-
mediaReadFile: params.mediaReadFile
|
|
97
|
-
} : {},
|
|
98
|
-
...params.blocks ? { blocks: params.blocks } : {},
|
|
99
|
-
...slackIdentity ? { identity: slackIdentity } : {},
|
|
100
|
-
deliveryQueueId: params.deliveryQueueId,
|
|
101
|
-
onPlatformSendDispatch: params.onPlatformSendDispatch,
|
|
102
|
-
onDeliveryResult: params.onDeliveryResult ? async (progress) => {
|
|
103
|
-
await params.onDeliveryResult?.(attachChannelToResult("slack", progress));
|
|
104
|
-
} : void 0
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
function resolveSlackBlocks(payload) {
|
|
108
|
-
const slackData = payload.channelData?.slack;
|
|
109
|
-
const nativeBlocks = parseSlackBlocksInput(slackData?.blocks);
|
|
110
|
-
const renderedPresentation = slackData?.presentationBlocks ?? (payload.presentation ? [...buildSlackVisiblePayloadTextBlocks(payload), ...buildSlackPresentationBlocks(payload.presentation, resolveSlackInteractiveBlockOffsets(nativeBlocks))] : []);
|
|
111
|
-
const previousBlocks = [...nativeBlocks ?? [], ...renderedPresentation];
|
|
112
|
-
const renderedInteractive = resolveRenderedInteractiveBlocks(payload.interactive, previousBlocks);
|
|
113
|
-
const mergedBlocks = [...previousBlocks, ...renderedInteractive ?? []];
|
|
114
|
-
if (mergedBlocks.length === 0) return;
|
|
115
|
-
if (mergedBlocks.length > 50) throw new Error(`Slack blocks cannot exceed 50 items after interactive render`);
|
|
116
|
-
return mergedBlocks;
|
|
117
|
-
}
|
|
118
|
-
const slackOutbound = {
|
|
119
|
-
deliveryMode: "direct",
|
|
120
|
-
chunker: null,
|
|
121
|
-
textChunkLimit: SLACK_TEXT_LIMIT,
|
|
122
|
-
normalizePayload: ({ payload, cfg, accountId }) => isSlackInteractiveRepliesEnabled({
|
|
123
|
-
cfg,
|
|
124
|
-
accountId
|
|
125
|
-
}) ? compileSlackInteractiveReplies(payload) : payload,
|
|
126
|
-
presentationCapabilities: SLACK_PRESENTATION_CAPABILITIES,
|
|
127
|
-
renderPresentation: ({ payload, presentation, ctx }) => {
|
|
128
|
-
const payloadForBudget = isSlackInteractiveRepliesEnabled({
|
|
129
|
-
cfg: ctx.cfg,
|
|
130
|
-
accountId: ctx.accountId
|
|
131
|
-
}) ? compileSlackInteractiveReplies(payload) : payload;
|
|
132
|
-
const slackData = payload.channelData?.slack;
|
|
133
|
-
const nativeBlocks = parseSlackBlocksInput(slackData?.blocks);
|
|
134
|
-
const payloadTextBlocks = buildSlackVisiblePayloadTextBlocks(payloadForBudget);
|
|
135
|
-
if (canRenderSlackPresentation(presentation)) {
|
|
136
|
-
const presentationBlocks = [...payloadTextBlocks, ...buildSlackPresentationBlocks(presentation, resolveSlackInteractiveBlockOffsets(nativeBlocks))];
|
|
137
|
-
const previousBlocks = [...nativeBlocks ?? [], ...presentationBlocks];
|
|
138
|
-
const interactiveBlocks = resolveRenderedInteractiveBlocks(payloadForBudget.interactive, previousBlocks);
|
|
139
|
-
if (presentationBlocks.length > 0 && previousBlocks.length + (interactiveBlocks?.length ?? 0) <= 50) return withSlackPresentationData(payloadForBudget, slackData, { presentationBlocks });
|
|
140
|
-
}
|
|
141
|
-
const baseInteractiveBlocks = resolveRenderedInteractiveBlocks(payloadForBudget.interactive, nativeBlocks);
|
|
142
|
-
if ((nativeBlocks?.length ?? 0) + (baseInteractiveBlocks?.length ?? 0) === 0) return null;
|
|
143
|
-
const fallback = buildSlackPresentationFallback(presentation);
|
|
144
|
-
const fallbackBlocks = [...payloadTextBlocks, ...fallback.blocks];
|
|
145
|
-
if (fallbackBlocks.length === 0) return null;
|
|
146
|
-
const fallbackPayload = {
|
|
147
|
-
...payloadForBudget,
|
|
148
|
-
text: renderMessagePresentationFallbackText({
|
|
149
|
-
text: payloadForBudget.text,
|
|
150
|
-
presentation
|
|
151
|
-
})
|
|
152
|
-
};
|
|
153
|
-
const fallbackPreviousBlocks = [...nativeBlocks ?? [], ...fallbackBlocks];
|
|
154
|
-
const fallbackInteractiveBlocks = resolveRenderedInteractiveBlocks(payloadForBudget.interactive, fallbackPreviousBlocks);
|
|
155
|
-
if (fallbackPreviousBlocks.length + (fallbackInteractiveBlocks?.length ?? 0) <= 50) return withSlackPresentationData(fallbackPayload, slackData, { presentationBlocks: fallbackBlocks });
|
|
156
|
-
const separateFallbackText = renderMessagePresentationFallbackText({
|
|
157
|
-
text: payloadTextBlocks.length > 0 ? payloadForBudget.text : void 0,
|
|
158
|
-
presentation
|
|
159
|
-
});
|
|
160
|
-
return withSlackPresentationData(payloadTextBlocks.length > 0 ? {
|
|
161
|
-
...payloadForBudget,
|
|
162
|
-
text: void 0
|
|
163
|
-
} : payloadForBudget, slackData, { presentationFallbackText: separateFallbackText });
|
|
164
|
-
},
|
|
165
|
-
sendPayload: async (ctx) => {
|
|
166
|
-
const payload = {
|
|
167
|
-
...ctx.payload,
|
|
168
|
-
text: resolveInteractiveTextFallback({
|
|
169
|
-
text: ctx.payload.text,
|
|
170
|
-
interactive: ctx.payload.interactive
|
|
171
|
-
}) ?? ""
|
|
172
|
-
};
|
|
173
|
-
const slackData = payload.channelData?.slack;
|
|
174
|
-
const presentationFallbackText = normalizeOptionalString(slackData?.presentationFallbackText);
|
|
175
|
-
const blocks = resolveSlackBlocks(payload);
|
|
176
|
-
if (!blocks) return await sendTextMediaPayload({
|
|
177
|
-
channel: "slack",
|
|
178
|
-
ctx: {
|
|
179
|
-
...ctx,
|
|
180
|
-
payload: presentationFallbackText ? {
|
|
181
|
-
...payload,
|
|
182
|
-
text: [normalizeOptionalString(payload.text), presentationFallbackText].filter((part) => Boolean(part)).join("\n\n")
|
|
183
|
-
} : payload
|
|
184
|
-
},
|
|
185
|
-
adapter: slackOutbound
|
|
186
|
-
});
|
|
187
|
-
return attachChannelToResult("slack", await sendPayloadMediaSequenceAndFinalize({
|
|
188
|
-
text: "",
|
|
189
|
-
mediaUrls: resolvePayloadMediaUrls(payload),
|
|
190
|
-
send: async ({ text, mediaUrl }) => await sendSlackOutboundMessage({
|
|
191
|
-
cfg: ctx.cfg,
|
|
192
|
-
to: ctx.to,
|
|
193
|
-
text,
|
|
194
|
-
mediaUrl,
|
|
195
|
-
mediaAccess: ctx.mediaAccess,
|
|
196
|
-
mediaLocalRoots: ctx.mediaLocalRoots,
|
|
197
|
-
mediaReadFile: ctx.mediaReadFile,
|
|
198
|
-
accountId: ctx.accountId,
|
|
199
|
-
deps: ctx.deps,
|
|
200
|
-
replyToId: ctx.replyToId,
|
|
201
|
-
threadId: ctx.threadId,
|
|
202
|
-
identity: ctx.identity,
|
|
203
|
-
onDeliveryResult: ctx.onDeliveryResult
|
|
204
|
-
}),
|
|
205
|
-
finalize: async () => {
|
|
206
|
-
const blockResult = await sendSlackOutboundMessage({
|
|
207
|
-
cfg: ctx.cfg,
|
|
208
|
-
to: ctx.to,
|
|
209
|
-
text: payload.text ?? "",
|
|
210
|
-
mediaAccess: ctx.mediaAccess,
|
|
211
|
-
mediaLocalRoots: ctx.mediaLocalRoots,
|
|
212
|
-
mediaReadFile: ctx.mediaReadFile,
|
|
213
|
-
blocks,
|
|
214
|
-
accountId: ctx.accountId,
|
|
215
|
-
deps: ctx.deps,
|
|
216
|
-
replyToId: ctx.replyToId,
|
|
217
|
-
threadId: ctx.threadId,
|
|
218
|
-
identity: ctx.identity,
|
|
219
|
-
onDeliveryResult: ctx.onDeliveryResult
|
|
220
|
-
});
|
|
221
|
-
if (!presentationFallbackText) return blockResult;
|
|
222
|
-
return await sendSlackOutboundMessage({
|
|
223
|
-
cfg: ctx.cfg,
|
|
224
|
-
to: ctx.to,
|
|
225
|
-
text: presentationFallbackText,
|
|
226
|
-
mediaAccess: ctx.mediaAccess,
|
|
227
|
-
mediaLocalRoots: ctx.mediaLocalRoots,
|
|
228
|
-
mediaReadFile: ctx.mediaReadFile,
|
|
229
|
-
accountId: ctx.accountId,
|
|
230
|
-
deps: ctx.deps,
|
|
231
|
-
replyToId: ctx.replyToId,
|
|
232
|
-
threadId: ctx.threadId,
|
|
233
|
-
identity: ctx.identity,
|
|
234
|
-
onDeliveryResult: ctx.onDeliveryResult
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
}));
|
|
238
|
-
},
|
|
239
|
-
...createAttachedChannelResultAdapter({
|
|
240
|
-
channel: "slack",
|
|
241
|
-
sendText: async ({ cfg, to, text, accountId, deps, replyToId, threadId, identity, deliveryQueueId, onPlatformSendDispatch, onDeliveryResult }) => await sendSlackOutboundMessage({
|
|
242
|
-
cfg,
|
|
243
|
-
to,
|
|
244
|
-
text,
|
|
245
|
-
accountId,
|
|
246
|
-
deps,
|
|
247
|
-
replyToId,
|
|
248
|
-
threadId,
|
|
249
|
-
identity,
|
|
250
|
-
deliveryQueueId,
|
|
251
|
-
onPlatformSendDispatch,
|
|
252
|
-
onDeliveryResult
|
|
253
|
-
}),
|
|
254
|
-
sendMedia: async ({ cfg, to, text, mediaUrl, mediaAccess, mediaLocalRoots, mediaReadFile, accountId, deps, replyToId, threadId, identity, onDeliveryResult }) => await sendSlackOutboundMessage({
|
|
255
|
-
cfg,
|
|
256
|
-
to,
|
|
257
|
-
text,
|
|
258
|
-
mediaUrl,
|
|
259
|
-
mediaAccess,
|
|
260
|
-
mediaLocalRoots,
|
|
261
|
-
mediaReadFile,
|
|
262
|
-
accountId,
|
|
263
|
-
deps,
|
|
264
|
-
replyToId,
|
|
265
|
-
threadId,
|
|
266
|
-
identity,
|
|
267
|
-
onDeliveryResult
|
|
268
|
-
})
|
|
269
|
-
})
|
|
270
|
-
};
|
|
271
|
-
//#endregion
|
|
272
|
-
export { slackOutbound };
|