@openclaw/slack 2026.7.1 → 2026.7.2-beta.1
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-p6M2ULpv.js} +205 -29
- package/dist/action-runtime.runtime-DQstDkHG.js +2 -0
- package/dist/{actions-DMpDmKEA.js → actions-DkTcWmpT.js} +87 -138
- package/dist/{actions.runtime-C103_BPW.js → actions.runtime-BSxpwgUc.js} +1 -1
- package/dist/api.js +14 -13
- package/dist/{approval-handler.runtime-CIUbOt5T.js → approval-handler.runtime-UGbnz9OC.js} +3 -3
- package/dist/{channel-BjlsaGHn.js → channel-B0_j6C6z.js} +116 -140
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/channel-type-BpeTezY4.js +109 -0
- package/dist/{channel.setup-Dq6syTNU.js → channel.setup-BQFut21T.js} +2 -2
- package/dist/{client-DGxwSL7f.js → client-D2F6m8CP.js} +38 -2
- package/dist/config-api-Df9a1B8C.js +3 -0
- package/dist/{config-schema-BzqzFW__.js → config-schema-DYI01PV2.js} +20 -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-DX7yFsM-.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-C-b2ZnSl.js +2332 -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-BN_uuvrQ.js} +3 -3
- package/dist/outbound-adapter-ECl0go7d.js +228 -0
- package/dist/{pipeline.runtime-rpVpay59.js → pipeline.runtime-f0eJJoJL.js} +492 -178
- package/dist/{policy-Dj-puVPb.js → policy-f8b0edSi.js} +1 -1
- package/dist/preflight-audio.runtime-D5Bgags0.js +3 -0
- package/dist/{probe-CuwRDE5j.js → probe-CfALk0l4.js} +2 -2
- package/dist/{provider-C1-DFSpw.js → provider-Ds-y-imP.js} +658 -192
- package/dist/{relay-source-D2jv1iGg.js → relay-source-B-6LFUdz.js} +6 -17
- package/dist/replies-BMvf3ihj.js +420 -0
- package/dist/{resolve-channels-CstkChBE.js → resolve-channels-DOMgNCWb.js} +17 -6
- package/dist/{resolve-users-C3NP2c-Q.js → resolve-users-aL6-Ssee.js} +11 -6
- package/dist/{runtime-BOk7xkOl.js → runtime-CauEvswP.js} +1 -1
- package/dist/{runtime-api-CEmqYxR-.js → runtime-api-CVb6CQjX.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-Dw8wbU0j.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-NEfJ0GvM.js} +662 -325
- package/dist/{send.runtime-GPRa63l1.js → send.runtime-BkKpitPu.js} +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-Dv2fIJNB.js → setup-surface-BN2WeG5c.js} +3 -3
- package/dist/{shared-CosfcFri.js → shared-BLnB9R1T.js} +7 -5
- package/dist/{slash-dispatch.runtime-CcMbbT3_.js → slash-dispatch.runtime-C0Otuf_T.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 +16 -0
- package/package.json +6 -4
- 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/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
|
@@ -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 };
|
package/dist/replies-DpF38e1y.js
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
import { a as SLACK_TEXT_LIMIT, t as resolveSlackReplyBlocks } from "./reply-blocks-BGQ6zSqM.js";
|
|
2
|
-
import { r as sendMessageSlack } from "./send-DKDXoeoV.js";
|
|
3
|
-
import { t as markdownToSlackMrkdwnChunks } from "./format-YCNoNkM2.js";
|
|
4
|
-
import "./provider-C1-DFSpw.js";
|
|
5
|
-
import { createReplyReferencePlanner } from "openclaw/plugin-sdk/reply-reference";
|
|
6
|
-
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
7
|
-
import { SILENT_REPLY_TOKEN, chunkMarkdownTextWithMode, isSilentReplyText } from "openclaw/plugin-sdk/reply-chunking";
|
|
8
|
-
import { deliverTextOrMediaReply, getReplyPayloadTtsSupplement, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
|
|
9
|
-
import { getGlobalHookRunner } from "openclaw/plugin-sdk/plugin-runtime";
|
|
10
|
-
import { buildCanonicalSentMessageHookContext, createInternalHookEvent, fireAndForgetHook, toInternalMessageSentContext, toPluginMessageContext, toPluginMessageSentEvent, triggerInternalHook } from "openclaw/plugin-sdk/hook-runtime";
|
|
11
|
-
//#region extensions/slack/src/message-sent-hook.ts
|
|
12
|
-
/**
|
|
13
|
-
* Slack-side emission of the `message_sent` plugin hook.
|
|
14
|
-
*
|
|
15
|
-
* Mirrors the Telegram pattern in `extensions/telegram/src/bot/delivery.replies.ts`
|
|
16
|
-
* (`buildTelegramSentHookContext`, `emitMessageSentHooks`, `emitTelegramMessageSentHooks`).
|
|
17
|
-
*
|
|
18
|
-
* Without this, plugins observing `message_sent` see Telegram outbound but not
|
|
19
|
-
* Slack outbound — even though `docs/plugins/hooks.md` documents the hook as
|
|
20
|
-
* firing for all successful outbound deliveries.
|
|
21
|
-
*/
|
|
22
|
-
function buildSlackSentHookContext(params) {
|
|
23
|
-
return buildCanonicalSentMessageHookContext({
|
|
24
|
-
to: params.to,
|
|
25
|
-
content: params.content,
|
|
26
|
-
success: params.success,
|
|
27
|
-
error: params.error,
|
|
28
|
-
channelId: "slack",
|
|
29
|
-
accountId: params.accountId ?? void 0,
|
|
30
|
-
conversationId: params.to,
|
|
31
|
-
sessionKey: params.sessionKeyForInternalHooks,
|
|
32
|
-
messageId: params.messageId,
|
|
33
|
-
isGroup: params.isGroup,
|
|
34
|
-
groupId: params.groupId
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
function emitInternalSlackMessageSentHook(params) {
|
|
38
|
-
if (!params.sessionKeyForInternalHooks) return;
|
|
39
|
-
const canonical = buildSlackSentHookContext(params);
|
|
40
|
-
fireAndForgetHook(triggerInternalHook(createInternalHookEvent("message", "sent", params.sessionKeyForInternalHooks, toInternalMessageSentContext(canonical))), "slack: message:sent internal hook failed");
|
|
41
|
-
}
|
|
42
|
-
function emitMessageSentHooks(params) {
|
|
43
|
-
if (!params.enabled && !params.sessionKeyForInternalHooks) return;
|
|
44
|
-
const canonical = buildSlackSentHookContext(params);
|
|
45
|
-
if (params.enabled) fireAndForgetHook(Promise.resolve(params.hookRunner.runMessageSent(toPluginMessageSentEvent(canonical), toPluginMessageContext(canonical))), "slack: message_sent plugin hook failed");
|
|
46
|
-
emitInternalSlackMessageSentHook(params);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Fire both the plugin `message_sent` hook and (if a session key is supplied)
|
|
50
|
-
* the internal `message:sent` hook for a successful or failed Slack outbound
|
|
51
|
-
* delivery.
|
|
52
|
-
*
|
|
53
|
-
* Safe to call after every `chat.postMessage` — the function self-gates on
|
|
54
|
-
* `hookRunner.hasHooks("message_sent")` so plugins not observing the hook
|
|
55
|
-
* incur no cost.
|
|
56
|
-
*/
|
|
57
|
-
function emitSlackMessageSentHooks(params) {
|
|
58
|
-
const hookRunner = getGlobalHookRunner();
|
|
59
|
-
emitMessageSentHooks({
|
|
60
|
-
...params,
|
|
61
|
-
hookRunner,
|
|
62
|
-
enabled: hookRunner?.hasHooks("message_sent") ?? false
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
//#endregion
|
|
66
|
-
//#region extensions/slack/src/monitor/replies.ts
|
|
67
|
-
function readSlackReplyBlocks(payload) {
|
|
68
|
-
return resolveSlackReplyBlocks(payload);
|
|
69
|
-
}
|
|
70
|
-
function resolveSlackMediaHookSpokenText(payload) {
|
|
71
|
-
return (getReplyPayloadTtsSupplement(payload)?.spokenText ?? payload.spokenText)?.trim() || void 0;
|
|
72
|
-
}
|
|
73
|
-
function resolveDeliveredSlackReplyThreadTs(params) {
|
|
74
|
-
return (params.replyToMode === "off" ? void 0 : params.payloadReplyToId) ?? params.replyThreadTs;
|
|
75
|
-
}
|
|
76
|
-
async function deliverReplies(params) {
|
|
77
|
-
let latestResult;
|
|
78
|
-
for (const payload of params.replies) {
|
|
79
|
-
if (payload.isReasoning === true) continue;
|
|
80
|
-
const threadTs = resolveDeliveredSlackReplyThreadTs({
|
|
81
|
-
replyToMode: params.replyToMode,
|
|
82
|
-
payloadReplyToId: payload.replyToId,
|
|
83
|
-
replyThreadTs: params.replyThreadTs
|
|
84
|
-
});
|
|
85
|
-
const reply = resolveSendableOutboundReplyParts(payload);
|
|
86
|
-
const slackBlocks = readSlackReplyBlocks(payload);
|
|
87
|
-
if (!reply.hasContent && !slackBlocks?.length) continue;
|
|
88
|
-
const emitSent = (content, result) => {
|
|
89
|
-
if (params.deferMessageSentHooks) return;
|
|
90
|
-
emitSlackMessageSentHooks({
|
|
91
|
-
sessionKeyForInternalHooks: params.sessionKeyForInternalHooks,
|
|
92
|
-
to: params.messageSentHookTarget ?? params.target,
|
|
93
|
-
accountId: params.accountId,
|
|
94
|
-
content,
|
|
95
|
-
success: true,
|
|
96
|
-
messageId: result?.messageId,
|
|
97
|
-
isGroup: params.isGroup,
|
|
98
|
-
groupId: params.groupId
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
const emitFailed = (content, error) => {
|
|
102
|
-
if (params.deferMessageSentHooks) return;
|
|
103
|
-
emitSlackMessageSentHooks({
|
|
104
|
-
sessionKeyForInternalHooks: params.sessionKeyForInternalHooks,
|
|
105
|
-
to: params.messageSentHookTarget ?? params.target,
|
|
106
|
-
accountId: params.accountId,
|
|
107
|
-
content,
|
|
108
|
-
success: false,
|
|
109
|
-
error: formatErrorMessage(error),
|
|
110
|
-
isGroup: params.isGroup,
|
|
111
|
-
groupId: params.groupId
|
|
112
|
-
});
|
|
113
|
-
};
|
|
114
|
-
if (!reply.hasMedia && slackBlocks?.length) {
|
|
115
|
-
const trimmed = reply.trimmedText;
|
|
116
|
-
if (!trimmed && !slackBlocks?.length) continue;
|
|
117
|
-
if (trimmed && isSilentReplyText(trimmed, SILENT_REPLY_TOKEN)) continue;
|
|
118
|
-
let result;
|
|
119
|
-
try {
|
|
120
|
-
result = await sendMessageSlack(params.target, trimmed, {
|
|
121
|
-
cfg: params.cfg,
|
|
122
|
-
token: params.token,
|
|
123
|
-
threadTs,
|
|
124
|
-
accountId: params.accountId,
|
|
125
|
-
...slackBlocks?.length ? { blocks: slackBlocks } : {},
|
|
126
|
-
...params.identity ? { identity: params.identity } : {},
|
|
127
|
-
...params.metadata ? { metadata: params.metadata } : {}
|
|
128
|
-
});
|
|
129
|
-
} catch (error) {
|
|
130
|
-
emitFailed(trimmed, error);
|
|
131
|
-
throw error;
|
|
132
|
-
}
|
|
133
|
-
emitSent(trimmed, result);
|
|
134
|
-
latestResult = result;
|
|
135
|
-
params.runtime.log?.(`delivered reply to ${params.target}`);
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
const spokenText = resolveSlackMediaHookSpokenText(payload);
|
|
139
|
-
const mediaHookContent = reply.hasText ? reply.text : spokenText || reply.text;
|
|
140
|
-
const hookContent = reply.hasMedia ? mediaHookContent : reply.trimmedText;
|
|
141
|
-
let lastResult;
|
|
142
|
-
let delivered;
|
|
143
|
-
try {
|
|
144
|
-
delivered = await deliverTextOrMediaReply({
|
|
145
|
-
payload,
|
|
146
|
-
text: reply.text,
|
|
147
|
-
chunkText: !reply.hasMedia ? (value) => {
|
|
148
|
-
const trimmed = value.trim();
|
|
149
|
-
if (!trimmed || isSilentReplyText(trimmed, SILENT_REPLY_TOKEN)) return [];
|
|
150
|
-
return [trimmed];
|
|
151
|
-
} : void 0,
|
|
152
|
-
sendText: async (trimmed) => {
|
|
153
|
-
lastResult = await sendMessageSlack(params.target, trimmed, {
|
|
154
|
-
cfg: params.cfg,
|
|
155
|
-
token: params.token,
|
|
156
|
-
threadTs,
|
|
157
|
-
accountId: params.accountId,
|
|
158
|
-
...params.identity ? { identity: params.identity } : {},
|
|
159
|
-
...params.metadata ? { metadata: params.metadata } : {}
|
|
160
|
-
});
|
|
161
|
-
},
|
|
162
|
-
sendMedia: async ({ mediaUrl, caption }) => {
|
|
163
|
-
lastResult = await sendMessageSlack(params.target, caption ?? "", {
|
|
164
|
-
cfg: params.cfg,
|
|
165
|
-
token: params.token,
|
|
166
|
-
mediaUrl,
|
|
167
|
-
threadTs,
|
|
168
|
-
accountId: params.accountId,
|
|
169
|
-
...params.identity ? { identity: params.identity } : {},
|
|
170
|
-
...params.metadata ? { metadata: params.metadata } : {}
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
} catch (error) {
|
|
175
|
-
emitFailed(hookContent, error);
|
|
176
|
-
throw error;
|
|
177
|
-
}
|
|
178
|
-
if (delivered !== "empty") {
|
|
179
|
-
emitSent(hookContent, reply.hasMedia ? void 0 : lastResult);
|
|
180
|
-
latestResult = lastResult;
|
|
181
|
-
params.runtime.log?.(`delivered reply to ${params.target}`);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return latestResult;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Compute effective threadTs for a Slack reply based on replyToMode.
|
|
188
|
-
* - "off": stay in thread if already in one, otherwise main channel
|
|
189
|
-
* - "first": first reply goes to thread, subsequent replies to main channel
|
|
190
|
-
* - "all": all replies go to thread
|
|
191
|
-
*/
|
|
192
|
-
function resolveSlackThreadTs(params) {
|
|
193
|
-
return createSlackReplyReferencePlanner({
|
|
194
|
-
replyToMode: params.replyToMode,
|
|
195
|
-
incomingThreadTs: params.incomingThreadTs,
|
|
196
|
-
messageTs: params.messageTs,
|
|
197
|
-
hasReplied: params.hasReplied,
|
|
198
|
-
isThreadReply: params.isThreadReply
|
|
199
|
-
}).use();
|
|
200
|
-
}
|
|
201
|
-
function createSlackReplyReferencePlanner(params) {
|
|
202
|
-
return createReplyReferencePlanner({
|
|
203
|
-
replyToMode: params.isThreadReply ?? Boolean(params.incomingThreadTs && params.incomingThreadTs !== params.messageTs) ? "all" : params.replyToMode,
|
|
204
|
-
existingId: params.incomingThreadTs,
|
|
205
|
-
startId: params.messageTs,
|
|
206
|
-
hasReplied: params.hasReplied
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
function createSlackReplyDeliveryPlan(params) {
|
|
210
|
-
const replyReference = createSlackReplyReferencePlanner({
|
|
211
|
-
replyToMode: params.replyToMode,
|
|
212
|
-
incomingThreadTs: params.incomingThreadTs,
|
|
213
|
-
messageTs: params.messageTs,
|
|
214
|
-
hasReplied: params.hasRepliedRef.value,
|
|
215
|
-
isThreadReply: params.isThreadReply
|
|
216
|
-
});
|
|
217
|
-
return {
|
|
218
|
-
peekThreadTs: () => replyReference.peek(),
|
|
219
|
-
nextThreadTs: () => replyReference.use(),
|
|
220
|
-
markSent: () => {
|
|
221
|
-
replyReference.markSent();
|
|
222
|
-
params.hasRepliedRef.value = replyReference.hasReplied();
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
async function deliverSlackSlashReplies(params) {
|
|
227
|
-
const deliveries = [];
|
|
228
|
-
const chunkLimit = Math.min(params.textLimit, SLACK_TEXT_LIMIT);
|
|
229
|
-
for (const payload of params.replies) {
|
|
230
|
-
if (payload.isReasoning === true) continue;
|
|
231
|
-
const reply = resolveSendableOutboundReplyParts(payload);
|
|
232
|
-
const slackBlocks = readSlackReplyBlocks(payload);
|
|
233
|
-
const text = reply.hasText && !isSilentReplyText(reply.trimmedText, SILENT_REPLY_TOKEN) ? reply.trimmedText : void 0;
|
|
234
|
-
if (slackBlocks?.length && !reply.hasMedia) {
|
|
235
|
-
deliveries.push({
|
|
236
|
-
hookContent: text ?? "",
|
|
237
|
-
messages: [{
|
|
238
|
-
text: text ?? "",
|
|
239
|
-
blocks: slackBlocks
|
|
240
|
-
}]
|
|
241
|
-
});
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
const combined = [text ?? "", ...reply.mediaUrls].filter(Boolean).join("\n");
|
|
245
|
-
if (!combined) continue;
|
|
246
|
-
const chunkMode = params.chunkMode ?? "length";
|
|
247
|
-
const chunks = (chunkMode === "newline" ? chunkMarkdownTextWithMode(combined, chunkLimit, chunkMode) : [combined]).flatMap((markdown) => markdownToSlackMrkdwnChunks(markdown, chunkLimit, { tableMode: params.tableMode }));
|
|
248
|
-
if (!chunks.length && combined) chunks.push(combined);
|
|
249
|
-
deliveries.push({
|
|
250
|
-
hookContent: text ?? resolveSlackMediaHookSpokenText(payload) ?? combined,
|
|
251
|
-
messages: chunks.map((chunk) => ({ text: chunk }))
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
if (deliveries.length === 0) return;
|
|
255
|
-
const responseType = params.ephemeral ? "ephemeral" : "in_channel";
|
|
256
|
-
for (const delivery of deliveries) {
|
|
257
|
-
try {
|
|
258
|
-
for (const message of delivery.messages) await params.respond({
|
|
259
|
-
...message,
|
|
260
|
-
response_type: responseType
|
|
261
|
-
});
|
|
262
|
-
} catch (error) {
|
|
263
|
-
if (params.messageSentHookTarget) emitSlackMessageSentHooks({
|
|
264
|
-
sessionKeyForInternalHooks: params.sessionKeyForInternalHooks,
|
|
265
|
-
to: params.messageSentHookTarget,
|
|
266
|
-
accountId: params.accountId,
|
|
267
|
-
content: delivery.hookContent,
|
|
268
|
-
success: false,
|
|
269
|
-
error: formatErrorMessage(error),
|
|
270
|
-
isGroup: params.isGroup,
|
|
271
|
-
groupId: params.groupId
|
|
272
|
-
});
|
|
273
|
-
throw error;
|
|
274
|
-
}
|
|
275
|
-
if (params.messageSentHookTarget) emitSlackMessageSentHooks({
|
|
276
|
-
sessionKeyForInternalHooks: params.sessionKeyForInternalHooks,
|
|
277
|
-
to: params.messageSentHookTarget,
|
|
278
|
-
accountId: params.accountId,
|
|
279
|
-
content: delivery.hookContent,
|
|
280
|
-
success: true,
|
|
281
|
-
isGroup: params.isGroup,
|
|
282
|
-
groupId: params.groupId
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
//#endregion
|
|
287
|
-
export { resolveDeliveredSlackReplyThreadTs as a, readSlackReplyBlocks as i, deliverReplies as n, resolveSlackThreadTs as o, deliverSlackSlashReplies as r, emitSlackMessageSentHooks as s, createSlackReplyDeliveryPlan as t };
|