@openclaw/slack 2026.5.14-beta.1 → 2026.5.14-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/{action-runtime-gtC-RM3r.js → action-runtime-CyE2jfW-.js} +4 -4
- package/dist/action-runtime.runtime-DLhfKw4B.js +2 -0
- package/dist/{media-B-nNpS2G.js → actions-BibhOXpJ.js} +307 -2
- package/dist/{actions.runtime-DD6hfFCA.js → actions.runtime-B9XQG6X4.js} +1 -1
- package/dist/api.js +16 -16
- package/dist/{approval-handler.runtime-DeYBuIaU.js → approval-handler.runtime-BjzVRaXN.js} +3 -4
- package/dist/{blocks-render-BdLueE_v.js → blocks-render-BAVfd6r0.js} +1 -1
- package/dist/{channel-CC04F-xs.js → channel-Dh07mU_K.js} +23 -27
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.setup-jzYjY634.js → channel.setup-CmG37S2W.js} +3 -3
- package/dist/{client-8r7r7aZ3.js → client-C_IaJbi5.js} +20 -1
- package/dist/{config-schema-Bueih4yH.js → config-schema-CNRousxw.js} +1 -1
- package/dist/contract-api.js +4 -4
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-CuaWaGnM.js → directory-live-CZPzpQZF.js} +1 -1
- package/dist/{doctor-contract-DCkS8eNN.js → doctor-contract-B8QIWMs1.js} +1 -1
- package/dist/doctor-contract-api.js +1 -1
- package/dist/http-routes-api.js +1 -1
- package/dist/inbound-contract-test-api.js +2 -2
- package/dist/interactive-replies-api.js +1 -1
- package/dist/{message-tool-api-B_bKUmP0.js → message-tool-api-C7gc7goF.js} +1 -1
- package/dist/message-tool-api.js +1 -1
- package/dist/{monitor-B3QB1ysK.js → monitor-DDE5AI2O.js} +3 -3
- package/dist/{outbound-adapter-DsAvCwpZ.js → outbound-adapter-BluPNDNi.js} +4 -5
- package/dist/outbound-payload-test-api.js +1 -1
- package/dist/{outbound-payload.test-harness-DM9ZdY2f.js → outbound-payload.test-harness-BNxnP6MC.js} +2 -2
- package/dist/{pipeline.runtime-D-YJZZaI.js → pipeline.runtime-Dft2-QU4.js} +11 -12
- package/dist/{plugin-routes-Dt_jh9W8.js → plugin-routes-CRnfsTTX.js} +1 -1
- package/dist/{prepare-CXI8nHbJ.js → prepare-D0tMg4dt.js} +8 -9
- package/dist/{prepare.test-helpers-BhFHtbz3.js → prepare.test-helpers-CU1qB54Q.js} +1 -1
- package/dist/{probe-D1wYA05H.js → probe-FL4sUJsH.js} +2 -2
- package/dist/{provider-Ut7IF0Mn.js → provider-C6WxaFFf.js} +21 -19
- package/dist/{replies-CzfjCaLG.js → replies-D0QXXSPP.js} +4 -4
- package/dist/reply-blocks-BFaJ_ejG.js +134 -0
- package/dist/{resolve-channels-BiVxSLVm.js → resolve-channels-B_eKaOkE.js} +2 -2
- package/dist/{resolve-users-CcpSlYw-.js → resolve-users-BzBAJwvq.js} +2 -2
- package/dist/{room-context-D0hGOp8m.js → room-context-Cd8jFpS-.js} +2 -2
- package/dist/{runtime-api-D8wiG9BS.js → runtime-api-B5HGOzX3.js} +2 -2
- package/dist/runtime-api.js +12 -12
- package/dist/runtime-setter-api.js +1 -1
- package/dist/{scopes-BTkB8PPE.js → scopes-Bvg_ZzqZ.js} +2 -2
- package/dist/secret-contract-api.js +1 -1
- package/dist/security-contract-api.js +1 -1
- package/dist/{send-ioky2Xpy.js → send-Dg9zcyYT.js} +4 -5
- package/dist/send.runtime-CjjQ9StM.js +2 -0
- package/dist/send.runtime-E47jGN-2.js +2 -0
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-B6w9gtds.js → setup-surface-BLoTgna4.js} +4 -4
- package/dist/{shared-CSiHkaVO.js → shared-GoB-OuUq.js} +7 -7
- package/dist/{slash-dispatch.runtime-DNr1EDON.js → slash-dispatch.runtime-Bz_OkRcR.js} +1 -1
- package/dist/test-api.js +7 -7
- package/dist/thread-ts-As_dcNbD.js +52 -0
- package/package.json +5 -5
- package/dist/action-runtime.runtime-DbVd7_Na.js +0 -2
- package/dist/actions-Cqyj7oRr.js +0 -309
- package/dist/approval-auth-D3xf0sS6.js +0 -28
- package/dist/blocks-input-BJZ8vv03.js +0 -29
- package/dist/channel-api-BfBK89IN.js +0 -20
- package/dist/exec-approvals-BLn4Zx7V.js +0 -58
- package/dist/group-policy-utF2iWnE.js +0 -41
- package/dist/mrkdwn-18IzcEAY.js +0 -6
- package/dist/reply-blocks-DWoZrUll.js +0 -14
- package/dist/send.runtime-5Kl3Wzbf.js +0 -2
- package/dist/send.runtime-DoifekaA.js +0 -2
- package/dist/thread-ts-o-QBwB3k.js +0 -24
- /package/dist/{accounts.runtime-CkfFIisb.js → accounts.runtime-BhbEu1ZK.js} +0 -0
- /package/dist/{allow-list-T7ZDpUsF.js → allow-list-nwXs_eCP.js} +0 -0
- /package/dist/{config-api-B48Z4H47.js → config-api-CmgE_ORg.js} +0 -0
- /package/dist/{directory-config-BKKNBkCq.js → directory-config-CMvFiswf.js} +0 -0
- /package/dist/{errors-BrtayXHa.js → errors-C_sW0Zgl.js} +0 -0
- /package/dist/{interactive-replies-CawNPL-h.js → interactive-replies-BSg5hXhj.js} +0 -0
- /package/dist/{magic-string.es-BLAi6qQC.js → magic-string.es-9lw4MGoF.js} +0 -0
- /package/dist/{registry-BdfKYina.js → registry-D2cWOLZV.js} +0 -0
- /package/dist/{resolve-allowlist-common-rhfyDyWi.js → resolve-allowlist-common-DLub2I2i.js} +0 -0
- /package/dist/{runtime--VlVtTPu.js → runtime-DQxkf7k2.js} +0 -0
- /package/dist/{secret-contract-BurGIyhv.js → secret-contract-0TL3L5Kb.js} +0 -0
- /package/dist/{security-audit-DvOpSaZM.js → security-audit-BJzADAw3.js} +0 -0
- /package/dist/{setup-core-DgLJ7dQY.js → setup-core-WWQl-cE9.js} +0 -0
- /package/dist/{slash-commands.runtime-DRkNgIQ2.js → slash-commands.runtime-bcDwsGnu.js} +0 -0
- /package/dist/{slash-plugin-commands.runtime-Dj5h8hmv.js → slash-plugin-commands.runtime-DBHGUSj2.js} +0 -0
- /package/dist/{slash-skill-commands.runtime-B-_KAk0C.js → slash-skill-commands.runtime-rrY2hXvN.js} +0 -0
- /package/dist/{streaming-compat-C6rySwiD.js → streaming-compat-eu5Rj5gj.js} +0 -0
package/dist/test-api.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as createSlackActions, t as slackPlugin } from "./channel-
|
|
2
|
-
import { n as setSlackRuntime } from "./runtime
|
|
3
|
-
import { t as sendMessageSlack } from "./send-
|
|
4
|
-
import { t as prepareSlackMessage } from "./prepare-
|
|
5
|
-
import { t as createInboundSlackTestContext } from "./prepare.test-helpers-
|
|
6
|
-
import { t as createSlackOutboundPayloadHarness } from "./outbound-payload.test-harness-
|
|
7
|
-
import { n as slackOutbound } from "./outbound-adapter-
|
|
1
|
+
import { a as createSlackActions, t as slackPlugin } from "./channel-Dh07mU_K.js";
|
|
2
|
+
import { n as setSlackRuntime } from "./runtime-DQxkf7k2.js";
|
|
3
|
+
import { t as sendMessageSlack } from "./send-Dg9zcyYT.js";
|
|
4
|
+
import { t as prepareSlackMessage } from "./prepare-D0tMg4dt.js";
|
|
5
|
+
import { t as createInboundSlackTestContext } from "./prepare.test-helpers-CU1qB54Q.js";
|
|
6
|
+
import { t as createSlackOutboundPayloadHarness } from "./outbound-payload.test-harness-BNxnP6MC.js";
|
|
7
|
+
import { n as slackOutbound } from "./outbound-adapter-BluPNDNi.js";
|
|
8
8
|
export { createInboundSlackTestContext, createSlackActions, createSlackOutboundPayloadHarness, prepareSlackMessage, sendMessageSlack, setSlackRuntime, slackOutbound, slackPlugin };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
|
+
//#region extensions/slack/src/truncate.ts
|
|
3
|
+
function truncateSlackText(value, max) {
|
|
4
|
+
const trimmed = value.trim();
|
|
5
|
+
if (trimmed.length <= max) return trimmed;
|
|
6
|
+
if (max <= 1) return trimmed.slice(0, max);
|
|
7
|
+
return `${trimmed.slice(0, max - 1)}…`;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region extensions/slack/src/limits.ts
|
|
11
|
+
const SLACK_TEXT_LIMIT = 8e3;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region extensions/slack/src/blocks-input.ts
|
|
14
|
+
const SLACK_MAX_BLOCKS = 50;
|
|
15
|
+
function parseBlocksJson(raw) {
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(raw);
|
|
18
|
+
} catch {
|
|
19
|
+
throw new Error("blocks must be valid JSON");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function assertBlocksArray(raw) {
|
|
23
|
+
if (!Array.isArray(raw)) throw new Error("blocks must be an array");
|
|
24
|
+
if (raw.length === 0) throw new Error("blocks must contain at least one block");
|
|
25
|
+
if (raw.length > 50) throw new Error(`blocks cannot exceed 50 items`);
|
|
26
|
+
for (const block of raw) {
|
|
27
|
+
if (!block || typeof block !== "object" || Array.isArray(block)) throw new Error("each block must be an object");
|
|
28
|
+
const type = block.type;
|
|
29
|
+
if (typeof type !== "string" || type.trim().length === 0) throw new Error("each block must include a non-empty string type");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function validateSlackBlocksArray(raw) {
|
|
33
|
+
assertBlocksArray(raw);
|
|
34
|
+
return raw;
|
|
35
|
+
}
|
|
36
|
+
function parseSlackBlocksInput(raw) {
|
|
37
|
+
if (raw == null) return;
|
|
38
|
+
return validateSlackBlocksArray(typeof raw === "string" ? parseBlocksJson(raw) : raw);
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region extensions/slack/src/thread-ts.ts
|
|
42
|
+
const SLACK_THREAD_TS_PATTERN = /^\d+\.\d+$/;
|
|
43
|
+
function normalizeSlackThreadTsCandidate(value) {
|
|
44
|
+
if (typeof value !== "string") return;
|
|
45
|
+
const normalized = normalizeOptionalString(value);
|
|
46
|
+
return normalized && SLACK_THREAD_TS_PATTERN.test(normalized) ? normalized : void 0;
|
|
47
|
+
}
|
|
48
|
+
function resolveSlackThreadTsValue(params) {
|
|
49
|
+
return normalizeSlackThreadTsCandidate(params.replyToId) ?? normalizeSlackThreadTsCandidate(params.threadId);
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { validateSlackBlocksArray as a, parseSlackBlocksInput as i, resolveSlackThreadTsValue as n, SLACK_TEXT_LIMIT as o, SLACK_MAX_BLOCKS as r, truncateSlackText as s, normalizeSlackThreadTsCandidate as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/slack",
|
|
3
|
-
"version": "2026.5.14-beta.
|
|
3
|
+
"version": "2026.5.14-beta.2",
|
|
4
4
|
"description": "OpenClaw Slack channel plugin",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@slack/bolt": "4.7.2",
|
|
12
12
|
"@slack/types": "2.21.1",
|
|
13
|
-
"@slack/web-api": "7.
|
|
13
|
+
"@slack/web-api": "7.16.0",
|
|
14
14
|
"https-proxy-agent": "9.0.0",
|
|
15
15
|
"typebox": "1.1.38",
|
|
16
16
|
"zod": "4.4.3"
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"openclaw": "workspace:*"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"openclaw": ">=2026.5.14-beta.
|
|
23
|
+
"openclaw": ">=2026.5.14-beta.2"
|
|
24
24
|
},
|
|
25
25
|
"peerDependenciesMeta": {
|
|
26
26
|
"openclaw": {
|
|
@@ -64,10 +64,10 @@
|
|
|
64
64
|
"minHostVersion": ">=2026.5.12-beta.1"
|
|
65
65
|
},
|
|
66
66
|
"compat": {
|
|
67
|
-
"pluginApi": ">=2026.5.14-beta.
|
|
67
|
+
"pluginApi": ">=2026.5.14-beta.2"
|
|
68
68
|
},
|
|
69
69
|
"build": {
|
|
70
|
-
"openclawVersion": "2026.5.14-beta.
|
|
70
|
+
"openclawVersion": "2026.5.14-beta.2",
|
|
71
71
|
"bundledDist": false
|
|
72
72
|
},
|
|
73
73
|
"release": {
|
package/dist/actions-Cqyj7oRr.js
DELETED
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
import { a as resolveSlackAccount, d as resolveSlackBotToken } from "./accounts-yk5K3wQU.js";
|
|
2
|
-
import { i as truncateSlackText, r as SLACK_TEXT_LIMIT } from "./thread-ts-o-QBwB3k.js";
|
|
3
|
-
import { a as getSlackWriteClient, r as createSlackWebClient } from "./client-8r7r7aZ3.js";
|
|
4
|
-
import { r as validateSlackBlocksArray } from "./blocks-input-BJZ8vv03.js";
|
|
5
|
-
import { c as buildSlackBlocksFallbackText, t as sendMessageSlack } from "./send-ioky2Xpy.js";
|
|
6
|
-
import { n as resolveSlackMedia } from "./media-B-nNpS2G.js";
|
|
7
|
-
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
8
|
-
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
9
|
-
import { z } from "zod";
|
|
10
|
-
//#region extensions/slack/src/edit-text.ts
|
|
11
|
-
function buildSlackEditTextPayload(content, blocks) {
|
|
12
|
-
const trimmedContent = content.trim();
|
|
13
|
-
if (trimmedContent) return trimmedContent;
|
|
14
|
-
if (blocks?.length) return truncateSlackText(buildSlackBlocksFallbackText(blocks), SLACK_TEXT_LIMIT);
|
|
15
|
-
return " ";
|
|
16
|
-
}
|
|
17
|
-
//#endregion
|
|
18
|
-
//#region extensions/slack/src/actions.ts
|
|
19
|
-
function resolveToken(explicit, accountId, cfg) {
|
|
20
|
-
if (explicit?.trim()) {
|
|
21
|
-
const token = resolveSlackBotToken(explicit);
|
|
22
|
-
if (token) return token;
|
|
23
|
-
}
|
|
24
|
-
if (!cfg) throw new Error("Slack actions requires a resolved runtime config. Load and resolve config at the command or gateway boundary, then pass cfg through the runtime path.");
|
|
25
|
-
const account = resolveSlackAccount({
|
|
26
|
-
cfg: requireRuntimeConfig(cfg, "Slack actions"),
|
|
27
|
-
accountId
|
|
28
|
-
});
|
|
29
|
-
const token = resolveSlackBotToken(account.botToken ?? void 0);
|
|
30
|
-
if (!token) {
|
|
31
|
-
logVerbose(`slack actions: missing bot token for account=${account.accountId} explicit=${Boolean(explicit)} source=${account.botTokenSource ?? "unknown"}`);
|
|
32
|
-
throw new Error("SLACK_BOT_TOKEN or channels.slack.botToken is required for Slack actions");
|
|
33
|
-
}
|
|
34
|
-
return token;
|
|
35
|
-
}
|
|
36
|
-
function normalizeEmoji(raw) {
|
|
37
|
-
const trimmed = raw.trim();
|
|
38
|
-
if (!trimmed) throw new Error("Emoji is required for Slack reactions");
|
|
39
|
-
return trimmed.replace(/^:+|:+$/g, "");
|
|
40
|
-
}
|
|
41
|
-
const SLACK_TIMESTAMP_RE = /^\d+(?:\.\d+)?$/;
|
|
42
|
-
const ISO_8601_TIMESTAMP_SCHEMA = z.iso.datetime({ offset: true });
|
|
43
|
-
function formatEpochSeconds(milliseconds) {
|
|
44
|
-
const seconds = milliseconds / 1e3;
|
|
45
|
-
if (Number.isInteger(seconds)) return String(seconds);
|
|
46
|
-
return seconds.toFixed(3).replace(/0+$/, "").replace(/\.$/, "");
|
|
47
|
-
}
|
|
48
|
-
function normalizeSlackReadTimestamp(raw, field) {
|
|
49
|
-
const trimmed = raw?.trim();
|
|
50
|
-
if (!trimmed) return;
|
|
51
|
-
if (SLACK_TIMESTAMP_RE.test(trimmed)) return trimmed;
|
|
52
|
-
if (!ISO_8601_TIMESTAMP_SCHEMA.safeParse(trimmed).success) throw new Error(`Invalid Slack read ${field} timestamp "${trimmed}": expected a Slack timestamp or ISO-8601 date string`);
|
|
53
|
-
const parsed = Date.parse(trimmed);
|
|
54
|
-
if (!Number.isFinite(parsed)) throw new Error(`Invalid Slack read ${field} timestamp "${trimmed}": expected a Slack timestamp or ISO-8601 date string`);
|
|
55
|
-
return formatEpochSeconds(parsed);
|
|
56
|
-
}
|
|
57
|
-
function hasSlackPlatformError(err, code) {
|
|
58
|
-
if (!err || typeof err !== "object") return false;
|
|
59
|
-
const data = err.data;
|
|
60
|
-
if (!data || typeof data !== "object") return false;
|
|
61
|
-
return data.error === code;
|
|
62
|
-
}
|
|
63
|
-
async function getClient(opts = {}, mode = "read") {
|
|
64
|
-
if (opts.client) return opts.client;
|
|
65
|
-
const token = resolveToken(opts.token, opts.accountId, opts.cfg);
|
|
66
|
-
return mode === "write" ? getSlackWriteClient(token) : createSlackWebClient(token);
|
|
67
|
-
}
|
|
68
|
-
async function resolveBotUserId(client) {
|
|
69
|
-
const auth = await client.auth.test();
|
|
70
|
-
if (!auth?.user_id) throw new Error("Failed to resolve Slack bot user id");
|
|
71
|
-
return auth.user_id;
|
|
72
|
-
}
|
|
73
|
-
async function reactSlackMessage(channelId, messageId, emoji, opts = {}) {
|
|
74
|
-
const client = await getClient(opts, "write");
|
|
75
|
-
try {
|
|
76
|
-
await client.reactions.add({
|
|
77
|
-
channel: channelId,
|
|
78
|
-
timestamp: messageId,
|
|
79
|
-
name: normalizeEmoji(emoji)
|
|
80
|
-
});
|
|
81
|
-
} catch (err) {
|
|
82
|
-
if (hasSlackPlatformError(err, "already_reacted")) return;
|
|
83
|
-
throw err;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
async function removeSlackReaction(channelId, messageId, emoji, opts = {}) {
|
|
87
|
-
const client = await getClient(opts, "write");
|
|
88
|
-
try {
|
|
89
|
-
await client.reactions.remove({
|
|
90
|
-
channel: channelId,
|
|
91
|
-
timestamp: messageId,
|
|
92
|
-
name: normalizeEmoji(emoji)
|
|
93
|
-
});
|
|
94
|
-
} catch (err) {
|
|
95
|
-
if (hasSlackPlatformError(err, "no_reaction")) return;
|
|
96
|
-
throw err;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
async function removeOwnSlackReactions(channelId, messageId, opts = {}) {
|
|
100
|
-
const client = await getClient(opts, "write");
|
|
101
|
-
const userId = await resolveBotUserId(client);
|
|
102
|
-
const reactions = await listSlackReactions(channelId, messageId, { client });
|
|
103
|
-
const toRemove = /* @__PURE__ */ new Set();
|
|
104
|
-
for (const reaction of reactions ?? []) {
|
|
105
|
-
const name = reaction?.name;
|
|
106
|
-
if (!name) continue;
|
|
107
|
-
if ((reaction?.users ?? []).includes(userId)) toRemove.add(name);
|
|
108
|
-
}
|
|
109
|
-
if (toRemove.size === 0) return [];
|
|
110
|
-
await Promise.all(Array.from(toRemove, (name) => removeSlackReaction(channelId, messageId, name, {
|
|
111
|
-
...opts,
|
|
112
|
-
client
|
|
113
|
-
})));
|
|
114
|
-
return Array.from(toRemove);
|
|
115
|
-
}
|
|
116
|
-
async function listSlackReactions(channelId, messageId, opts = {}) {
|
|
117
|
-
return (await (await getClient(opts)).reactions.get({
|
|
118
|
-
channel: channelId,
|
|
119
|
-
timestamp: messageId,
|
|
120
|
-
full: true
|
|
121
|
-
})).message?.reactions ?? [];
|
|
122
|
-
}
|
|
123
|
-
async function sendSlackMessage(to, content, opts) {
|
|
124
|
-
return await sendMessageSlack(to, content, {
|
|
125
|
-
accountId: opts.accountId,
|
|
126
|
-
cfg: opts.cfg,
|
|
127
|
-
token: opts.token,
|
|
128
|
-
mediaUrl: opts.mediaUrl,
|
|
129
|
-
mediaAccess: opts.mediaAccess,
|
|
130
|
-
mediaLocalRoots: opts.mediaLocalRoots,
|
|
131
|
-
mediaReadFile: opts.mediaReadFile,
|
|
132
|
-
client: opts.client,
|
|
133
|
-
threadTs: opts.threadTs,
|
|
134
|
-
replyBroadcast: opts.replyBroadcast,
|
|
135
|
-
...opts.uploadFileName ? { uploadFileName: opts.uploadFileName } : {},
|
|
136
|
-
...opts.uploadTitle ? { uploadTitle: opts.uploadTitle } : {},
|
|
137
|
-
blocks: opts.blocks
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
async function editSlackMessage(channelId, messageId, content, opts = {}) {
|
|
141
|
-
const client = await getClient(opts, "write");
|
|
142
|
-
const blocks = opts.blocks == null ? void 0 : validateSlackBlocksArray(opts.blocks);
|
|
143
|
-
await client.chat.update({
|
|
144
|
-
channel: channelId,
|
|
145
|
-
ts: messageId,
|
|
146
|
-
text: buildSlackEditTextPayload(content, blocks),
|
|
147
|
-
...blocks ? { blocks } : {}
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
async function deleteSlackMessage(channelId, messageId, opts = {}) {
|
|
151
|
-
await (await getClient(opts, "write")).chat.delete({
|
|
152
|
-
channel: channelId,
|
|
153
|
-
ts: messageId
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
async function readSlackMessages(channelId, opts = {}) {
|
|
157
|
-
const exactMessageId = opts.messageId?.trim();
|
|
158
|
-
const readLimit = exactMessageId ? 1 : opts.limit;
|
|
159
|
-
const exactBounds = exactMessageId ? {
|
|
160
|
-
inclusive: true,
|
|
161
|
-
latest: exactMessageId,
|
|
162
|
-
oldest: void 0
|
|
163
|
-
} : {
|
|
164
|
-
latest: normalizeSlackReadTimestamp(opts.before, "before"),
|
|
165
|
-
oldest: normalizeSlackReadTimestamp(opts.after, "after")
|
|
166
|
-
};
|
|
167
|
-
const client = await getClient(opts);
|
|
168
|
-
if (opts.threadId) {
|
|
169
|
-
const result = await client.conversations.replies({
|
|
170
|
-
channel: channelId,
|
|
171
|
-
ts: opts.threadId,
|
|
172
|
-
limit: readLimit,
|
|
173
|
-
...exactBounds
|
|
174
|
-
});
|
|
175
|
-
return {
|
|
176
|
-
messages: (result.messages ?? []).filter((message) => {
|
|
177
|
-
if (exactMessageId) return message.ts === exactMessageId;
|
|
178
|
-
return message.ts !== opts.threadId;
|
|
179
|
-
}),
|
|
180
|
-
hasMore: exactMessageId ? false : Boolean(result.has_more)
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
const result = await client.conversations.history({
|
|
184
|
-
channel: channelId,
|
|
185
|
-
limit: readLimit,
|
|
186
|
-
...exactBounds
|
|
187
|
-
});
|
|
188
|
-
return {
|
|
189
|
-
messages: (result.messages ?? []).filter((message) => !exactMessageId || message.ts === exactMessageId),
|
|
190
|
-
hasMore: exactMessageId ? false : Boolean(result.has_more)
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
async function getSlackMemberInfo(userId, opts = {}) {
|
|
194
|
-
return await (await getClient(opts)).users.info({ user: userId });
|
|
195
|
-
}
|
|
196
|
-
async function listSlackEmojis(opts = {}) {
|
|
197
|
-
return await (await getClient(opts)).emoji.list();
|
|
198
|
-
}
|
|
199
|
-
async function pinSlackMessage(channelId, messageId, opts = {}) {
|
|
200
|
-
await (await getClient(opts, "write")).pins.add({
|
|
201
|
-
channel: channelId,
|
|
202
|
-
timestamp: messageId
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
async function unpinSlackMessage(channelId, messageId, opts = {}) {
|
|
206
|
-
await (await getClient(opts, "write")).pins.remove({
|
|
207
|
-
channel: channelId,
|
|
208
|
-
timestamp: messageId
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
async function listSlackPins(channelId, opts = {}) {
|
|
212
|
-
return (await (await getClient(opts)).pins.list({ channel: channelId })).items ?? [];
|
|
213
|
-
}
|
|
214
|
-
function normalizeSlackScopeValue(value) {
|
|
215
|
-
const trimmed = value?.trim();
|
|
216
|
-
return trimmed ? trimmed : void 0;
|
|
217
|
-
}
|
|
218
|
-
function collectSlackDirectShareChannelIds(file) {
|
|
219
|
-
const ids = /* @__PURE__ */ new Set();
|
|
220
|
-
for (const group of [
|
|
221
|
-
file.channels,
|
|
222
|
-
file.groups,
|
|
223
|
-
file.ims
|
|
224
|
-
]) {
|
|
225
|
-
if (!Array.isArray(group)) continue;
|
|
226
|
-
for (const entry of group) {
|
|
227
|
-
if (typeof entry !== "string") continue;
|
|
228
|
-
const normalized = normalizeSlackScopeValue(entry);
|
|
229
|
-
if (normalized) ids.add(normalized);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
return ids;
|
|
233
|
-
}
|
|
234
|
-
function collectSlackShareMaps(file) {
|
|
235
|
-
if (!file.shares || typeof file.shares !== "object" || Array.isArray(file.shares)) return [];
|
|
236
|
-
const shares = file.shares;
|
|
237
|
-
return [shares.public, shares.private].filter((value) => Boolean(value) && typeof value === "object" && !Array.isArray(value));
|
|
238
|
-
}
|
|
239
|
-
function collectSlackSharedChannelIds(file) {
|
|
240
|
-
const ids = /* @__PURE__ */ new Set();
|
|
241
|
-
for (const shareMap of collectSlackShareMaps(file)) for (const channelId of Object.keys(shareMap)) {
|
|
242
|
-
const normalized = normalizeSlackScopeValue(channelId);
|
|
243
|
-
if (normalized) ids.add(normalized);
|
|
244
|
-
}
|
|
245
|
-
return ids;
|
|
246
|
-
}
|
|
247
|
-
function collectSlackThreadShares(file, channelId) {
|
|
248
|
-
const matches = [];
|
|
249
|
-
for (const shareMap of collectSlackShareMaps(file)) {
|
|
250
|
-
const rawEntries = shareMap[channelId];
|
|
251
|
-
if (!Array.isArray(rawEntries)) continue;
|
|
252
|
-
for (const rawEntry of rawEntries) {
|
|
253
|
-
if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) continue;
|
|
254
|
-
const entry = rawEntry;
|
|
255
|
-
const ts = typeof entry.ts === "string" ? normalizeSlackScopeValue(entry.ts) : void 0;
|
|
256
|
-
const threadTs = typeof entry.thread_ts === "string" ? normalizeSlackScopeValue(entry.thread_ts) : void 0;
|
|
257
|
-
matches.push({
|
|
258
|
-
channelId,
|
|
259
|
-
ts,
|
|
260
|
-
threadTs
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
return matches;
|
|
265
|
-
}
|
|
266
|
-
function hasSlackScopeMismatch(params) {
|
|
267
|
-
const channelId = normalizeSlackScopeValue(params.channelId);
|
|
268
|
-
if (!channelId) return false;
|
|
269
|
-
const threadId = normalizeSlackScopeValue(params.threadId);
|
|
270
|
-
const directIds = collectSlackDirectShareChannelIds(params.file);
|
|
271
|
-
const sharedIds = collectSlackSharedChannelIds(params.file);
|
|
272
|
-
const hasChannelEvidence = directIds.size > 0 || sharedIds.size > 0;
|
|
273
|
-
const inChannel = directIds.has(channelId) || sharedIds.has(channelId);
|
|
274
|
-
if (hasChannelEvidence && !inChannel) return true;
|
|
275
|
-
if (!threadId) return false;
|
|
276
|
-
const threadShares = collectSlackThreadShares(params.file, channelId);
|
|
277
|
-
if (threadShares.length === 0) return false;
|
|
278
|
-
const threadEvidence = threadShares.filter((entry) => entry.threadTs || entry.ts);
|
|
279
|
-
if (threadEvidence.length === 0) return false;
|
|
280
|
-
return !threadEvidence.some((entry) => entry.threadTs === threadId || entry.ts === threadId);
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Downloads a Slack file by ID and saves it to the local media store.
|
|
284
|
-
* Fetches a fresh download URL via files.info to avoid using stale private URLs.
|
|
285
|
-
* Returns null when the file cannot be found or downloaded.
|
|
286
|
-
*/
|
|
287
|
-
async function downloadSlackFile(fileId, opts) {
|
|
288
|
-
const token = resolveToken(opts.token, opts.accountId, opts.cfg);
|
|
289
|
-
const file = (await (await getClient(opts)).files.info({ file: fileId })).file;
|
|
290
|
-
if (!file?.url_private_download && !file?.url_private) return null;
|
|
291
|
-
if (hasSlackScopeMismatch({
|
|
292
|
-
file,
|
|
293
|
-
channelId: opts.channelId,
|
|
294
|
-
threadId: opts.threadId
|
|
295
|
-
})) return null;
|
|
296
|
-
return (await resolveSlackMedia({
|
|
297
|
-
files: [{
|
|
298
|
-
id: file.id,
|
|
299
|
-
name: file.name,
|
|
300
|
-
mimetype: file.mimetype,
|
|
301
|
-
url_private: file.url_private,
|
|
302
|
-
url_private_download: file.url_private_download
|
|
303
|
-
}],
|
|
304
|
-
token,
|
|
305
|
-
maxBytes: opts.maxBytes
|
|
306
|
-
}))?.[0] ?? null;
|
|
307
|
-
}
|
|
308
|
-
//#endregion
|
|
309
|
-
export { listSlackEmojis as a, pinSlackMessage as c, removeOwnSlackReactions as d, removeSlackReaction as f, buildSlackEditTextPayload as h, getSlackMemberInfo as i, reactSlackMessage as l, unpinSlackMessage as m, downloadSlackFile as n, listSlackPins as o, sendSlackMessage as p, editSlackMessage as r, listSlackReactions as s, deleteSlackMessage as t, readSlackMessages as u };
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { a as resolveSlackAccount, o as resolveSlackAccountAllowFrom } from "./accounts-yk5K3wQU.js";
|
|
2
|
-
import { i as normalizeSlackApproverId } from "./exec-approvals-BLn4Zx7V.js";
|
|
3
|
-
import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
4
|
-
//#region extensions/slack/src/approval-auth.ts
|
|
5
|
-
function getSlackApprovalApprovers(params) {
|
|
6
|
-
const account = resolveSlackAccount(params).config;
|
|
7
|
-
return resolveApprovalApprovers({
|
|
8
|
-
allowFrom: resolveSlackAccountAllowFrom(params),
|
|
9
|
-
defaultTo: account.defaultTo,
|
|
10
|
-
normalizeApprover: normalizeSlackApproverId,
|
|
11
|
-
normalizeDefaultTo: normalizeSlackApproverId
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
function isSlackApprovalAuthorizedSender(params) {
|
|
15
|
-
const senderId = params.senderId ? normalizeSlackApproverId(params.senderId) : void 0;
|
|
16
|
-
if (!senderId) return false;
|
|
17
|
-
return getSlackApprovalApprovers(params).includes(senderId);
|
|
18
|
-
}
|
|
19
|
-
createResolvedApproverActionAuthAdapter({
|
|
20
|
-
channelLabel: "Slack",
|
|
21
|
-
resolveApprovers: ({ cfg, accountId }) => getSlackApprovalApprovers({
|
|
22
|
-
cfg,
|
|
23
|
-
accountId
|
|
24
|
-
}),
|
|
25
|
-
normalizeSenderId: (value) => normalizeSlackApproverId(value)
|
|
26
|
-
});
|
|
27
|
-
//#endregion
|
|
28
|
-
export { isSlackApprovalAuthorizedSender as t };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
//#region extensions/slack/src/blocks-input.ts
|
|
2
|
-
const SLACK_MAX_BLOCKS = 50;
|
|
3
|
-
function parseBlocksJson(raw) {
|
|
4
|
-
try {
|
|
5
|
-
return JSON.parse(raw);
|
|
6
|
-
} catch {
|
|
7
|
-
throw new Error("blocks must be valid JSON");
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
function assertBlocksArray(raw) {
|
|
11
|
-
if (!Array.isArray(raw)) throw new Error("blocks must be an array");
|
|
12
|
-
if (raw.length === 0) throw new Error("blocks must contain at least one block");
|
|
13
|
-
if (raw.length > 50) throw new Error(`blocks cannot exceed 50 items`);
|
|
14
|
-
for (const block of raw) {
|
|
15
|
-
if (!block || typeof block !== "object" || Array.isArray(block)) throw new Error("each block must be an object");
|
|
16
|
-
const type = block.type;
|
|
17
|
-
if (typeof type !== "string" || type.trim().length === 0) throw new Error("each block must include a non-empty string type");
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function validateSlackBlocksArray(raw) {
|
|
21
|
-
assertBlocksArray(raw);
|
|
22
|
-
return raw;
|
|
23
|
-
}
|
|
24
|
-
function parseSlackBlocksInput(raw) {
|
|
25
|
-
if (raw == null) return;
|
|
26
|
-
return validateSlackBlocksArray(typeof raw === "string" ? parseBlocksJson(raw) : raw);
|
|
27
|
-
}
|
|
28
|
-
//#endregion
|
|
29
|
-
export { parseSlackBlocksInput as n, validateSlackBlocksArray as r, SLACK_MAX_BLOCKS as t };
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import "./target-parsing-CQmv-iSm.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
|
-
//#region extensions/slack/src/channel-api.ts
|
|
5
|
-
const SLACK_CHANNEL_META = {
|
|
6
|
-
id: "slack",
|
|
7
|
-
label: "Slack",
|
|
8
|
-
selectionLabel: "Slack",
|
|
9
|
-
docsPath: "/channels/slack",
|
|
10
|
-
docsLabel: "slack",
|
|
11
|
-
blurb: "supports bot + app tokens, channels, threads, and interactive replies.",
|
|
12
|
-
systemImage: "number.square",
|
|
13
|
-
markdownCapable: true
|
|
14
|
-
};
|
|
15
|
-
function getChatChannelMeta(id) {
|
|
16
|
-
if (id !== SLACK_CHANNEL_META.id) throw new Error(`Unsupported Slack channel meta lookup: ${id}`);
|
|
17
|
-
return SLACK_CHANNEL_META;
|
|
18
|
-
}
|
|
19
|
-
//#endregion
|
|
20
|
-
export { resolveConfiguredFromRequiredCredentialStatuses as a, projectCredentialSnapshotFields as i, PAIRING_APPROVED_MESSAGE as n, getChatChannelMeta as r, DEFAULT_ACCOUNT_ID$1 as t };
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { a as resolveSlackAccount } from "./accounts-yk5K3wQU.js";
|
|
2
|
-
import { normalizeStringifiedOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
-
import { doesApprovalRequestMatchChannelAccount } from "openclaw/plugin-sdk/approval-native-runtime";
|
|
4
|
-
import { resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
|
|
5
|
-
import { createChannelExecApprovalProfile, isChannelExecApprovalTargetRecipient } from "openclaw/plugin-sdk/approval-client-runtime";
|
|
6
|
-
//#region extensions/slack/src/exec-approvals.ts
|
|
7
|
-
function normalizeSlackApproverId(value) {
|
|
8
|
-
const trimmed = normalizeStringifiedOptionalString(value);
|
|
9
|
-
if (!trimmed) return;
|
|
10
|
-
const prefixed = trimmed.match(/^(?:slack|user):([A-Z0-9]+)$/i);
|
|
11
|
-
if (prefixed?.[1]) return prefixed[1];
|
|
12
|
-
const mention = trimmed.match(/^<@([A-Z0-9]+)>$/i);
|
|
13
|
-
if (mention?.[1]) return mention[1];
|
|
14
|
-
return /^[UW][A-Z0-9]+$/i.test(trimmed) ? trimmed : void 0;
|
|
15
|
-
}
|
|
16
|
-
function resolveSlackOwnerApprovers(cfg) {
|
|
17
|
-
const ownerAllowFrom = cfg.commands?.ownerAllowFrom;
|
|
18
|
-
if (!Array.isArray(ownerAllowFrom) || ownerAllowFrom.length === 0) return [];
|
|
19
|
-
return resolveApprovalApprovers({
|
|
20
|
-
explicit: ownerAllowFrom,
|
|
21
|
-
normalizeApprover: normalizeSlackApproverId
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
function getSlackExecApprovalApprovers(params) {
|
|
25
|
-
const account = resolveSlackAccount(params).config;
|
|
26
|
-
return resolveApprovalApprovers({
|
|
27
|
-
explicit: account.execApprovals?.approvers ?? resolveSlackOwnerApprovers(params.cfg),
|
|
28
|
-
normalizeApprover: normalizeSlackApproverId
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
function isSlackExecApprovalTargetRecipient(params) {
|
|
32
|
-
return isChannelExecApprovalTargetRecipient({
|
|
33
|
-
...params,
|
|
34
|
-
channel: "slack",
|
|
35
|
-
normalizeSenderId: normalizeSlackApproverId,
|
|
36
|
-
matchTarget: ({ target, normalizedSenderId }) => normalizeSlackApproverId(target.to) === normalizedSenderId
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
const slackExecApprovalProfile = createChannelExecApprovalProfile({
|
|
40
|
-
resolveConfig: (params) => resolveSlackAccount(params).config.execApprovals,
|
|
41
|
-
resolveApprovers: getSlackExecApprovalApprovers,
|
|
42
|
-
normalizeSenderId: normalizeSlackApproverId,
|
|
43
|
-
isTargetRecipient: isSlackExecApprovalTargetRecipient,
|
|
44
|
-
matchesRequestAccount: (params) => doesApprovalRequestMatchChannelAccount({
|
|
45
|
-
cfg: params.cfg,
|
|
46
|
-
request: params.request,
|
|
47
|
-
channel: "slack",
|
|
48
|
-
accountId: params.accountId
|
|
49
|
-
})
|
|
50
|
-
});
|
|
51
|
-
const isSlackExecApprovalClientEnabled = slackExecApprovalProfile.isClientEnabled;
|
|
52
|
-
slackExecApprovalProfile.isApprover;
|
|
53
|
-
const isSlackExecApprovalAuthorizedSender = slackExecApprovalProfile.isAuthorizedSender;
|
|
54
|
-
const resolveSlackExecApprovalTarget = slackExecApprovalProfile.resolveTarget;
|
|
55
|
-
const shouldHandleSlackExecApprovalRequest = slackExecApprovalProfile.shouldHandleRequest;
|
|
56
|
-
const shouldSuppressLocalSlackExecApprovalPrompt = slackExecApprovalProfile.shouldSuppressLocalPrompt;
|
|
57
|
-
//#endregion
|
|
58
|
-
export { resolveSlackExecApprovalTarget as a, normalizeSlackApproverId as i, isSlackExecApprovalAuthorizedSender as n, shouldHandleSlackExecApprovalRequest as o, isSlackExecApprovalClientEnabled as r, shouldSuppressLocalSlackExecApprovalPrompt as s, getSlackExecApprovalApprovers as t };
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { i as resolveDefaultSlackAccountId, r as mergeSlackAccountConfig } from "./accounts-yk5K3wQU.js";
|
|
2
|
-
import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
|
|
3
|
-
import { normalizeHyphenSlug } from "openclaw/plugin-sdk/string-normalization-runtime";
|
|
4
|
-
import { resolveToolsBySender } from "openclaw/plugin-sdk/channel-policy";
|
|
5
|
-
//#region extensions/slack/src/group-policy.ts
|
|
6
|
-
function resolveSlackChannelPolicyEntry(params) {
|
|
7
|
-
const accountId = normalizeAccountId(params.accountId ?? resolveDefaultSlackAccountId(params.cfg));
|
|
8
|
-
const channelMap = mergeSlackAccountConfig(params.cfg, accountId).channels ?? {};
|
|
9
|
-
if (Object.keys(channelMap).length === 0) return;
|
|
10
|
-
const channelId = params.groupId?.trim();
|
|
11
|
-
const channelName = params.groupChannel?.replace(/^#/, "");
|
|
12
|
-
const normalizedName = normalizeHyphenSlug(channelName);
|
|
13
|
-
const candidates = [
|
|
14
|
-
channelId ?? "",
|
|
15
|
-
channelName ? `#${channelName}` : "",
|
|
16
|
-
channelName ?? "",
|
|
17
|
-
normalizedName
|
|
18
|
-
].filter(Boolean);
|
|
19
|
-
for (const candidate of candidates) if (candidate && channelMap[candidate]) return channelMap[candidate];
|
|
20
|
-
return channelMap["*"];
|
|
21
|
-
}
|
|
22
|
-
function resolveSenderToolsEntry(entry, params) {
|
|
23
|
-
if (!entry) return;
|
|
24
|
-
return resolveToolsBySender({
|
|
25
|
-
toolsBySender: entry.toolsBySender,
|
|
26
|
-
senderId: params.senderId,
|
|
27
|
-
senderName: params.senderName,
|
|
28
|
-
senderUsername: params.senderUsername,
|
|
29
|
-
senderE164: params.senderE164
|
|
30
|
-
}) ?? entry.tools;
|
|
31
|
-
}
|
|
32
|
-
function resolveSlackGroupRequireMention(params) {
|
|
33
|
-
const resolved = resolveSlackChannelPolicyEntry(params);
|
|
34
|
-
if (typeof resolved?.requireMention === "boolean") return resolved.requireMention;
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
function resolveSlackGroupToolPolicy(params) {
|
|
38
|
-
return resolveSenderToolsEntry(resolveSlackChannelPolicyEntry(params), params);
|
|
39
|
-
}
|
|
40
|
-
//#endregion
|
|
41
|
-
export { resolveSlackGroupToolPolicy as n, resolveSlackGroupRequireMention as t };
|
package/dist/mrkdwn-18IzcEAY.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
//#region extensions/slack/src/monitor/mrkdwn.ts
|
|
2
|
-
function escapeSlackMrkdwn(value) {
|
|
3
|
-
return value.replaceAll("\\", "\\\\").replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replace(/([*_`~])/g, "\\$1");
|
|
4
|
-
}
|
|
5
|
-
//#endregion
|
|
6
|
-
export { escapeSlackMrkdwn as t };
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { t as buildSlackInteractiveBlocks } from "./blocks-render-BdLueE_v.js";
|
|
2
|
-
import { n as parseSlackBlocksInput } from "./blocks-input-BJZ8vv03.js";
|
|
3
|
-
//#region extensions/slack/src/reply-blocks.ts
|
|
4
|
-
function resolveSlackReplyBlocks(payload) {
|
|
5
|
-
const slackData = payload.channelData?.slack;
|
|
6
|
-
const interactiveBlocks = buildSlackInteractiveBlocks(payload.interactive);
|
|
7
|
-
let channelBlocks = [];
|
|
8
|
-
if (slackData && typeof slackData === "object" && !Array.isArray(slackData)) channelBlocks = parseSlackBlocksInput(slackData.blocks) ?? [];
|
|
9
|
-
const blocks = [...channelBlocks, ...interactiveBlocks];
|
|
10
|
-
if (blocks.length > 50) throw new Error(`Slack blocks cannot exceed 50 items after interactive render`);
|
|
11
|
-
return blocks.length > 0 ? blocks : void 0;
|
|
12
|
-
}
|
|
13
|
-
//#endregion
|
|
14
|
-
export { resolveSlackReplyBlocks as t };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
|
-
//#region extensions/slack/src/truncate.ts
|
|
3
|
-
function truncateSlackText(value, max) {
|
|
4
|
-
const trimmed = value.trim();
|
|
5
|
-
if (trimmed.length <= max) return trimmed;
|
|
6
|
-
if (max <= 1) return trimmed.slice(0, max);
|
|
7
|
-
return `${trimmed.slice(0, max - 1)}…`;
|
|
8
|
-
}
|
|
9
|
-
//#endregion
|
|
10
|
-
//#region extensions/slack/src/limits.ts
|
|
11
|
-
const SLACK_TEXT_LIMIT = 8e3;
|
|
12
|
-
//#endregion
|
|
13
|
-
//#region extensions/slack/src/thread-ts.ts
|
|
14
|
-
const SLACK_THREAD_TS_PATTERN = /^\d+\.\d+$/;
|
|
15
|
-
function normalizeSlackThreadTsCandidate(value) {
|
|
16
|
-
if (typeof value !== "string") return;
|
|
17
|
-
const normalized = normalizeOptionalString(value);
|
|
18
|
-
return normalized && SLACK_THREAD_TS_PATTERN.test(normalized) ? normalized : void 0;
|
|
19
|
-
}
|
|
20
|
-
function resolveSlackThreadTsValue(params) {
|
|
21
|
-
return normalizeSlackThreadTsCandidate(params.replyToId) ?? normalizeSlackThreadTsCandidate(params.threadId);
|
|
22
|
-
}
|
|
23
|
-
//#endregion
|
|
24
|
-
export { truncateSlackText as i, resolveSlackThreadTsValue as n, SLACK_TEXT_LIMIT as r, normalizeSlackThreadTsCandidate as t };
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|