@openclaw/slack 2026.8.1-beta.2 → 2026.8.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/account-configured-sUohAxZr.js +33 -0
- package/dist/account-inspect-CN2hBsim.js +87 -0
- package/dist/account-inspect-api.js +1 -1
- package/dist/{accounts-CK4AVI2_.js → accounts-Dm_H77gH.js} +12 -11
- package/dist/{accounts.runtime-Cb7QwWBz.js → accounts.runtime-DRuEK6mL.js} +1 -1
- package/dist/{action-runtime-BkGe7ny_.js → action-runtime-044ldvNL.js} +80 -79
- package/dist/action-runtime.runtime-BL3KzX13.js +2 -0
- package/dist/{actions-BTDXwwE3.js → actions-BI7JkfVm.js} +273 -263
- package/dist/api.js +14 -14
- package/dist/{approval-handler.runtime-CJaNzAq2.js → approval-handler.runtime-DYv0UIZS.js} +53 -174
- package/dist/{channel-D_tovcUL.js → channel-1vIJOzPx.js} +134 -160
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-type-B9MSdoGN.js → channel-type-DlFSKeIZ.js} +3 -7
- package/dist/{channel.setup-Bch9dYmA.js → channel.setup-ofDi3_Pu.js} +34 -49
- package/dist/{config-schema-xto5jFIx.js → config-schema-BVIMyiDN.js} +42 -19
- package/dist/configured-state.js +34 -0
- package/dist/conversation-binding-route-DFVLUdYF.js +115 -0
- package/dist/{directory-config-CNBz8lJa.js → directory-config-DqfQ42OV.js} +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-CFKUtW9E.js → directory-live-BPaNHjmP.js} +2 -2
- package/dist/{group-policy-c4RP9bjc.js → group-policy-BdwszjYn.js} +625 -773
- package/dist/{message-tool-api-BykQB4AU.js → message-tool-api-CJ0kjcg5.js} +23 -5
- package/dist/message-tool-api.js +1 -1
- package/dist/{monitor-1nF1NtqT.js → monitor-Dq5Cmrvp.js} +3 -3
- package/dist/{outbound-adapter-S81tsswN.js → outbound-adapter-DYaI8ThX.js} +101 -66
- package/dist/{pipeline.runtime-BvYsM5JO.js → pipeline.runtime-Bd22U0ga.js} +494 -474
- package/dist/{policy-TapwbeaT.js → policy-CtQVbde1.js} +2 -1
- package/dist/{probe-HoEg_WxB.js → probe-0usmAb0i.js} +209 -22
- package/dist/{provider-CDNvBXUi.js → provider-CN_8hFv2.js} +296 -178
- package/dist/{relay-source-C9leF11u.js → relay-source-BNGpsdwV.js} +1 -1
- package/dist/{replies-CeOfv82I.js → replies-BSiRQOJ1.js} +48 -27
- package/dist/{resolve-channels-CNPrxaXY.js → resolve-channels-Czheznc8.js} +1 -1
- package/dist/{resolve-users-Dzomuwnr.js → resolve-users-BAOlNimr.js} +1 -1
- package/dist/runtime-api.js +11 -11
- package/dist/{scopes-cYXKkrRD.js → scopes-COSlmhnH.js} +1 -1
- package/dist/security-contract-api.js +1 -1
- package/dist/{send-Nor0iBwY.js → send-DS9ICrBI.js} +88 -100
- package/dist/send-results-eeOu_HYm.js +23 -0
- package/dist/{send.runtime-BmgNe6S9.js → send.runtime-D_Bb6IuH.js} +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-CbX1-Knh.js → setup-surface-BGnd2pSe.js} +6 -6
- package/dist/{shared-zdT5AMp-.js → shared-D5B-5hBg.js} +35 -9
- package/dist/{slash-dispatch.runtime-Bnr9GR1S.js → slash-dispatch.runtime-CilDmI0c.js} +2 -2
- package/node_modules/@slack/bolt/node_modules/@types/node/README.md +1 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/child_process.d.ts +0 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/crypto.d.ts +6 -6
- package/node_modules/@slack/bolt/node_modules/@types/node/dns/promises.d.ts +5 -5
- package/node_modules/@slack/bolt/node_modules/@types/node/dns.d.ts +5 -5
- package/node_modules/@slack/bolt/node_modules/@types/node/fs.d.ts +7 -0
- package/node_modules/@slack/bolt/node_modules/@types/node/http.d.ts +30 -0
- package/node_modules/@slack/bolt/node_modules/@types/node/http2.d.ts +4 -4
- package/node_modules/@slack/bolt/node_modules/@types/node/os.d.ts +30 -30
- package/node_modules/@slack/bolt/node_modules/@types/node/package.json +2 -2
- package/node_modules/@slack/bolt/node_modules/@types/node/perf_hooks.d.ts +2 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/process.d.ts +42 -43
- package/node_modules/@slack/bolt/node_modules/@types/node/quic.d.ts +1049 -84
- package/node_modules/@slack/bolt/node_modules/@types/node/sqlite.d.ts +14 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/stream/iter.d.ts +3 -2
- package/node_modules/@slack/bolt/node_modules/@types/node/test.d.ts +61 -0
- package/node_modules/@slack/bolt/node_modules/@types/node/v8.d.ts +20 -23
- package/node_modules/@slack/bolt/node_modules/body-parser/node_modules/content-type/README.md +2 -0
- package/node_modules/@slack/bolt/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +20 -0
- package/node_modules/@slack/bolt/node_modules/body-parser/node_modules/content-type/dist/index.js +20 -14
- package/node_modules/@slack/bolt/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -1
- package/node_modules/@slack/bolt/node_modules/body-parser/node_modules/content-type/package.json +1 -1
- package/node_modules/@slack/bolt/node_modules/type-is/node_modules/content-type/README.md +2 -0
- package/node_modules/@slack/bolt/node_modules/type-is/node_modules/content-type/dist/index.d.ts +20 -0
- package/node_modules/@slack/bolt/node_modules/type-is/node_modules/content-type/dist/index.js +20 -14
- package/node_modules/@slack/bolt/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -1
- package/node_modules/@slack/bolt/node_modules/type-is/node_modules/content-type/package.json +1 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/README.md +1 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/child_process.d.ts +0 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/crypto.d.ts +6 -6
- package/node_modules/@slack/socket-mode/node_modules/@types/node/dns/promises.d.ts +5 -5
- package/node_modules/@slack/socket-mode/node_modules/@types/node/dns.d.ts +5 -5
- package/node_modules/@slack/socket-mode/node_modules/@types/node/fs.d.ts +7 -0
- package/node_modules/@slack/socket-mode/node_modules/@types/node/http.d.ts +30 -0
- package/node_modules/@slack/socket-mode/node_modules/@types/node/http2.d.ts +4 -4
- package/node_modules/@slack/socket-mode/node_modules/@types/node/os.d.ts +30 -30
- package/node_modules/@slack/socket-mode/node_modules/@types/node/package.json +2 -2
- package/node_modules/@slack/socket-mode/node_modules/@types/node/perf_hooks.d.ts +2 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/process.d.ts +42 -43
- package/node_modules/@slack/socket-mode/node_modules/@types/node/quic.d.ts +1049 -84
- package/node_modules/@slack/socket-mode/node_modules/@types/node/sqlite.d.ts +14 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/stream/iter.d.ts +3 -2
- package/node_modules/@slack/socket-mode/node_modules/@types/node/test.d.ts +61 -0
- package/node_modules/@slack/socket-mode/node_modules/@types/node/v8.d.ts +20 -23
- package/node_modules/@slack/web-api/node_modules/@types/node/README.md +1 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/child_process.d.ts +0 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/crypto.d.ts +6 -6
- package/node_modules/@slack/web-api/node_modules/@types/node/dns/promises.d.ts +5 -5
- package/node_modules/@slack/web-api/node_modules/@types/node/dns.d.ts +5 -5
- package/node_modules/@slack/web-api/node_modules/@types/node/fs.d.ts +7 -0
- package/node_modules/@slack/web-api/node_modules/@types/node/http.d.ts +30 -0
- package/node_modules/@slack/web-api/node_modules/@types/node/http2.d.ts +4 -4
- package/node_modules/@slack/web-api/node_modules/@types/node/os.d.ts +30 -30
- package/node_modules/@slack/web-api/node_modules/@types/node/package.json +2 -2
- package/node_modules/@slack/web-api/node_modules/@types/node/perf_hooks.d.ts +2 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/process.d.ts +42 -43
- package/node_modules/@slack/web-api/node_modules/@types/node/quic.d.ts +1049 -84
- package/node_modules/@slack/web-api/node_modules/@types/node/sqlite.d.ts +14 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/stream/iter.d.ts +3 -2
- package/node_modules/@slack/web-api/node_modules/@types/node/test.d.ts +61 -0
- package/node_modules/@slack/web-api/node_modules/@types/node/v8.d.ts +20 -23
- package/node_modules/typebox/build/format/date.d.mts +1 -1
- package/node_modules/typebox/build/format/date.mjs +1 -1
- package/node_modules/typebox/build/format/date_time.d.mts +2 -2
- package/node_modules/typebox/build/format/date_time.mjs +3 -3
- package/node_modules/typebox/build/format/email.d.mts +1 -1
- package/node_modules/typebox/build/format/email.mjs +2 -2
- package/node_modules/typebox/build/format/hostname.mjs +2 -10
- package/node_modules/typebox/build/format/idn_email.d.mts +1 -1
- package/node_modules/typebox/build/format/idn_email.mjs +3 -3
- package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idn_hostname.mjs +3 -11
- package/node_modules/typebox/build/format/idna/format/bidi.d.mts +3 -0
- package/node_modules/typebox/build/format/idna/format/bidi.mjs +98 -0
- package/node_modules/typebox/build/format/idna/format/puny.d.mts +3 -0
- package/node_modules/typebox/build/format/idna/format/puny.mjs +144 -0
- package/node_modules/typebox/build/format/idna/hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/hostname.mjs +16 -0
- package/node_modules/typebox/build/format/idna/idn-hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/idn-hostname.mjs +23 -0
- package/node_modules/typebox/build/format/idna/index.d.mts +2 -0
- package/node_modules/typebox/build/format/idna/index.mjs +2 -0
- package/node_modules/typebox/build/format/idna/label/ascii.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/ascii.mjs +9 -0
- package/node_modules/typebox/build/format/idna/label/puny.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/puny.mjs +28 -0
- package/node_modules/typebox/build/format/idna/label/unicode.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/unicode.mjs +106 -0
- package/node_modules/typebox/build/format/idna/pattern/pattern.d.mts +30 -0
- package/node_modules/typebox/build/format/idna/pattern/pattern.mjs +70 -0
- package/node_modules/typebox/build/format/ipv4.d.mts +0 -1
- package/node_modules/typebox/build/format/ipv4.mjs +2 -32
- package/node_modules/typebox/build/format/ipv6.mjs +2 -61
- package/node_modules/typebox/build/format/iri.d.mts +2 -2
- package/node_modules/typebox/build/format/iri.mjs +26 -8
- package/node_modules/typebox/build/format/iri_reference.d.mts +2 -2
- package/node_modules/typebox/build/format/iri_reference.mjs +9 -55
- package/node_modules/typebox/build/format/regex.d.mts +1 -2
- package/node_modules/typebox/build/format/regex.mjs +2 -6
- package/node_modules/typebox/build/format/time.d.mts +2 -2
- package/node_modules/typebox/build/format/time.mjs +19 -14
- package/node_modules/typebox/build/format/uri.d.mts +1 -1
- package/node_modules/typebox/build/format/uri.mjs +3 -130
- package/node_modules/typebox/build/format/uri_reference.d.mts +1 -1
- package/node_modules/typebox/build/format/uri_reference.mjs +2 -3
- package/node_modules/typebox/build/format/uri_template.d.mts +2 -3
- package/node_modules/typebox/build/format/uri_template.mjs +4 -5
- package/node_modules/typebox/build/format/url.d.mts +3 -3
- package/node_modules/typebox/build/format/url.mjs +4 -5
- package/node_modules/typebox/build/guard/emit.d.mts +3 -1
- package/node_modules/typebox/build/guard/emit.mjs +12 -5
- package/node_modules/typebox/build/guard/guard.d.mts +8 -2
- package/node_modules/typebox/build/guard/guard.mjs +25 -4
- package/node_modules/typebox/build/guard/string.d.mts +2 -2
- package/node_modules/typebox/build/guard/string.mjs +7 -7
- package/node_modules/typebox/build/schema/engine/_context.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -2
- package/node_modules/typebox/build/schema/engine/_regexp.d.mts +2 -0
- package/node_modules/typebox/build/schema/engine/_regexp.mjs +4 -0
- package/node_modules/typebox/build/schema/engine/_stack.mjs +12 -13
- package/node_modules/typebox/build/schema/engine/additionalItems.mjs +17 -7
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +4 -3
- package/node_modules/typebox/build/schema/engine/contains.mjs +18 -6
- package/node_modules/typebox/build/schema/engine/enum.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/items.mjs +26 -6
- package/node_modules/typebox/build/schema/engine/maxContains.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/minContains.mjs +14 -4
- package/node_modules/typebox/build/schema/engine/not.mjs +4 -2
- package/node_modules/typebox/build/schema/engine/oneOf.mjs +7 -6
- package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +4 -3
- package/node_modules/typebox/build/schema/engine/ref.mjs +1 -7
- package/node_modules/typebox/build/schema/engine/schema.mjs +13 -4
- package/node_modules/typebox/build/schema/engine/type.mjs +1 -1
- package/node_modules/typebox/build/schema/resolve/resolve.d.mts +4 -1
- package/node_modules/typebox/build/schema/resolve/resolve.mjs +202 -1
- package/node_modules/typebox/build/schema/static/propertyNames.d.mts +5 -0
- package/node_modules/typebox/build/schema/static/propertyNames.mjs +3 -0
- package/node_modules/typebox/build/schema/static/schema.d.mts +3 -0
- package/node_modules/typebox/build/schema/types/index.d.mts +0 -2
- package/node_modules/typebox/build/schema/types/index.mjs +0 -2
- package/node_modules/typebox/build/system/memory/clone.mjs +14 -11
- package/node_modules/typebox/build/system/memory/discard.mjs +6 -5
- package/node_modules/typebox/build/system/settings/settings.d.mts +9 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +2 -0
- package/node_modules/typebox/build/type/engine/call/distribute_arguments.d.mts +6 -1
- package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +16 -3
- package/node_modules/typebox/build/type/engine/call/instantiate.mjs +34 -4
- package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +5 -5
- package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +20 -26
- package/node_modules/typebox/build/type/engine/evaluate/compare.d.mts +6 -10
- package/node_modules/typebox/build/type/engine/evaluate/compare.mjs +9 -13
- package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +7 -4
- package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +12 -19
- package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +4 -20
- package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +8 -20
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +4 -4
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +11 -8
- package/node_modules/typebox/build/type/engine/evaluate/flatten.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/evaluate/flatten.mjs +3 -4
- package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +17 -2
- package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +26 -6
- package/node_modules/typebox/build/type/engine/exclude/operation.mjs +3 -4
- package/node_modules/typebox/build/type/engine/extract/operation.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/extract/operation.mjs +3 -4
- package/node_modules/typebox/build/type/engine/priority/priority.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/priority/priority.mjs +3 -4
- package/node_modules/typebox/build/type/script/mapping.d.mts +32 -29
- package/node_modules/typebox/build/type/script/mapping.mjs +18 -25
- package/node_modules/typebox/build/type/script/parser.d.mts +19 -25
- package/node_modules/typebox/build/type/script/parser.mjs +27 -23
- package/node_modules/typebox/build/value/errors/errors.d.mts +2 -2
- package/node_modules/typebox/build/value/errors/errors.mjs +1 -1
- package/node_modules/typebox/package.json +27 -27
- package/node_modules/typebox/readme.md +79 -82
- package/node_modules/ws/lib/permessage-deflate.js +3 -1
- package/node_modules/ws/package.json +1 -1
- package/openclaw.plugin.json +57 -7
- package/package.json +9 -9
- package/dist/account-configured-BwfXBo_F.js +0 -14
- package/dist/account-inspect-Drw2gAiN.js +0 -89
- package/dist/account-reply-mode-DrUXogvO.js +0 -14
- package/dist/action-runtime.runtime-D9I6uc0Q.js +0 -2
- package/dist/actions.runtime-DLFyUkvg.js +0 -2
- package/dist/block-text-YtiNkqmx.js +0 -79
- package/dist/runtime-api-Cj9nxBNv.js +0 -10
- package/node_modules/p-map/index.d.ts +0 -155
- package/node_modules/p-map/index.js +0 -285
- package/node_modules/p-map/license +0 -9
- package/node_modules/p-map/package.json +0 -57
- package/node_modules/p-map/readme.md +0 -190
- package/node_modules/typebox/build/format/_idna.d.mts +0 -2
- package/node_modules/typebox/build/format/_idna.mjs +0 -246
- package/node_modules/typebox/build/format/_puny.d.mts +0 -1
- package/node_modules/typebox/build/format/_puny.mjs +0 -77
- package/node_modules/typebox/build/schema/resolve/ref.d.mts +0 -3
- package/node_modules/typebox/build/schema/resolve/ref.mjs +0 -146
- package/node_modules/typebox/build/schema/types/contentEncoding.d.mts +0 -9
- package/node_modules/typebox/build/schema/types/contentEncoding.mjs +0 -13
- package/node_modules/typebox/build/schema/types/contentMediaType.d.mts +0 -9
- package/node_modules/typebox/build/schema/types/contentMediaType.mjs +0 -13
- package/dist/{security-audit-DR097212.js → security-audit-B_yKr7MW.js} +1 -1
|
@@ -1,23 +1,46 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { a as resolveSlackAccount, f as resolveSlackBotToken } from "./accounts-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { a as resolveSlackAccount, f as resolveSlackBotToken, i as resolveDefaultSlackAccountId } from "./accounts-Dm_H77gH.js";
|
|
3
|
+
import { n as formatSlackTarget } from "./target-parsing-BnMD2ZqZ.js";
|
|
4
|
+
import { At as SLACK_PRIVATE_ACTION_DELIVERY_RESULT, D as renderSlackBlockFallbackText, E as buildSlackCompleteBlocksFallbackText, I as countSlackTextUtf8Bytes, Q as normalizeSlackOutboundText, R as truncateSlackTextByUtf8Bytes, T as buildSlackBlocksFallbackText, _ as appendSlackNativeDataPlainTextFallback, b as hasSlackNativeDataBlock, c as assertSlackDetachedTargetAllowed, et as escapeSlackMrkdwn, g as appendSlackNativeDataFallbackText, k as SLACK_EDIT_TEXT_MAX_BYTES, st as validateSlackBlocksArray, w as stripSlackNativeDataBlocks, x as isSlackInvalidBlocksError } from "./group-policy-BdwszjYn.js";
|
|
5
|
+
import { S as getSlackWriteClient, h as createSlackLookupClient } from "./probe-0usmAb0i.js";
|
|
6
|
+
import { m as buildSlackNativeDataDeliveryPlan, r as sendMessageSlack } from "./send-DS9ICrBI.js";
|
|
7
7
|
import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
|
|
8
8
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
9
|
-
import { logVerbose, logVerbose as logVerbose$1 } from "openclaw/plugin-sdk/runtime-env";
|
|
10
|
-
import {
|
|
9
|
+
import { createSubsystemLogger, logVerbose, logVerbose as logVerbose$1 } from "openclaw/plugin-sdk/runtime-env";
|
|
10
|
+
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
11
|
+
import { redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
|
|
11
12
|
import { z } from "zod";
|
|
12
13
|
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
13
14
|
import fs from "node:fs/promises";
|
|
15
|
+
import { runTasksWithConcurrency } from "openclaw/plugin-sdk/concurrency-runtime";
|
|
14
16
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
15
17
|
import { normalizeHostname } from "openclaw/plugin-sdk/host-runtime";
|
|
16
18
|
import { resolveRequestUrl } from "openclaw/plugin-sdk/request-url";
|
|
17
|
-
import pMap, { pMapSkip } from "p-map";
|
|
18
19
|
import { fetchWithRuntimeDispatcher } from "openclaw/plugin-sdk/runtime-fetch";
|
|
19
20
|
import { saveRemoteMedia } from "openclaw/plugin-sdk/media-runtime";
|
|
20
|
-
|
|
21
|
+
//#region extensions/slack/src/conversation-open.ts
|
|
22
|
+
function parseSlackConversationOpenInput(userIds, teamId) {
|
|
23
|
+
const users = z.array(z.string().trim().regex(/^[UW][A-Z0-9]+$/)).min(1).max(8).parse(userIds);
|
|
24
|
+
if (new Set(users).size !== users.length) throw new Error("Slack conversation-open requires distinct userIds.");
|
|
25
|
+
return {
|
|
26
|
+
users,
|
|
27
|
+
teamId: teamId === void 0 ? void 0 : z.string().trim().regex(/^T[A-Z0-9]+$/i).parse(teamId)
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async function openSlackConversationWithClient(client, input) {
|
|
31
|
+
const channelId = (await client.conversations.open({ users: input.users.join(",") })).channel?.id?.trim();
|
|
32
|
+
if (!channelId || !/^[CDG][A-Z0-9]+$/i.test(channelId)) throw new Error("Slack conversations.open did not return a valid conversation ID.");
|
|
33
|
+
return {
|
|
34
|
+
channelId,
|
|
35
|
+
target: formatSlackTarget({
|
|
36
|
+
teamId: input.teamId,
|
|
37
|
+
kind: "channel",
|
|
38
|
+
id: channelId,
|
|
39
|
+
explicitKind: true
|
|
40
|
+
})
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
21
44
|
//#region extensions/slack/src/edit-text.ts
|
|
22
45
|
function buildSlackEditTextPayload(content, blocks) {
|
|
23
46
|
const trimmedContent = content.trim();
|
|
@@ -31,6 +54,85 @@ function buildSlackEditTextPayload(content, blocks) {
|
|
|
31
54
|
return " ";
|
|
32
55
|
}
|
|
33
56
|
//#endregion
|
|
57
|
+
//#region extensions/slack/src/monitor/block-text.ts
|
|
58
|
+
function readSlackBlockType(block) {
|
|
59
|
+
return block && typeof block === "object" && !Array.isArray(block) ? block.type : void 0;
|
|
60
|
+
}
|
|
61
|
+
function hasSlackTableBlock(blocks) {
|
|
62
|
+
return blocks?.some((block) => readSlackBlockType(block) === "table") ?? false;
|
|
63
|
+
}
|
|
64
|
+
function hasSlackMessageTableBlock(message) {
|
|
65
|
+
return hasSlackTableBlock(message.blocks) || message.attachments?.some((attachment) => !isSlackUnfurlAttachment(attachment) && hasSlackTableBlock(attachment.blocks)) === true;
|
|
66
|
+
}
|
|
67
|
+
function isSlackUnfurlAttachment(attachment) {
|
|
68
|
+
return attachment.is_msg_unfurl === true || attachment.is_app_unfurl === true || typeof attachment.app_unfurl_url === "string" && attachment.app_unfurl_url.trim().length > 0;
|
|
69
|
+
}
|
|
70
|
+
function resolveSlackBlocksText(blocks) {
|
|
71
|
+
if (!blocks?.length) return;
|
|
72
|
+
const parts = [];
|
|
73
|
+
let hasRichText = false;
|
|
74
|
+
let hasNativeData = false;
|
|
75
|
+
for (const block of blocks) {
|
|
76
|
+
const blockType = readSlackBlockType(block);
|
|
77
|
+
hasRichText ||= blockType === "rich_text";
|
|
78
|
+
hasNativeData ||= blockType === "data_visualization" || blockType === "data_table" || blockType === "table";
|
|
79
|
+
const text = renderSlackBlockFallbackText(block, {
|
|
80
|
+
nativeDataFormat: "plain",
|
|
81
|
+
nativeReferenceFormat: "plain"
|
|
82
|
+
});
|
|
83
|
+
if (text) parts.push(text);
|
|
84
|
+
}
|
|
85
|
+
return parts.length > 0 ? {
|
|
86
|
+
text: parts.join("\n"),
|
|
87
|
+
hasRichText,
|
|
88
|
+
hasNativeData
|
|
89
|
+
} : void 0;
|
|
90
|
+
}
|
|
91
|
+
function appendDistinctSlackText(base, addition) {
|
|
92
|
+
if (!base) return addition;
|
|
93
|
+
const comparableBase = `\n${base.replace(/\r\n?/g, "\n")}\n`;
|
|
94
|
+
const comparableAddition = `\n${addition.replace(/\r\n?/g, "\n")}\n`;
|
|
95
|
+
if (comparableBase.includes(comparableAddition)) return base;
|
|
96
|
+
return `${base}\n${addition}`;
|
|
97
|
+
}
|
|
98
|
+
function resolveSlackAttachmentTableTexts(attachments) {
|
|
99
|
+
const seen = /* @__PURE__ */ new Set();
|
|
100
|
+
const texts = [];
|
|
101
|
+
for (const attachment of attachments ?? []) {
|
|
102
|
+
if (isSlackUnfurlAttachment(attachment)) continue;
|
|
103
|
+
for (const block of attachment.blocks ?? []) {
|
|
104
|
+
if (readSlackBlockType(block) !== "table") continue;
|
|
105
|
+
const text = renderSlackBlockFallbackText(block, { nativeDataFormat: "plain" });
|
|
106
|
+
if (!text || seen.has(text)) continue;
|
|
107
|
+
seen.add(text);
|
|
108
|
+
texts.push(text);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return texts;
|
|
112
|
+
}
|
|
113
|
+
/** Resolve agent-visible Slack text while admitting only native tables from attachments. */
|
|
114
|
+
function resolveSlackMessageText(message, options = {}) {
|
|
115
|
+
let resolved = chooseSlackPrimaryText({
|
|
116
|
+
messageText: options.preserveMessageTextWhitespace ? typeof message.text === "string" && message.text.trim().length > 0 ? message.text : void 0 : normalizeOptionalString(message.text),
|
|
117
|
+
blocksText: resolveSlackBlocksText(message.blocks)
|
|
118
|
+
});
|
|
119
|
+
for (const tableText of resolveSlackAttachmentTableTexts(message.attachments)) resolved = appendDistinctSlackText(resolved, tableText);
|
|
120
|
+
return resolved;
|
|
121
|
+
}
|
|
122
|
+
function chooseSlackPrimaryText(params) {
|
|
123
|
+
const { messageText, blocksText } = params;
|
|
124
|
+
if (!blocksText) return messageText;
|
|
125
|
+
if (!messageText) return blocksText.text;
|
|
126
|
+
if (blocksText.hasNativeData) {
|
|
127
|
+
const comparableMessageText = messageText.replace(/\s+/g, " ").trim();
|
|
128
|
+
const comparableBlocksText = blocksText.text.replace(/\s+/g, " ").trim();
|
|
129
|
+
if (comparableMessageText.includes(comparableBlocksText)) return messageText;
|
|
130
|
+
return comparableBlocksText.startsWith(comparableMessageText) ? blocksText.text : `${messageText}\n${blocksText.text}`;
|
|
131
|
+
}
|
|
132
|
+
if (blocksText.hasRichText && blocksText.text.length > messageText.length) return blocksText.text;
|
|
133
|
+
return blocksText.text.length > messageText.length && blocksText.text.startsWith(messageText) ? blocksText.text : messageText;
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
34
136
|
//#region extensions/slack/src/file-reference.ts
|
|
35
137
|
function formatSlackFileReference(file) {
|
|
36
138
|
const name = normalizeOptionalString(file?.name) ?? "file";
|
|
@@ -49,164 +151,11 @@ function formatSlackFileReferenceList(files) {
|
|
|
49
151
|
return files.map((file) => formatSlackFileReference(file)).join(", ");
|
|
50
152
|
}
|
|
51
153
|
//#endregion
|
|
52
|
-
//#region extensions/slack/src/monitor/
|
|
53
|
-
const
|
|
54
|
-
const THREAD_STARTER_CACHE_TTL_MS = 360 * 6e4;
|
|
55
|
-
const THREAD_STARTER_CACHE_MAX = 2e3;
|
|
56
|
-
function evictThreadStarterCache() {
|
|
57
|
-
const now = asDateTimestampMs(Date.now());
|
|
58
|
-
if (now === void 0) {
|
|
59
|
-
THREAD_STARTER_CACHE.clear();
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
for (const [cacheKey, entry] of THREAD_STARTER_CACHE.entries()) if (asDateTimestampMs(entry.expiresAt) === void 0 || entry.expiresAt <= now) THREAD_STARTER_CACHE.delete(cacheKey);
|
|
63
|
-
pruneMapToMaxSize(THREAD_STARTER_CACHE, THREAD_STARTER_CACHE_MAX);
|
|
64
|
-
}
|
|
65
|
-
function formatSlackFilePlaceholder(files) {
|
|
66
|
-
return `[attached: ${formatSlackFileReferenceList(files)}]`;
|
|
67
|
-
}
|
|
68
|
-
function pushUniqueText(parts, value, options = {}) {
|
|
69
|
-
const text = options.preserveWhitespace ? typeof value === "string" && value.trim().length > 0 ? value : void 0 : normalizeOptionalString(value);
|
|
70
|
-
if (text && !parts.includes(text)) parts.push(text);
|
|
71
|
-
}
|
|
72
|
-
function resolveSlackBlocksFallbackText(blocks) {
|
|
73
|
-
return resolveSlackBlocksText(blocks)?.text;
|
|
74
|
-
}
|
|
75
|
-
function resolveSlackAttachmentFallbackText(attachments) {
|
|
76
|
-
if (!Array.isArray(attachments) || attachments.length === 0) return;
|
|
77
|
-
const parts = [];
|
|
78
|
-
for (const attachment of attachments) {
|
|
79
|
-
const excludeTableBlocks = isSlackUnfurlAttachment(attachment);
|
|
80
|
-
const fallbackBlocks = (blocks) => excludeTableBlocks ? blocks?.filter((block) => !hasSlackTableBlock([block])) : blocks;
|
|
81
|
-
pushUniqueText(parts, attachment.pretext);
|
|
82
|
-
pushUniqueText(parts, attachment.title);
|
|
83
|
-
pushUniqueText(parts, attachment.text);
|
|
84
|
-
if (!(hasSlackTableBlock(attachment.blocks) && normalizeOptionalString(attachment.fallback) === "[no preview available]")) pushUniqueText(parts, attachment.fallback);
|
|
85
|
-
for (const field of attachment.fields ?? []) {
|
|
86
|
-
pushUniqueText(parts, field.title);
|
|
87
|
-
pushUniqueText(parts, field.value);
|
|
88
|
-
}
|
|
89
|
-
pushUniqueText(parts, resolveSlackBlocksFallbackText(fallbackBlocks(attachment.blocks)), { preserveWhitespace: true });
|
|
90
|
-
pushUniqueText(parts, resolveSlackBlocksFallbackText(fallbackBlocks(attachment.message_blocks)), { preserveWhitespace: true });
|
|
91
|
-
}
|
|
92
|
-
return parts.length > 0 ? parts.join("\n") : void 0;
|
|
93
|
-
}
|
|
94
|
-
function resolveSlackMessageText(message) {
|
|
95
|
-
const messageText = normalizeOptionalString(message.text) ?? resolveSlackAttachmentFallbackText(message.attachments);
|
|
96
|
-
return resolveSlackMessageText$1({
|
|
97
|
-
...message,
|
|
98
|
-
text: messageText
|
|
99
|
-
}, { preserveMessageTextWhitespace: true });
|
|
100
|
-
}
|
|
101
|
-
async function resolveSlackThreadStarter(params) {
|
|
102
|
-
evictThreadStarterCache();
|
|
103
|
-
const cacheKey = JSON.stringify([
|
|
104
|
-
params.workspaceScope.accountId,
|
|
105
|
-
params.workspaceScope.teamId,
|
|
106
|
-
params.channelId,
|
|
107
|
-
params.threadTs
|
|
108
|
-
]);
|
|
109
|
-
const cached = THREAD_STARTER_CACHE.get(cacheKey);
|
|
110
|
-
if (cached) {
|
|
111
|
-
const now = asDateTimestampMs(Date.now());
|
|
112
|
-
if (now !== void 0 && cached.expiresAt > now) return cached.value;
|
|
113
|
-
THREAD_STARTER_CACHE.delete(cacheKey);
|
|
114
|
-
}
|
|
115
|
-
try {
|
|
116
|
-
const message = (await params.client.conversations.replies({
|
|
117
|
-
channel: params.channelId,
|
|
118
|
-
ts: params.threadTs,
|
|
119
|
-
limit: 1,
|
|
120
|
-
inclusive: true
|
|
121
|
-
}))?.messages?.[0];
|
|
122
|
-
const text = message ? resolveSlackMessageText(message) : void 0;
|
|
123
|
-
const files = message?.files?.length ? message.files : void 0;
|
|
124
|
-
if (!message || !text && !files) return null;
|
|
125
|
-
const starter = {
|
|
126
|
-
text: text || formatSlackFilePlaceholder(files),
|
|
127
|
-
userId: message.user,
|
|
128
|
-
botId: message.bot_id,
|
|
129
|
-
ts: message.ts,
|
|
130
|
-
files
|
|
131
|
-
};
|
|
132
|
-
const expiresAt = resolveExpiresAtMsFromDurationMs(THREAD_STARTER_CACHE_TTL_MS);
|
|
133
|
-
if (expiresAt !== void 0) {
|
|
134
|
-
if (THREAD_STARTER_CACHE.has(cacheKey)) THREAD_STARTER_CACHE.delete(cacheKey);
|
|
135
|
-
THREAD_STARTER_CACHE.set(cacheKey, {
|
|
136
|
-
value: starter,
|
|
137
|
-
expiresAt
|
|
138
|
-
});
|
|
139
|
-
evictThreadStarterCache();
|
|
140
|
-
}
|
|
141
|
-
return starter;
|
|
142
|
-
} catch (err) {
|
|
143
|
-
logVerbose$1(`slack thread starter fetch failed channel=${params.channelId} ts=${params.threadTs}: ${formatErrorMessage(err)}`);
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
function resetSlackThreadStarterCacheForTest() {
|
|
148
|
-
THREAD_STARTER_CACHE.clear();
|
|
149
|
-
}
|
|
150
|
-
const SLACK_THREAD_HISTORY_MAX_PAGES = 3;
|
|
151
|
-
/**
|
|
152
|
-
* Fetches the most recent messages in a Slack thread (excluding the current message).
|
|
153
|
-
* Used to populate thread context when a new thread session starts.
|
|
154
|
-
*
|
|
155
|
-
* Uses cursor pagination and keeps only the latest N retained messages when the full
|
|
156
|
-
* thread fits in the bounded fetch window.
|
|
157
|
-
*/
|
|
158
|
-
async function resolveSlackThreadHistory(params) {
|
|
159
|
-
const maxMessages = params.limit ?? 20;
|
|
160
|
-
if (!Number.isFinite(maxMessages) || maxMessages <= 0) return [];
|
|
161
|
-
const fetchLimit = 200;
|
|
162
|
-
const retained = [];
|
|
163
|
-
let cursor;
|
|
164
|
-
let pagesFetched = 0;
|
|
165
|
-
try {
|
|
166
|
-
do {
|
|
167
|
-
pagesFetched += 1;
|
|
168
|
-
const response = await params.client.conversations.replies({
|
|
169
|
-
channel: params.channelId,
|
|
170
|
-
ts: params.threadTs,
|
|
171
|
-
limit: fetchLimit,
|
|
172
|
-
inclusive: true,
|
|
173
|
-
...cursor ? { cursor } : {}
|
|
174
|
-
});
|
|
175
|
-
for (const msg of response.messages ?? []) {
|
|
176
|
-
if (!resolveSlackMessageText(msg) && !msg.files?.length) continue;
|
|
177
|
-
if (params.currentMessageTs && msg.ts === params.currentMessageTs) continue;
|
|
178
|
-
retained.push(msg);
|
|
179
|
-
}
|
|
180
|
-
if (retained.length > maxMessages) retained.splice(0, retained.length - maxMessages);
|
|
181
|
-
const next = response.response_metadata?.next_cursor;
|
|
182
|
-
cursor = typeof next === "string" && next.trim().length > 0 ? next.trim() : void 0;
|
|
183
|
-
} while (cursor && pagesFetched < SLACK_THREAD_HISTORY_MAX_PAGES);
|
|
184
|
-
if (cursor) {
|
|
185
|
-
logVerbose$1(`slack thread history capped channel=${params.channelId} ts=${params.threadTs} pages=${SLACK_THREAD_HISTORY_MAX_PAGES}`);
|
|
186
|
-
return [];
|
|
187
|
-
}
|
|
188
|
-
return retained.map((msg) => ({
|
|
189
|
-
text: resolveSlackMessageText(msg) ?? formatSlackFilePlaceholder(msg.files),
|
|
190
|
-
userId: msg.user,
|
|
191
|
-
botId: msg.bot_id,
|
|
192
|
-
ts: msg.ts,
|
|
193
|
-
files: msg.files
|
|
194
|
-
}));
|
|
195
|
-
} catch (err) {
|
|
196
|
-
logVerbose$1(`slack thread history fetch failed channel=${params.channelId} ts=${params.threadTs}: ${formatErrorMessage(err)}`);
|
|
197
|
-
return [];
|
|
198
|
-
}
|
|
199
|
-
}
|
|
154
|
+
//#region extensions/slack/src/monitor/media.runtime.ts
|
|
155
|
+
const slackMediaLog = createSubsystemLogger("gateway/channels/slack").child("media");
|
|
200
156
|
//#endregion
|
|
201
|
-
//#region extensions/slack/src/monitor/
|
|
202
|
-
|
|
203
|
-
SLACK_MEDIA_READ_IDLE_TIMEOUT_MS: () => SLACK_MEDIA_READ_IDLE_TIMEOUT_MS,
|
|
204
|
-
resetSlackThreadStarterCacheForTest: () => resetSlackThreadStarterCacheForTest,
|
|
205
|
-
resolveSlackAttachmentContent: () => resolveSlackAttachmentContent,
|
|
206
|
-
resolveSlackMedia: () => resolveSlackMedia,
|
|
207
|
-
resolveSlackThreadHistory: () => resolveSlackThreadHistory,
|
|
208
|
-
resolveSlackThreadStarter: () => resolveSlackThreadStarter
|
|
209
|
-
});
|
|
157
|
+
//#region extensions/slack/src/monitor/slack-client-kind.ts
|
|
158
|
+
/** Detects the isolated GovSlack API plane without consulting mutable config. */
|
|
210
159
|
function isGovSlackClient(client) {
|
|
211
160
|
if (!client?.slackApiUrl) return false;
|
|
212
161
|
try {
|
|
@@ -216,6 +165,13 @@ function isGovSlackClient(client) {
|
|
|
216
165
|
return false;
|
|
217
166
|
}
|
|
218
167
|
}
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region extensions/slack/src/monitor/media.ts
|
|
170
|
+
var media_exports = /* @__PURE__ */ __exportAll({
|
|
171
|
+
SLACK_MEDIA_READ_IDLE_TIMEOUT_MS: () => SLACK_MEDIA_READ_IDLE_TIMEOUT_MS,
|
|
172
|
+
resolveSlackAttachmentContent: () => resolveSlackAttachmentContent,
|
|
173
|
+
resolveSlackMedia: () => resolveSlackMedia
|
|
174
|
+
});
|
|
219
175
|
function isSlackHostname(hostname, govSlack) {
|
|
220
176
|
const normalized = normalizeHostname(hostname);
|
|
221
177
|
if (!normalized) return false;
|
|
@@ -345,10 +301,18 @@ async function looksLikeHtmlFile(filePath) {
|
|
|
345
301
|
}
|
|
346
302
|
const MAX_SLACK_MEDIA_CONCURRENCY = 3;
|
|
347
303
|
const MAX_SLACK_FORWARDED_ATTACHMENTS = 8;
|
|
304
|
+
const SLACK_MEDIA_LIMIT_REASON = `omitted: 8-file limit`;
|
|
305
|
+
function formatSlackMediaFailure(error) {
|
|
306
|
+
return redactToolPayloadText(formatErrorMessage(error)).replace(/\s+/g, " ").slice(0, 200);
|
|
307
|
+
}
|
|
348
308
|
async function fetchFreshSlackFileUrl(params) {
|
|
349
309
|
if (!params.file.id || !params.client) return null;
|
|
350
310
|
try {
|
|
351
311
|
const freshFile = (await params.client.files.info({ file: params.file.id })).file;
|
|
312
|
+
if (freshFile && params.isRefreshedFileAllowed?.(freshFile) === false) {
|
|
313
|
+
logVerbose$1(`slack: refreshed file metadata rejected for file id=${params.file.id}`);
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
352
316
|
const freshUrl = freshFile?.url_private_download ?? freshFile?.url_private;
|
|
353
317
|
if (freshUrl) {
|
|
354
318
|
logVerbose$1(`slack: refreshed file URL via files.info for file id=${params.file.id}`);
|
|
@@ -382,7 +346,7 @@ async function downloadSlackMediaFile(params) {
|
|
|
382
346
|
if (!(fileMime === "text/html" || fileName.endsWith(".html") || fileName.endsWith(".htm"))) {
|
|
383
347
|
if (normalizeOptionalLowercaseString(saved.contentType?.split(";")[0]) === "text/html" || await looksLikeHtmlFile(saved.path)) {
|
|
384
348
|
await fs.rm(saved.path, { force: true }).catch(() => void 0);
|
|
385
|
-
|
|
349
|
+
throw new Error("blocked: unexpected HTML content");
|
|
386
350
|
}
|
|
387
351
|
}
|
|
388
352
|
const effectiveMime = resolveSlackMediaMimetype(params.file, saved.contentType);
|
|
@@ -391,6 +355,7 @@ async function downloadSlackMediaFile(params) {
|
|
|
391
355
|
return {
|
|
392
356
|
path: saved.path,
|
|
393
357
|
...contentType ? { contentType } : {},
|
|
358
|
+
...label ? { fileName: label } : {},
|
|
394
359
|
placeholder: `[Slack file: ${formatSlackFileReference({
|
|
395
360
|
...params.file,
|
|
396
361
|
name: label
|
|
@@ -418,57 +383,81 @@ function resolveForwardedAttachmentImageUrl(attachment, govSlack) {
|
|
|
418
383
|
async function resolveSlackMedia(params) {
|
|
419
384
|
const govSlack = isGovSlackClient(params.client);
|
|
420
385
|
const files = params.files ?? [];
|
|
421
|
-
const
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
}).catch(() => null) ?? pMapSkip;
|
|
456
|
-
}, {
|
|
457
|
-
concurrency: MAX_SLACK_MEDIA_CONCURRENCY,
|
|
458
|
-
stopOnError: true
|
|
386
|
+
const limitedFiles = files.length > 8 ? files.slice(0, 8) : files;
|
|
387
|
+
for (const file of files.slice(8)) params.unavailableFiles?.set(file, SLACK_MEDIA_LIMIT_REASON);
|
|
388
|
+
const refreshFileUrl = (file) => fetchFreshSlackFileUrl({
|
|
389
|
+
file,
|
|
390
|
+
client: params.client,
|
|
391
|
+
isRefreshedFileAllowed: params.isRefreshedFileAllowed
|
|
392
|
+
});
|
|
393
|
+
const { results } = await runTasksWithConcurrency({
|
|
394
|
+
tasks: limitedFiles.map((file) => async () => {
|
|
395
|
+
const preloaded = params.preloadedMedia?.get(file);
|
|
396
|
+
if (preloaded) return preloaded;
|
|
397
|
+
const eventUrl = file.url_private_download ?? file.url_private;
|
|
398
|
+
let url = eventUrl ?? await refreshFileUrl(file);
|
|
399
|
+
let reason = "no private download URL";
|
|
400
|
+
for (let attempt = 0; url && attempt < 2; attempt += 1) {
|
|
401
|
+
try {
|
|
402
|
+
return await downloadSlackMediaFile({
|
|
403
|
+
...params,
|
|
404
|
+
file,
|
|
405
|
+
url,
|
|
406
|
+
govSlack
|
|
407
|
+
});
|
|
408
|
+
} catch (error) {
|
|
409
|
+
reason = formatSlackMediaFailure(error);
|
|
410
|
+
}
|
|
411
|
+
url = attempt === 0 && eventUrl ? await refreshFileUrl(file) : null;
|
|
412
|
+
}
|
|
413
|
+
params.unavailableFiles?.set(file, reason);
|
|
414
|
+
slackMediaLog.warn(`slack: file ${formatSlackFileReference(file)} unavailable (${reason})`);
|
|
415
|
+
return null;
|
|
416
|
+
}),
|
|
417
|
+
limit: MAX_SLACK_MEDIA_CONCURRENCY,
|
|
418
|
+
errorMode: "stop",
|
|
419
|
+
throwOnError: true
|
|
459
420
|
});
|
|
421
|
+
const resolved = results.filter((result) => result !== null);
|
|
460
422
|
return resolved.length > 0 ? resolved : null;
|
|
461
423
|
}
|
|
462
424
|
/** Extracts text and media from forwarded-message attachments. Returns null when empty. */
|
|
463
425
|
async function resolveSlackAttachmentContent(params) {
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
426
|
+
const forwardedAttachments = (params.attachments ?? []).filter((attachment) => isForwardedSlackAttachment(attachment)).slice(0, MAX_SLACK_FORWARDED_ATTACHMENTS);
|
|
427
|
+
const candidates = [...params.files ?? [], ...forwardedAttachments.flatMap((attachment) => attachment.files ?? [])];
|
|
428
|
+
if (forwardedAttachments.length === 0 && candidates.length === 0) return null;
|
|
429
|
+
const fileIds = /* @__PURE__ */ new Set();
|
|
430
|
+
const allFiles = candidates.filter((file) => {
|
|
431
|
+
const fileId = normalizeOptionalString(file.id);
|
|
432
|
+
if (!fileId) return true;
|
|
433
|
+
if (fileIds.has(fileId)) return false;
|
|
434
|
+
fileIds.add(fileId);
|
|
435
|
+
return true;
|
|
436
|
+
}).map((file, index) => {
|
|
437
|
+
if (index >= 8) return file;
|
|
438
|
+
const fileId = normalizeOptionalString(file.id);
|
|
439
|
+
const preloaded = fileId && candidates.find((candidate) => normalizeOptionalString(candidate.id) === fileId && params.preloadedMedia?.has(candidate));
|
|
440
|
+
if (preloaded) return preloaded;
|
|
441
|
+
if (!fileId || file.url_private_download || file.url_private) return file;
|
|
442
|
+
const downloadable = candidates.find((candidate) => normalizeOptionalString(candidate.id) === fileId && (candidate.url_private_download || candidate.url_private));
|
|
443
|
+
return downloadable ? Object.assign({}, file, downloadable) : file;
|
|
444
|
+
});
|
|
445
|
+
const pendingFiles = new Map(allFiles.slice(0, 8).map((file) => [normalizeOptionalString(file.id) ?? file, file]));
|
|
446
|
+
const unavailableFileReasons = /* @__PURE__ */ new Map();
|
|
447
|
+
const resolveFiles = (files) => resolveSlackMedia({
|
|
448
|
+
...params,
|
|
449
|
+
unavailableFiles: unavailableFileReasons,
|
|
450
|
+
files: files?.flatMap((file) => {
|
|
451
|
+
const key = normalizeOptionalString(file.id) ?? file;
|
|
452
|
+
const selected = pendingFiles.get(key);
|
|
453
|
+
pendingFiles.delete(key);
|
|
454
|
+
return selected ? [selected] : [];
|
|
455
|
+
})
|
|
456
|
+
});
|
|
457
|
+
const directMediaPromise = resolveFiles(params.files);
|
|
468
458
|
const textBlocks = [];
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
let unavailableImageCount = 0;
|
|
459
|
+
const attachmentMedia = [];
|
|
460
|
+
let unavailableMediaCount = 0;
|
|
472
461
|
const govSlack = isGovSlackClient(params.client);
|
|
473
462
|
for (const att of forwardedAttachments) {
|
|
474
463
|
const text = att.text?.trim() || att.fallback?.trim();
|
|
@@ -493,41 +482,60 @@ async function resolveSlackAttachmentContent(params) {
|
|
|
493
482
|
abortSignal: params.abortSignal
|
|
494
483
|
});
|
|
495
484
|
const label = saved.fileName ?? "forwarded image";
|
|
496
|
-
|
|
485
|
+
attachmentMedia.push({
|
|
497
486
|
path: saved.path,
|
|
498
487
|
contentType: saved.contentType,
|
|
488
|
+
...saved.fileName ? { fileName: saved.fileName } : {},
|
|
499
489
|
placeholder: `[Forwarded image: ${label}]`
|
|
500
490
|
});
|
|
501
|
-
} catch {
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
if (att.files && att.files.length > 0) {
|
|
505
|
-
const fileMedia = await resolveSlackMedia({
|
|
506
|
-
files: att.files,
|
|
507
|
-
client: params.client,
|
|
508
|
-
token: params.token,
|
|
509
|
-
maxBytes: params.maxBytes,
|
|
510
|
-
readIdleTimeoutMs: params.readIdleTimeoutMs,
|
|
511
|
-
totalTimeoutMs: params.totalTimeoutMs,
|
|
512
|
-
abortSignal: params.abortSignal
|
|
513
|
-
});
|
|
514
|
-
if (fileMedia) allMedia.push(...fileMedia);
|
|
491
|
+
} catch (error) {
|
|
492
|
+
unavailableMediaCount += 1;
|
|
493
|
+
slackMediaLog.warn(`slack: forwarded image unavailable (${formatSlackMediaFailure(error)})`);
|
|
515
494
|
}
|
|
495
|
+
attachmentMedia.push(...await resolveFiles(att.files) ?? []);
|
|
516
496
|
}
|
|
497
|
+
const allMedia = [...await directMediaPromise ?? [], ...attachmentMedia];
|
|
498
|
+
const unavailableFiles = allFiles.flatMap((file, index) => {
|
|
499
|
+
const reason = index >= 8 ? SLACK_MEDIA_LIMIT_REASON : unavailableFileReasons.get(file);
|
|
500
|
+
return reason ? [{
|
|
501
|
+
...file,
|
|
502
|
+
reason
|
|
503
|
+
}] : [];
|
|
504
|
+
});
|
|
505
|
+
unavailableMediaCount += unavailableFiles.length;
|
|
517
506
|
const combinedText = textBlocks.join("\n\n");
|
|
518
|
-
if (!combinedText && allMedia.length === 0 && allFiles.length === 0 &&
|
|
507
|
+
if (!combinedText && allMedia.length === 0 && allFiles.length === 0 && unavailableMediaCount === 0) return null;
|
|
519
508
|
return {
|
|
520
509
|
text: combinedText,
|
|
521
510
|
media: allMedia,
|
|
522
|
-
|
|
523
|
-
...
|
|
511
|
+
unavailableMediaCount,
|
|
512
|
+
...unavailableFiles.length > 0 ? { files: unavailableFiles } : {}
|
|
524
513
|
};
|
|
525
514
|
}
|
|
526
515
|
//#endregion
|
|
527
516
|
//#region extensions/slack/src/actions.ts
|
|
517
|
+
var actions_exports = /* @__PURE__ */ __exportAll({
|
|
518
|
+
deleteSlackMessage: () => deleteSlackMessage,
|
|
519
|
+
downloadSlackFile: () => downloadSlackFile,
|
|
520
|
+
editSlackMessage: () => editSlackMessage,
|
|
521
|
+
editSlackRenderedMessage: () => editSlackRenderedMessage,
|
|
522
|
+
getSlackMemberInfo: () => getSlackMemberInfo,
|
|
523
|
+
listSlackEmojis: () => listSlackEmojis,
|
|
524
|
+
listSlackPins: () => listSlackPins,
|
|
525
|
+
listSlackReactions: () => listSlackReactions,
|
|
526
|
+
openSlackConversation: () => openSlackConversation,
|
|
527
|
+
pinSlackMessage: () => pinSlackMessage,
|
|
528
|
+
reactSlackMessage: () => reactSlackMessage,
|
|
529
|
+
readSlackMessages: () => readSlackMessages,
|
|
530
|
+
removeOwnSlackReactions: () => removeOwnSlackReactions,
|
|
531
|
+
removeSlackReaction: () => removeSlackReaction,
|
|
532
|
+
resolveSlackConversationName: () => resolveSlackConversationName,
|
|
533
|
+
sendSlackMessage: () => sendSlackMessage,
|
|
534
|
+
unpinSlackMessage: () => unpinSlackMessage
|
|
535
|
+
});
|
|
528
536
|
function renderSlackReadMessageText(message) {
|
|
529
537
|
if (!hasSlackMessageTableBlock(message)) return message;
|
|
530
|
-
const text = resolveSlackMessageText
|
|
538
|
+
const text = resolveSlackMessageText(message, { preserveMessageTextWhitespace: true });
|
|
531
539
|
return text && text !== message.text ? {
|
|
532
540
|
...message,
|
|
533
541
|
text
|
|
@@ -691,6 +699,7 @@ async function listSlackReactions(channelId, messageId, opts = {}) {
|
|
|
691
699
|
})).message?.reactions ?? [];
|
|
692
700
|
}
|
|
693
701
|
async function sendSlackMessage(to, content, opts) {
|
|
702
|
+
const onDeliveryResult = Object.getOwnPropertyDescriptor(opts, SLACK_PRIVATE_ACTION_DELIVERY_RESULT)?.value;
|
|
694
703
|
return await sendMessageSlack(to, content, {
|
|
695
704
|
accountId: opts.accountId,
|
|
696
705
|
cfg: opts.cfg,
|
|
@@ -709,11 +718,17 @@ async function sendSlackMessage(to, content, opts) {
|
|
|
709
718
|
...Object.hasOwn(opts, "nativeDataFallbackBaseText") ? { nativeDataFallbackBaseText: opts.nativeDataFallbackBaseText } : {},
|
|
710
719
|
...opts.uploadFileName ? { uploadFileName: opts.uploadFileName } : {},
|
|
711
720
|
...opts.uploadTitle ? { uploadTitle: opts.uploadTitle } : {},
|
|
721
|
+
...typeof onDeliveryResult === "function" ? { onDeliveryResult } : {},
|
|
712
722
|
blocks: opts.blocks
|
|
713
723
|
});
|
|
714
724
|
}
|
|
715
725
|
async function editSlackMessage(channelId, messageId, content, opts = {}) {
|
|
716
|
-
|
|
726
|
+
const accountId = opts.accountId ?? (opts.cfg ? resolveDefaultSlackAccountId(opts.cfg) : void 0);
|
|
727
|
+
await editSlackRenderedMessage(channelId, messageId, normalizeSlackOutboundText(content, { tableMode: resolveMarkdownTableMode({
|
|
728
|
+
cfg: opts.cfg,
|
|
729
|
+
channel: "slack",
|
|
730
|
+
accountId
|
|
731
|
+
}) }), opts);
|
|
717
732
|
}
|
|
718
733
|
async function editSlackRenderedMessage(channelId, messageId, content, opts = {}) {
|
|
719
734
|
const client = await getClient(opts, "write");
|
|
@@ -758,6 +773,13 @@ async function deleteSlackMessage(channelId, messageId, opts = {}) {
|
|
|
758
773
|
ts: messageId
|
|
759
774
|
});
|
|
760
775
|
}
|
|
776
|
+
async function openSlackConversation(userIds, opts = {}) {
|
|
777
|
+
const input = parseSlackConversationOpenInput(userIds, opts.teamId);
|
|
778
|
+
return await openSlackConversationWithClient(await getClient({
|
|
779
|
+
...opts,
|
|
780
|
+
teamId: input.teamId
|
|
781
|
+
}, "write"), input);
|
|
782
|
+
}
|
|
761
783
|
async function resolveSlackConversationName(channelId, opts = {}) {
|
|
762
784
|
return (await (await getClient(opts, "read")).conversations.info({ channel: channelId })).channel?.name?.trim() || void 0;
|
|
763
785
|
}
|
|
@@ -842,48 +864,34 @@ function collectSlackShareMaps(file) {
|
|
|
842
864
|
const shares = file.shares;
|
|
843
865
|
return [shares.public, shares.private].filter((value) => Boolean(value) && typeof value === "object" && !Array.isArray(value));
|
|
844
866
|
}
|
|
845
|
-
function
|
|
846
|
-
const
|
|
847
|
-
for (const shareMap of collectSlackShareMaps(file)) for (const
|
|
848
|
-
const
|
|
849
|
-
if (
|
|
850
|
-
}
|
|
851
|
-
return ids;
|
|
852
|
-
}
|
|
853
|
-
function collectSlackThreadShares(file, channelId) {
|
|
854
|
-
const matches = [];
|
|
855
|
-
for (const shareMap of collectSlackShareMaps(file)) {
|
|
856
|
-
const rawEntries = shareMap[channelId];
|
|
857
|
-
if (!Array.isArray(rawEntries)) continue;
|
|
867
|
+
function collectSlackShares(file) {
|
|
868
|
+
const shares = [];
|
|
869
|
+
for (const shareMap of collectSlackShareMaps(file)) for (const [rawChannelId, rawEntries] of Object.entries(shareMap)) {
|
|
870
|
+
const channelId = normalizeOptionalString(rawChannelId);
|
|
871
|
+
if (!channelId || !Array.isArray(rawEntries)) continue;
|
|
858
872
|
for (const rawEntry of rawEntries) {
|
|
859
873
|
if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) continue;
|
|
860
874
|
const entry = rawEntry;
|
|
861
875
|
const ts = typeof entry.ts === "string" ? normalizeOptionalString(entry.ts) : void 0;
|
|
862
876
|
const threadTs = typeof entry.thread_ts === "string" ? normalizeOptionalString(entry.thread_ts) : void 0;
|
|
863
|
-
|
|
877
|
+
if (ts || threadTs) shares.push({
|
|
864
878
|
channelId,
|
|
865
879
|
ts,
|
|
866
880
|
threadTs
|
|
867
881
|
});
|
|
868
882
|
}
|
|
869
883
|
}
|
|
870
|
-
return
|
|
884
|
+
return shares;
|
|
871
885
|
}
|
|
872
|
-
function
|
|
886
|
+
function lacksSlackScopeProof(params) {
|
|
873
887
|
const channelId = normalizeOptionalString(params.channelId);
|
|
874
|
-
if (!channelId) return
|
|
888
|
+
if (!channelId) return true;
|
|
875
889
|
const threadId = normalizeOptionalString(params.threadId);
|
|
876
890
|
const directIds = collectSlackDirectShareChannelIds(params.file);
|
|
877
|
-
const
|
|
878
|
-
|
|
879
|
-
const inChannel = directIds.has(channelId) || sharedIds.has(channelId);
|
|
880
|
-
if (hasChannelEvidence && !inChannel) return true;
|
|
891
|
+
const shares = collectSlackShares(params.file);
|
|
892
|
+
if (!(directIds.has(channelId) || shares.some((entry) => entry.channelId === channelId))) return true;
|
|
881
893
|
if (!threadId) return false;
|
|
882
|
-
|
|
883
|
-
if (threadShares.length === 0) return false;
|
|
884
|
-
const threadEvidence = threadShares.filter((entry) => entry.threadTs || entry.ts);
|
|
885
|
-
if (threadEvidence.length === 0) return false;
|
|
886
|
-
return !threadEvidence.some((entry) => entry.threadTs === threadId || entry.ts === threadId);
|
|
894
|
+
return !shares.some((entry) => entry.channelId === channelId && (entry.threadTs === threadId || entry.ts === threadId));
|
|
887
895
|
}
|
|
888
896
|
/**
|
|
889
897
|
* Downloads a Slack file by ID and saves it to the local media store.
|
|
@@ -893,13 +901,14 @@ function hasSlackScopeMismatch(params) {
|
|
|
893
901
|
async function downloadSlackFile(fileId, opts) {
|
|
894
902
|
const token = resolveToken(opts.token, opts.accountId, opts.cfg);
|
|
895
903
|
const client = await getClient(opts);
|
|
896
|
-
const
|
|
897
|
-
if (!file?.url_private_download && !file?.url_private) return null;
|
|
898
|
-
if (hasSlackScopeMismatch({
|
|
904
|
+
const isFileAllowed = (file) => !lacksSlackScopeProof({
|
|
899
905
|
file,
|
|
900
906
|
channelId: opts.channelId,
|
|
901
907
|
threadId: opts.threadId
|
|
902
|
-
})
|
|
908
|
+
});
|
|
909
|
+
const file = (await client.files.info({ file: fileId })).file;
|
|
910
|
+
if (!file?.url_private_download && !file?.url_private) return null;
|
|
911
|
+
if (!isFileAllowed(file)) return null;
|
|
903
912
|
return (await resolveSlackMedia({
|
|
904
913
|
files: [{
|
|
905
914
|
id: file.id,
|
|
@@ -909,9 +918,10 @@ async function downloadSlackFile(fileId, opts) {
|
|
|
909
918
|
url_private_download: file.url_private_download
|
|
910
919
|
}],
|
|
911
920
|
client,
|
|
921
|
+
isRefreshedFileAllowed: isFileAllowed,
|
|
912
922
|
token,
|
|
913
923
|
maxBytes: opts.maxBytes
|
|
914
924
|
}))?.[0] ?? null;
|
|
915
925
|
}
|
|
916
926
|
//#endregion
|
|
917
|
-
export { media_exports as _,
|
|
927
|
+
export { hasSlackMessageTableBlock as C, resolveSlackMessageText as D, resolveSlackBlocksText as E, buildSlackEditTextPayload as O, formatSlackFileReferenceList as S, isSlackUnfurlAttachment as T, media_exports as _, editSlackRenderedMessage as a, saveRemoteMedia as b, listSlackPins as c, reactSlackMessage as d, readSlackMessages as f, unpinSlackMessage as g, sendSlackMessage as h, editSlackMessage as i, listSlackReactions as l, removeSlackReaction as m, deleteSlackMessage as n, getSlackMemberInfo as o, removeOwnSlackReactions as p, downloadSlackFile as r, listSlackEmojis as s, actions_exports as t, pinSlackMessage as u, logVerbose$1 as v, hasSlackTableBlock as w, formatSlackFileReference as x, isGovSlackClient as y };
|