@openclaw/discord 2026.9.8 → 2026.10.1-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.
Files changed (147) hide show
  1. package/README.md +7 -0
  2. package/dist/.setup/{account-inspect-De8hOUxG.mjs → account-inspect-CjKqkDnH.mjs} +2 -2
  3. package/dist/.setup/{accounts-ChaMcixG.mjs → accounts-DXHCL8Zm.mjs} +9 -32
  4. package/dist/.setup/{active-turn-thread-route-fmHl1HNd.mjs → active-turn-thread-route-C4tp9noA.mjs} +5 -9
  5. package/dist/.setup/{activities-api-tvbsU2e3.mjs → activities-api-BL_hJ0JQ.mjs} +15 -18
  6. package/dist/.setup/{api-DVbJwZVt.mjs → api-_oznjffB.mjs} +1 -1
  7. package/dist/.setup/{approval-handler.runtime-DxCK2Rux.mjs → approval-handler.runtime-BilYSrRF.mjs} +22 -61
  8. package/dist/.setup/{approval-message-updates-BKFqavHZ.mjs → approval-message-updates-CgRwc2_Q.mjs} +2 -2
  9. package/dist/.setup/{audit-CLg9I71N.mjs → audit-DtvzxONM.mjs} +4 -4
  10. package/dist/.setup/{channel-access-C12aDZ0p.mjs → channel-access-BRp3Y-rF.mjs} +4 -17
  11. package/dist/.setup/{channel-type-DRCrEMss.mjs → channel-type-D1_b5UhU.mjs} +12 -16
  12. package/dist/.setup/{channel-DxlUVU9t.mjs → channel-z5lQMS_9.mjs} +79 -75
  13. package/dist/.setup/{channel.setup-CRo1GjV7.mjs → channel.setup-DBJtugJO.mjs} +14 -34
  14. package/dist/.setup/{components-Cq1PvIpN.mjs → components-CzXLR3QH.mjs} +56 -72
  15. package/dist/.setup/{config-schema-oxELUSDx.mjs → config-schema-CsemBDpS.mjs} +6 -17
  16. package/dist/.setup/{conversation-binding-route-Caz_XuFH.mjs → conversation-binding-route-Bi62ApSt.mjs} +1 -1
  17. package/dist/.setup/{directory-config-esqNn0Eo.mjs → directory-config-BH1LA-gi.mjs} +1 -1
  18. package/dist/.setup/{directory-live-DtKRHuGV.mjs → directory-live-C9xz7IPm.mjs} +10 -13
  19. package/dist/.setup/{discord-0xJYfdDD.mjs → discord-J7aRzq2Q.mjs} +101 -381
  20. package/dist/.setup/{doctor-BCl1H5tl.mjs → doctor-DxSAngJq.mjs} +31 -70
  21. package/dist/.setup/doctor-contract-Bg3NPAMw.mjs +137 -0
  22. package/dist/.setup/{handle-action-CUvQWnE7.mjs → handle-action-DlmFX-_G.mjs} +10 -11
  23. package/dist/.setup/{handle-action.guild-admin-Df-8gVle.mjs → handle-action.guild-admin-BnyqTczR.mjs} +67 -129
  24. package/dist/.setup/{live-policy-config-8Pv20CHc.mjs → live-policy-config-emmPNyh4.mjs} +1 -1
  25. package/dist/.setup/{message-handler-B-Jk4oDk.mjs → message-handler-BNToPZrx.mjs} +7 -6
  26. package/dist/.setup/{message-handler.preflight-v-__NSDq.mjs → message-handler.preflight-D0BcCyI7.mjs} +13 -23
  27. package/dist/.setup/{message-handler.preflight-pluralkit-CWLUBVcx.mjs → message-handler.preflight-pluralkit-D1g3eq0B.mjs} +5 -8
  28. package/dist/.setup/{message-handler.process-BNFFuChn.mjs → message-handler.process-CThRmCWK.mjs} +57 -96
  29. package/dist/.setup/{outbound-adapter-BobT-kse.mjs → outbound-adapter-BPq0c2wY.mjs} +11 -17
  30. package/dist/.setup/{outbound-session-route-zVGxxceg.mjs → outbound-session-route-DGPPKA0z.mjs} +21 -46
  31. package/dist/.setup/{presence-cache-Di3H3DIU.mjs → presence-cache-Dg3_dADn.mjs} +2 -4
  32. package/dist/.setup/{probe-LYrIHlBF.mjs → probe-DIRY8vh7.mjs} +17 -27
  33. package/dist/.setup/{provider-B_G5hASF.mjs → provider-D2OKMo0f.mjs} +273 -446
  34. package/dist/.setup/{provider-session.runtime-BYlTBFD2.mjs → provider-session.runtime-BupCTZQv.mjs} +3 -3
  35. package/dist/.setup/provider.runtime-BaW_JnfU.mjs +2 -0
  36. package/dist/.setup/{realtime-session.runtime-oUd9DOcz.mjs → realtime-session.runtime-D5RSC8Mm.mjs} +6 -8
  37. package/dist/.setup/{receive-recovery-CHPOsnLc.mjs → receive-recovery-GqF2PUN_.mjs} +1 -4
  38. package/dist/.setup/{resolve-allowlist-common-DPdRggu5.mjs → resolve-allowlist-common-DUYRrrVB.mjs} +5 -9
  39. package/dist/.setup/{resolve-channels-BFPNRmVv.mjs → resolve-channels--MUatisx.mjs} +3 -3
  40. package/dist/.setup/{resolve-users-0-aBuCy3.mjs → resolve-users-CxLcDmM0.mjs} +6 -9
  41. package/dist/.setup/{retry-pz_cSha2.mjs → retry-BKzO25k4.mjs} +27 -51
  42. package/dist/.setup/{runtime-sUksZ--Q.mjs → runtime-CerRBfaa.mjs} +2 -2
  43. package/dist/.setup/{runtime-FN000lxA.mjs → runtime-CwUA0RLr.mjs} +228 -255
  44. package/dist/.setup/{runtime-doctor-migrations-CshUGl36.mjs → runtime-doctor-migrations-BPV-R4G9.mjs} +6 -0
  45. package/dist/.setup/{security-audit-Cdaegq7C.mjs → security-audit-D42cp5N7.mjs} +21 -48
  46. package/dist/.setup/{send-CrfEI6Bs.mjs → send-2X7m2Zmw.mjs} +45 -58
  47. package/dist/.setup/{send.components-DxQAMfES.mjs → send.components-RqvgmCs3.mjs} +44 -90
  48. package/dist/.setup/{send.outbound-BISKnb-a.mjs → send.outbound-B4QHSEzm.mjs} +60 -98
  49. package/dist/.setup/{send.shared-DGFkbkQR.mjs → send.shared-BQIUh6Vn.mjs} +13 -20
  50. package/dist/.setup/{sender-identity-B9X5Vb9R.mjs → sender-identity-CooeYfAn.mjs} +1 -1
  51. package/dist/.setup/{session-key-normalization-wJgsKPNF.mjs → session-key-normalization-CCHGNSQw.mjs} +3 -9
  52. package/dist/.setup/setup-plugin-api-nn_giXvZ.mjs +3 -0
  53. package/dist/.setup/{shared-B3wZ4hN-.mjs → shared-CIJn6AEC.mjs} +7 -7
  54. package/dist/.setup/{subagent-hooks-nlUE9ow7.mjs → subagent-hooks-BYlVnxzy.mjs} +4 -9
  55. package/dist/.setup/{system-events-CdeZnvPV.mjs → system-events-CQ3if_pS.mjs} +2 -2
  56. package/dist/.setup/{target-resolver-BuLapkhy.mjs → target-resolver-Dzxf80Y3.mjs} +5 -13
  57. package/dist/.setup/targets-Lf8D55w-.mjs +3 -0
  58. package/dist/.setup/{thread-bindings-D7TfgjR_.mjs → thread-bindings-yNNlcUWE.mjs} +5 -6
  59. package/dist/.setup/{thread-bindings.manager-DN-NissX.mjs → thread-bindings.manager-plk0zJAW.mjs} +14 -20
  60. package/dist/.setup/{thread-bindings.session-updates-CshfKghV.mjs → thread-bindings.session-updates-C9aKtVs6.mjs} +295 -5
  61. package/dist/.setup/{timeouts-D86uWLt_.mjs → timeouts-pun7VJ02.mjs} +2 -15
  62. package/dist/.setup/{transcripts-source-p8EV179h.mjs → transcripts-source-CNWswry-.mjs} +31 -79
  63. package/dist/.setup/typing-CNlSKY5S.mjs +11 -0
  64. package/dist/.setup/{voice-runtime-B46rcwrG.mjs → voice-runtime-Bc75quiH.mjs} +62 -110
  65. package/dist/account-inspect-api.js +1 -1
  66. package/dist/action-runtime-api.js +1 -1
  67. package/dist/activities-api.js +1 -1
  68. package/dist/api.js +18 -18
  69. package/dist/channel-config-api.js +1 -1
  70. package/dist/channel-plugin-api.js +1 -1
  71. package/dist/control-ui/2afbdab1d3aa65a789d8a3eba666f4b1ec5df07073538fe30d6cf32093a1fb2d/index.js +1 -0
  72. package/dist/directory-contract-api.js +1 -1
  73. package/dist/doctor-contract-api.js +19 -128
  74. package/dist/index.js +1 -1
  75. package/dist/runtime-api.js +20 -21
  76. package/dist/security-audit-contract-api.js +1 -1
  77. package/dist/session-key-api.js +1 -1
  78. package/dist/setup-entry.js +1 -1
  79. package/dist/setup-plugin-api.js +1 -1
  80. package/dist/src/voice/audio-worker.runtime.js +6 -8
  81. package/dist/subagent-hooks-api.js +1 -1
  82. package/dist/transcripts-source-api.js +1 -1
  83. package/node_modules/libopus-wasm/CHANGELOG.md +8 -0
  84. package/node_modules/libopus-wasm/dist/discordjs.d.ts.map +1 -1
  85. package/node_modules/libopus-wasm/dist/discordjs.js +14 -2
  86. package/node_modules/libopus-wasm/dist/generated/libopus.generated.mjs +0 -0
  87. package/node_modules/libopus-wasm/dist/index.d.ts.map +1 -1
  88. package/node_modules/libopus-wasm/dist/index.js +55 -100
  89. package/node_modules/libopus-wasm/package.json +5 -5
  90. package/node_modules/undici/README.md +10 -1
  91. package/node_modules/undici/docs/docs/api/Agent.md +8 -8
  92. package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +9 -6
  93. package/node_modules/undici/docs/docs/api/Dispatcher.md +9 -0
  94. package/node_modules/undici/docs/docs/api/Errors.md +25 -0
  95. package/node_modules/undici/docs/docs/api/Fetch.md +10 -0
  96. package/node_modules/undici/docs/docs/api/Interceptors.md +4 -3
  97. package/node_modules/undici/docs/docs/api/Pool.md +5 -6
  98. package/node_modules/undici/docs/docs/index.md +10 -1
  99. package/node_modules/undici/lib/api/readable.js +1 -2
  100. package/node_modules/undici/lib/core/request.js +23 -2
  101. package/node_modules/undici/lib/core/util.js +0 -39
  102. package/node_modules/undici/lib/dispatcher/client-h1.js +11 -4
  103. package/node_modules/undici/lib/dispatcher/client-h2.js +52 -8
  104. package/node_modules/undici/lib/dispatcher/client.js +6 -1
  105. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +21 -6
  106. package/node_modules/undici/lib/dispatcher/pool-base.js +63 -2
  107. package/node_modules/undici/lib/dispatcher/pool.js +90 -7
  108. package/node_modules/undici/lib/dispatcher/proxy-agent.js +16 -3
  109. package/node_modules/undici/lib/handler/deduplication-handler.js +24 -11
  110. package/node_modules/undici/lib/handler/redirect-handler.js +5 -0
  111. package/node_modules/undici/lib/handler/retry-handler.js +72 -13
  112. package/node_modules/undici/lib/interceptor/cache.js +4 -1
  113. package/node_modules/undici/lib/interceptor/decompress.js +236 -69
  114. package/node_modules/undici/lib/web/cache/cache.js +17 -8
  115. package/node_modules/undici/lib/web/cache/cachestorage.js +11 -5
  116. package/node_modules/undici/lib/web/cookies/index.js +19 -7
  117. package/node_modules/undici/lib/web/cookies/util.js +3 -1
  118. package/node_modules/undici/lib/web/eventsource/eventsource.js +25 -1
  119. package/node_modules/undici/lib/web/fetch/body.js +22 -15
  120. package/node_modules/undici/lib/web/fetch/data-url.js +6 -6
  121. package/node_modules/undici/lib/web/fetch/formdata.js +30 -36
  122. package/node_modules/undici/lib/web/fetch/headers.js +34 -31
  123. package/node_modules/undici/lib/web/fetch/index.js +46 -25
  124. package/node_modules/undici/lib/web/fetch/request.js +74 -79
  125. package/node_modules/undici/lib/web/fetch/response.js +43 -44
  126. package/node_modules/undici/lib/web/fetch/util.js +7 -7
  127. package/node_modules/undici/lib/web/infra/index.js +16 -1
  128. package/node_modules/undici/lib/web/webidl/index.js +2 -14
  129. package/node_modules/undici/lib/web/websocket/connection.js +33 -12
  130. package/node_modules/undici/lib/web/websocket/events.js +43 -26
  131. package/node_modules/undici/lib/web/websocket/receiver.js +2 -0
  132. package/node_modules/undici/lib/web/websocket/stream/websocketerror.js +13 -10
  133. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +19 -4
  134. package/node_modules/undici/lib/web/websocket/websocket.js +44 -41
  135. package/node_modules/undici/package.json +1 -1
  136. package/node_modules/undici/types/diagnostics-channel.d.ts +2 -1
  137. package/node_modules/undici/types/interceptors.d.ts +1 -1
  138. package/node_modules/undici/types/webidl.d.ts +13 -7
  139. package/openclaw.plugin.json +6 -0
  140. package/package.json +12 -7
  141. package/dist/.setup/doctor-contract-CvvgwrrG.mjs +0 -409
  142. package/dist/.setup/model-picker-preference-primitives-BHT1LkR_.mjs +0 -37
  143. package/dist/.setup/provider.runtime-CUE3UxER.mjs +0 -2
  144. package/dist/.setup/setup-plugin-api-BQUBxbhe.mjs +0 -3
  145. package/dist/.setup/targets-0KUcEIYx.mjs +0 -3
  146. package/dist/.setup/thread-bindings.state-g6v9zAym.mjs +0 -331
  147. package/dist/.setup/typing-BiHCzBRu.mjs +0 -15
package/README.md CHANGED
@@ -9,3 +9,10 @@ openclaw plugins install @openclaw/discord
9
9
  ```
10
10
 
11
11
  Configure a Discord bot token and the channels or servers OpenClaw should handle. The plugin lets OpenClaw agents receive Discord messages and respond through the configured Discord app.
12
+
13
+ Configurations using pre-July-2026 `voice.tts.<provider>` keys or per-channel
14
+ `allow`/`agentId` fields require an intermediate upgrade. Install OpenClaw
15
+ `2026.9.7` and run `openclaw doctor --fix` before upgrading again. Current Doctor
16
+ preserves these old settings and reports the exact path instead of rewriting
17
+ them. Supported configurations use `voice.tts.providers`, channel `enabled`,
18
+ and top-level `bindings`.
@@ -1,6 +1,6 @@
1
- import { _ as inspectDiscordAccountTokenState, o as mergeDiscordAccountConfig, r as listDiscordAccountIds, s as resolveDefaultDiscordAccountId, u as resolveDiscordAccountConfig, v as resolveDiscordAccountAvailability } from "./accounts-ChaMcixG.mjs";
2
- import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
1
+ import { _ as inspectDiscordAccountTokenState, o as mergeDiscordAccountConfig, r as listDiscordAccountIds, s as resolveDefaultDiscordAccountId, u as resolveDiscordAccountConfig, v as resolveDiscordAccountAvailability } from "./accounts-DXHCL8Zm.mjs";
3
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
+ import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
4
4
  import { normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
5
5
  //#region extensions/discord/src/account-inspect.ts
6
6
  function inspectDiscordAccountPrimary(params) {
@@ -1,9 +1,9 @@
1
+ import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
1
2
  import { createAccountActionGate, createAccountListHelpers } from "openclaw/plugin-sdk/account-helpers";
2
3
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
3
4
  import { mapAllowFromEntries, normalizeChannelDmPolicy } from "openclaw/plugin-sdk/channel-config-helpers";
4
5
  import { resolveConfiguredFromCredentialStatuses } from "openclaw/plugin-sdk/channel-status";
5
6
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, normalizeAccountId as normalizeAccountId$1, resolveAccountEntry } from "openclaw/plugin-sdk/routing";
6
- import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  import { hasConfiguredSecretInput, normalizeResolvedSecretInputString, normalizeSecretInputString, resolveSecretInputString } from "openclaw/plugin-sdk/secret-input";
8
8
  import { getRuntimeConfigSnapshot, getRuntimeConfigSourceSnapshot, selectApplicableRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
9
9
  //#region extensions/discord/src/account-token-inspect.ts
@@ -22,43 +22,20 @@ function inspectDiscordConfiguredToken(value) {
22
22
  return null;
23
23
  }
24
24
  function inspectDiscordAccountTokenState(params) {
25
- const accountToken = inspectDiscordConfiguredToken(params.accountToken);
26
- if (accountToken) return {
25
+ const configuredToken = inspectDiscordConfiguredToken(params.accountToken) ?? (params.hasAccountToken ? null : inspectDiscordConfiguredToken(params.channelToken));
26
+ if (configuredToken) return {
27
27
  ...params.base,
28
- ...accountToken,
29
- configured: true,
30
- config: params.config
31
- };
32
- if (params.hasAccountToken) return {
33
- ...params.base,
34
- token: "",
35
- tokenSource: "none",
36
- tokenStatus: "missing",
37
- configured: false,
38
- config: params.config
39
- };
40
- const channelToken = inspectDiscordConfiguredToken(params.channelToken);
41
- if (channelToken) return {
42
- ...params.base,
43
- ...channelToken,
44
- configured: true,
45
- config: params.config
46
- };
47
- const fallback = params.resolveFallbackToken();
48
- if (fallback.token) return {
49
- ...params.base,
50
- token: fallback.token,
51
- tokenSource: fallback.source,
52
- tokenStatus: "available",
28
+ ...configuredToken,
53
29
  configured: true,
54
30
  config: params.config
55
31
  };
32
+ const fallback = params.hasAccountToken ? void 0 : params.resolveFallbackToken();
56
33
  return {
57
34
  ...params.base,
58
- token: "",
59
- tokenSource: "none",
60
- tokenStatus: "missing",
61
- configured: false,
35
+ token: fallback?.token || "",
36
+ tokenSource: fallback?.token ? fallback.source : "none",
37
+ tokenStatus: fallback?.token ? "available" : "missing",
38
+ configured: Boolean(fallback?.token),
62
39
  config: params.config
63
40
  };
64
41
  }
@@ -28,17 +28,13 @@ async function notifyDiscordActiveTurnThreadCreated(params) {
28
28
  return true;
29
29
  }
30
30
  function notifyDiscordActiveTurnThreadReplyDelivered(params) {
31
- const route = findDiscordActiveTurnThreadReplyRoute(params);
32
- const threadId = normalizeOptionalString(params.threadId ?? void 0);
33
- if (!route || !threadId) return false;
34
- route.onThreadReplyDelivered?.(threadId);
35
- return true;
36
- }
37
- function findDiscordActiveTurnThreadReplyRoute(params) {
38
31
  const key = normalizeOptionalString(params.sessionKey ?? void 0);
39
32
  const threadId = normalizeOptionalString(params.threadId);
40
- if (!key || !threadId) return;
41
- return Array.from(activeRoutes.get(key) ?? []).find((route) => Boolean(route.adoptedThreadId) && route.adoptedThreadId === threadId && (!route.accountId || !params.accountId || route.accountId === params.accountId));
33
+ if (!key || !threadId) return false;
34
+ const route = Array.from(activeRoutes.get(key) ?? []).find((candidate) => candidate.adoptedThreadId === threadId && (!candidate.accountId || !params.accountId || candidate.accountId === params.accountId));
35
+ if (!route) return false;
36
+ route.onThreadReplyDelivered?.(threadId);
37
+ return true;
42
38
  }
43
39
  //#endregion
44
40
  export { notifyDiscordActiveTurnThreadCreated as n, notifyDiscordActiveTurnThreadReplyDelivered as r, beginDiscordActiveTurnThreadRoute as t };
@@ -1,11 +1,12 @@
1
- import { S as parseDiscordActivityCustomId, i as buildDiscordPresentationComponents } from "./components-Cq1PvIpN.mjs";
2
- import { D as getDiscordEndpointRuntime } from "./channel-type-DRCrEMss.mjs";
3
- import { c as resolveDiscordAccount } from "./accounts-ChaMcixG.mjs";
4
- import { r as sendDiscordComponentMessage } from "./send.components-DxQAMfES.mjs";
5
- import { x as resolveDiscordChannelId$1 } from "./retry-pz_cSha2.mjs";
6
- import { r as setDiscordActivitiesRuntime, t as DiscordActivitiesRuntime } from "./runtime-sUksZ--Q.mjs";
1
+ import { S as parseDiscordActivityCustomId, i as buildDiscordPresentationComponents } from "./components-CzXLR3QH.mjs";
2
+ import { O as getDiscordEndpointRuntime } from "./channel-type-D1_b5UhU.mjs";
3
+ import { c as resolveDiscordAccount } from "./accounts-DXHCL8Zm.mjs";
4
+ import { r as sendDiscordComponentMessage } from "./send.components-RqvgmCs3.mjs";
5
+ import { x as resolveDiscordChannelId$1 } from "./retry-BKzO25k4.mjs";
6
+ import { r as setDiscordActivitiesRuntime, t as DiscordActivitiesRuntime } from "./runtime-CerRBfaa.mjs";
7
7
  import fs from "node:fs/promises";
8
8
  import { logError } from "openclaw/plugin-sdk/logging-core";
9
+ import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
9
10
  import { resolveRequestClientIp } from "openclaw/plugin-sdk/webhook-ingress";
10
11
  import { WEBHOOK_BODY_READ_DEFAULTS, readJsonBodyWithLimit, sendHttpRequestRejection } from "openclaw/plugin-sdk/webhook-request-guards";
11
12
  import { WIDGET_CDN_ORIGINS } from "openclaw/plugin-sdk/widget-html";
@@ -21,15 +22,11 @@ const JSON_MAX_BYTES = 65536;
21
22
  const INSTANCE_ID_MAX_LENGTH = 256;
22
23
  function normalizeInstanceId(value) {
23
24
  const instanceId = value?.trim();
24
- let hasControlCharacter = false;
25
- for (let index = 0; index < (instanceId?.length ?? 0); index += 1) {
26
- const codePoint = instanceId?.charCodeAt(index) ?? 0;
27
- if (codePoint < 32 || codePoint === 127) {
28
- hasControlCharacter = true;
29
- break;
30
- }
25
+ if (!instanceId || instanceId.length > INSTANCE_ID_MAX_LENGTH) return;
26
+ for (let index = 0; index < instanceId.length; index += 1) {
27
+ const codePoint = instanceId.charCodeAt(index);
28
+ if (codePoint < 32 || codePoint === 127) return;
31
29
  }
32
- if (!instanceId || instanceId.length > INSTANCE_ID_MAX_LENGTH || hasControlCharacter) return;
33
30
  return instanceId;
34
31
  }
35
32
  async function fetchDiscordJson(params) {
@@ -337,7 +334,7 @@ function createDiscordActivityHttpHandler(deps) {
337
334
  await sendHttpRequestRejection(req, res, timedOut ? 408 : 413, jsonBody({ error: timedOut ? "request body timeout" : "request body too large" }), JSON_CONTENT_TYPE);
338
335
  return true;
339
336
  }
340
- const body = bodyResult.ok && bodyResult.value && typeof bodyResult.value === "object" && !Array.isArray(bodyResult.value) ? bodyResult.value : null;
337
+ const body = bodyResult.ok ? asOptionalRecord(bodyResult.value) : void 0;
341
338
  const code = typeof body?.code === "string" ? body.code.trim() : "";
342
339
  if (!code) return respondJson(res, 401, { error: "invalid authorization code" });
343
340
  const reservation = limiter.reserveGlobal();
@@ -520,7 +517,7 @@ function resolveDiscordPresentationRoute(context, runtime) {
520
517
  };
521
518
  }
522
519
  /** Presents a canonical core widget document in the active Discord channel. */
523
- function createDiscordWidgetPresenter(runtime, deps = {}) {
520
+ function createDiscordWidgetPresenter(runtime) {
524
521
  return {
525
522
  target: "current_channel",
526
523
  description: "Post an Activity launch button in the current Discord channel",
@@ -562,7 +559,7 @@ function createDiscordWidgetPresenter(runtime, deps = {}) {
562
559
  title,
563
560
  channelId: route.channelId,
564
561
  accountId: route.account.accountId,
565
- createdAt: (deps.now ?? Date.now)()
562
+ createdAt: Date.now()
566
563
  });
567
564
  let result;
568
565
  let deliveredResult;
@@ -590,7 +587,7 @@ function createDiscordWidgetPresenter(runtime, deps = {}) {
590
587
  }]
591
588
  }] });
592
589
  if (!components) throw new Error("Discord widget launch button could not be rendered");
593
- result = await (deps.sendComponentMessage ?? sendDiscordComponentMessage)(`channel:${route.channelId}`, {
590
+ result = await sendDiscordComponentMessage(`channel:${route.channelId}`, {
594
591
  ...components,
595
592
  text: title
596
593
  }, {
@@ -1,4 +1,4 @@
1
- import { D as getDiscordEndpointRuntime, T as parseDiscordRetryAfterBodySeconds } from "./channel-type-DRCrEMss.mjs";
1
+ import { E as parseDiscordRetryAfterBodySeconds, O as getDiscordEndpointRuntime } from "./channel-type-D1_b5UhU.mjs";
2
2
  import { redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
3
3
  import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
4
4
  import { captureChannelReadAuthority, resolveFetch } from "openclaw/plugin-sdk/fetch-runtime";
@@ -1,35 +1,15 @@
1
- import { s as buildExecApprovalCustomId } from "./components-Cq1PvIpN.mjs";
2
- import { A as serializePayload, B as Container, J as Separator, K as Row, R as Button, X as TextDisplay, ct as createChannelMessage, dt as deleteChannelMessage, pt as editChannelMessage, rt as createUserDmChannel, tt as stripUndefinedFields } from "./discord-0xJYfdDD.mjs";
3
- import { s as findGraphemeChunkEnd } from "./retry-pz_cSha2.mjs";
4
- import { D as createDiscordMessageNonce, M as createDiscordClient } from "./send.shared-DGFkbkQR.mjs";
5
- import { D as isDiscordExecApprovalClientEnabled, c as formatDiscordApprovalDisplayValue, s as DISCORD_APPROVAL_ALLOWED_MENTIONS } from "./outbound-session-route-zVGxxceg.mjs";
6
- import { a as shouldHandleDiscordApprovalRequest } from "./channel-DxlUVU9t.mjs";
7
- import { t as discordApprovalMessageUpdates } from "./approval-message-updates-BKFqavHZ.mjs";
1
+ import { s as buildExecApprovalCustomId } from "./components-CzXLR3QH.mjs";
2
+ import { A as serializePayload, B as Container, J as Separator, K as Row, R as Button, X as TextDisplay, lt as deleteChannelMessage, rt as createUserDmChannel, tt as stripUndefinedFields, ut as editChannelMessage } from "./discord-J7aRzq2Q.mjs";
3
+ import { s as findGraphemeChunkEnd } from "./retry-BKzO25k4.mjs";
4
+ import { D as createDiscordMessageNonce, M as createDiscordClient } from "./send.shared-BQIUh6Vn.mjs";
5
+ import { D as isDiscordExecApprovalClientEnabled, c as formatDiscordApprovalDisplayValue, s as DISCORD_APPROVAL_ALLOWED_MENTIONS } from "./outbound-session-route-DGPPKA0z.mjs";
6
+ import { a as shouldHandleDiscordApprovalRequest } from "./channel-z5lQMS_9.mjs";
7
+ import { t as discordApprovalMessageUpdates } from "./approval-message-updates-CgRwc2_Q.mjs";
8
8
  import { logDebug, logError } from "openclaw/plugin-sdk/logging-core";
9
- import { ButtonStyle } from "discord-api-types/v10";
10
9
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
10
+ import { ButtonStyle, Routes } from "discord-api-types/v10";
11
11
  import { createChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-runtime";
12
12
  import { formatChannelApprovalResolvedLabel } from "openclaw/plugin-sdk/approval-runtime";
13
- //#region extensions/discord/src/ui-colors.ts
14
- function normalizeDiscordAccentColor(raw) {
15
- const trimmed = (raw ?? "").trim();
16
- if (!trimmed) return null;
17
- const normalized = trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
18
- if (!/^#[0-9a-fA-F]{6}$/.test(normalized)) return null;
19
- return normalized.toUpperCase();
20
- }
21
- //#endregion
22
- //#region extensions/discord/src/ui.ts
23
- var DiscordUiContainer = class extends Container {
24
- constructor(params) {
25
- const accentColor = normalizeDiscordAccentColor(params.accentColor) ?? "#5865F2";
26
- super(params.components, {
27
- accentColor,
28
- spoiler: params.spoiler
29
- });
30
- }
31
- };
32
- //#endregion
33
13
  //#region extensions/discord/src/approval-handler.runtime.ts
34
14
  function resolveHandlerContext(params) {
35
15
  const context = params.context;
@@ -104,30 +84,19 @@ function createApprovalContainer(params) {
104
84
  divider: false,
105
85
  spacing: "small"
106
86
  }), new TextDisplay(`-# ${footer}`));
107
- return new DiscordUiContainer({
108
- cfg: params.cfg,
109
- accountId: params.accountId,
110
- components,
111
- accentColor
112
- });
87
+ return new Container(components, { accentColor });
113
88
  }
114
- async function updateMessage(params) {
115
- try {
89
+ async function finalizeMessage(params) {
90
+ if (params.cleanupAfterResolve) try {
116
91
  const { rest, request: discordRequest } = createDiscordClient({
117
92
  cfg: params.cfg,
118
93
  token: params.token,
119
94
  accountId: params.accountId
120
95
  });
121
- const payload = buildExecApprovalPayload(params.container);
122
- await discordApprovalMessageUpdates.enqueue(params.messageId, () => discordRequest(() => editChannelMessage(rest, params.channelId, params.messageId, { body: stripUndefinedFields(serializePayload(payload)) }), "update-approval"));
123
- } catch (err) {
124
- logError(`discord approvals: failed to update message: ${String(err)}`);
125
- }
126
- }
127
- async function finalizeMessage(params) {
128
- if (!params.cleanupAfterResolve) {
129
- await updateMessage(params);
96
+ await discordApprovalMessageUpdates.enqueue(params.messageId, () => discordRequest(() => deleteChannelMessage(rest, params.channelId, params.messageId), "delete-approval"));
130
97
  return;
98
+ } catch (err) {
99
+ logError(`discord approvals: failed to delete message: ${String(err)}`);
131
100
  }
132
101
  try {
133
102
  const { rest, request: discordRequest } = createDiscordClient({
@@ -135,22 +104,17 @@ async function finalizeMessage(params) {
135
104
  token: params.token,
136
105
  accountId: params.accountId
137
106
  });
138
- await discordApprovalMessageUpdates.enqueue(params.messageId, () => discordRequest(() => deleteChannelMessage(rest, params.channelId, params.messageId), "delete-approval"));
107
+ const payload = buildExecApprovalPayload(params.container);
108
+ await discordApprovalMessageUpdates.enqueue(params.messageId, () => discordRequest(() => editChannelMessage(rest, params.channelId, params.messageId, { body: stripUndefinedFields(serializePayload(payload)) }), "update-approval"));
139
109
  } catch (err) {
140
- logError(`discord approvals: failed to delete message: ${String(err)}`);
141
- await updateMessage(params);
110
+ logError(`discord approvals: failed to update message: ${String(err)}`);
142
111
  }
143
112
  }
144
113
  function buildTerminalApprovalResult(params) {
145
- const resolved = resolveHandlerContext(params);
146
- if (!resolved) return { kind: "delete" };
114
+ if (!resolveHandlerContext(params)) return { kind: "delete" };
147
115
  return {
148
116
  kind: "update",
149
- payload: createApprovalContainer({
150
- view: params.view,
151
- cfg: params.cfg,
152
- accountId: resolved.accountId
153
- })
117
+ payload: createApprovalContainer({ view: params.view })
154
118
  };
155
119
  }
156
120
  const discordApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter({
@@ -180,16 +144,13 @@ const discordApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter({
180
144
  },
181
145
  presentation: {
182
146
  buildPendingPayload: ({ cfg, accountId, context, view }) => {
183
- const resolved = resolveHandlerContext({
147
+ if (!resolveHandlerContext({
184
148
  cfg,
185
149
  accountId,
186
150
  context
187
- });
188
- if (!resolved) return { body: {} };
151
+ })) return { body: {} };
189
152
  const container = createApprovalContainer({
190
153
  view,
191
- cfg,
192
- accountId: resolved.accountId,
193
154
  actionRow: createApprovalActionRow(view)
194
155
  });
195
156
  return { body: stripUndefinedFields(serializePayload(buildExecApprovalPayload(container))) };
@@ -248,7 +209,7 @@ const discordApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter({
248
209
  nonce: createDiscordMessageNonce(),
249
210
  enforce_nonce: true
250
211
  };
251
- const message = await discordRequest(() => createChannelMessage(rest, preparedTarget.discordChannelId, { body }), plannedTarget.surface === "origin" ? "send-approval-channel" : "send-approval", { safety: "nonce-protected-create" });
212
+ const message = await discordRequest(() => rest.post(Routes.channelMessages(preparedTarget.discordChannelId), { body }), plannedTarget.surface === "origin" ? "send-approval-channel" : "send-approval", { safety: "nonce-protected-create" });
252
213
  if (!message?.id) {
253
214
  if (plannedTarget.surface === "origin") logError("discord approvals: failed to send to channel");
254
215
  else if (preparedTarget.recipientUserId) logError(`discord approvals: failed to send message to user ${preparedTarget.recipientUserId}`);
@@ -1,5 +1,5 @@
1
- import { c as parseExecApprovalData } from "./components-Cq1PvIpN.mjs";
2
- import { et as parseCustomId } from "./discord-0xJYfdDD.mjs";
1
+ import { c as parseExecApprovalData } from "./components-CzXLR3QH.mjs";
2
+ import { et as parseCustomId } from "./discord-J7aRzq2Q.mjs";
3
3
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
4
4
  //#region extensions/discord/src/approval-message-updates.ts
5
5
  const discordApprovalMessageUpdates = new KeyedAsyncQueue();
@@ -1,8 +1,8 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
2
- import { b as fetchChannelPermissionsDiscord } from "./send.shared-DGFkbkQR.mjs";
3
- import { t as inspectDiscordAccount } from "./account-inspect-De8hOUxG.mjs";
4
- import "./send-CrfEI6Bs.mjs";
5
- import { C as collectDiscordAuditChannelIdsForAccount, S as auditDiscordChannelPermissionsWithFetcher } from "./outbound-session-route-zVGxxceg.mjs";
2
+ import { b as fetchChannelPermissionsDiscord } from "./send.shared-BQIUh6Vn.mjs";
3
+ import { t as inspectDiscordAccount } from "./account-inspect-CjKqkDnH.mjs";
4
+ import "./send-2X7m2Zmw.mjs";
5
+ import { C as collectDiscordAuditChannelIdsForAccount, S as auditDiscordChannelPermissionsWithFetcher } from "./outbound-session-route-DGPPKA0z.mjs";
6
6
  //#region extensions/discord/src/audit.ts
7
7
  var audit_exports = /* @__PURE__ */ __exportAll({
8
8
  auditDiscordChannelPermissions: () => auditDiscordChannelPermissions,
@@ -16,18 +16,8 @@ function resolveDiscordChannelNumberPropertySafe(channel, key) {
16
16
  const value = readDiscordChannelPropertySafe(channel, key);
17
17
  return typeof value === "number" ? value : void 0;
18
18
  }
19
- const DISCORD_CHANNEL_SNAKE_CASE_ALIASES = {
20
- ownerId: "owner_id",
21
- parentId: "parent_id"
22
- };
23
- function resolveDiscordChannelStringWithAliasSafe(channel, camelKey) {
24
- const camelValue = resolveDiscordChannelStringPropertySafe(channel, camelKey);
25
- if (camelValue !== void 0) return camelValue;
26
- const snakeKey = DISCORD_CHANNEL_SNAKE_CASE_ALIASES[camelKey];
27
- if (!snakeKey) return;
28
- const directSnakeValue = resolveDiscordChannelStringPropertySafe(channel, snakeKey);
29
- if (directSnakeValue !== void 0) return directSnakeValue;
30
- return resolveDiscordChannelStringPropertySafe(readDiscordChannelPropertySafe(channel, "rawData"), snakeKey);
19
+ function resolveDiscordChannelStringWithAliasSafe(channel, camelKey, snakeKey) {
20
+ return resolveDiscordChannelStringPropertySafe(channel, camelKey) ?? resolveDiscordChannelStringPropertySafe(channel, snakeKey) ?? resolveDiscordChannelStringPropertySafe(readDiscordChannelPropertySafe(channel, "rawData"), snakeKey);
31
21
  }
32
22
  function resolveDiscordChannelNameSafe(channel) {
33
23
  return resolveDiscordChannelStringPropertySafe(channel, "name");
@@ -39,10 +29,7 @@ function resolveDiscordChannelTopicSafe(channel) {
39
29
  return resolveDiscordChannelStringPropertySafe(channel, "topic");
40
30
  }
41
31
  function resolveDiscordChannelParentIdSafe(channel) {
42
- return resolveDiscordChannelStringWithAliasSafe(channel, "parentId");
43
- }
44
- function resolveDiscordChannelOwnerIdSafe(channel) {
45
- return resolveDiscordChannelStringWithAliasSafe(channel, "ownerId");
32
+ return resolveDiscordChannelStringWithAliasSafe(channel, "parentId", "parent_id");
46
33
  }
47
34
  function resolveDiscordChannelParentSafe(channel) {
48
35
  return readDiscordChannelPropertySafe(channel, "parent");
@@ -54,7 +41,7 @@ function resolveDiscordChannelInfoSafe(channel) {
54
41
  topic: resolveDiscordChannelTopicSafe(channel),
55
42
  type: resolveDiscordChannelNumberPropertySafe(channel, "type"),
56
43
  parentId: resolveDiscordChannelParentIdSafe(channel),
57
- ownerId: resolveDiscordChannelOwnerIdSafe(channel),
44
+ ownerId: resolveDiscordChannelStringWithAliasSafe(channel, "ownerId", "owner_id"),
58
45
  parentName: resolveDiscordChannelNameSafe(parent)
59
46
  };
60
47
  }
@@ -1,9 +1,9 @@
1
+ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
1
2
  import { ChannelType } from "discord-api-types/v10";
2
3
  import { asFiniteNumberInRange, parseDateStringTimestampMs, parseStrictFiniteNumber } from "openclaw/plugin-sdk/number-runtime";
3
4
  import { readResponseWithLimit } from "openclaw/plugin-sdk/response-limit-runtime";
4
5
  import { fetchWithSsrFGuard, isBlockedHostnameOrIp, isLoopbackHost } from "openclaw/plugin-sdk/ssrf-runtime";
5
- import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
- import { buildChannelKeyCandidates, resolveChannelEntryMatchWithFallback, resolveChannelMatchConfig } from "openclaw/plugin-sdk/channel-targets";
6
+ import { buildChannelKeyCandidates, normalizeChannelSlug, resolveChannelEntryMatchWithFallback, resolveChannelMatchConfig } from "openclaw/plugin-sdk/channel-targets";
7
7
  import { resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
8
8
  //#region extensions/discord/src/endpoint-runtime.ts
9
9
  const DISCORD_ENDPOINT_RESPONSE_MAX_BYTES = 8388608;
@@ -224,7 +224,7 @@ function normalizeDiscordAllowList(raw, prefixes) {
224
224
  };
225
225
  }
226
226
  function normalizeDiscordSlug(value) {
227
- return normalizeLowercaseStringOrEmpty(value).replace(/^#/, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
227
+ return normalizeChannelSlug(value);
228
228
  }
229
229
  function normalizeDiscordDisplaySlug(value) {
230
230
  return normalizeLowercaseStringOrEmpty(value).normalize("NFC").replace(/^#/, "").replace(/[\s_]+/g, "-").replace(/[^\p{L}\p{M}\p{N}-]+/gu, "-").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "");
@@ -354,17 +354,13 @@ function resolveDiscordOwnerAccess(params) {
354
354
  }
355
355
  function resolveDiscordCommandAuthorized(params) {
356
356
  if (!params.isDirectMessage) return true;
357
- const allowList = normalizeDiscordAllowList(params.allowFrom, [
358
- "discord:",
359
- "user:",
360
- "pk:"
361
- ]);
362
- if (!allowList) return true;
363
- return allowListMatches(allowList, {
364
- id: params.author.id,
365
- name: params.author.username,
366
- tag: formatDiscordUserTag(params.author)
367
- }, { allowNameMatching: params.allowNameMatching });
357
+ return resolveDiscordUserAllowed({
358
+ allowList: params.allowFrom,
359
+ userId: params.author.id,
360
+ userName: params.author.username,
361
+ userTag: formatDiscordUserTag(params.author),
362
+ allowNameMatching: params.allowNameMatching
363
+ });
368
364
  }
369
365
  function resolveDiscordGuildEntry(params) {
370
366
  const guild = params.guild;
@@ -472,7 +468,7 @@ function isDiscordGroupAllowedByPolicy(params) {
472
468
  return params.groupPolicy !== "allowlist" || !params.channelAllowlistConfigured || params.channelAllowed;
473
469
  }
474
470
  function resolveDiscordChannelPolicyCommandAuthorizer(params) {
475
- const channelAllowlistConfigured = Boolean(params.guildInfo?.channels) && Object.keys(params.guildInfo?.channels ?? {}).length > 0;
471
+ const channelAllowlistConfigured = hasConfiguredDiscordChannels(params.guildInfo?.channels);
476
472
  return {
477
473
  configured: params.groupPolicy === "allowlist" && (Boolean(params.guildInfo) || channelAllowlistConfigured),
478
474
  allowed: isDiscordGroupAllowedByPolicy({
@@ -531,4 +527,4 @@ function isDiscordThreadChannelType(channelType) {
531
527
  return channelType === ChannelType.AnnouncementThread || channelType === ChannelType.PublicThread || channelType === ChannelType.PrivateThread;
532
528
  }
533
529
  //#endregion
534
- export { resolveDiscordSystemLocation as C, getDiscordEndpointRuntime as D, assertDiscordEndpointGatewayUrl as E, resolveDiscordEndpointAttachmentGuard as O, formatDiscordUserTag as S, parseDiscordRetryAfterBodySeconds as T, resolveDiscordOwnerAllowFrom as _, normalizeDiscordDisplaySlug as a, shouldEmitDiscordReactionNotification as b, resolveDiscordChannelConfig as c, resolveDiscordCommandAuthorized as d, resolveDiscordGuildEntry as f, resolveDiscordOwnerAccess as g, resolveDiscordMentionPolicy as h, normalizeDiscordAllowList as i, resolveDiscordEndpointMediaGuard as k, resolveDiscordChannelConfigWithFallback as l, resolveDiscordMemberAllowed as m, allowListMatches as n, normalizeDiscordSlug as o, resolveDiscordMemberAccessState as p, isDiscordGroupAllowedByPolicy as r, resolveDiscordAllowListMatch as s, isDiscordThreadChannelType as t, resolveDiscordChannelPolicyCommandAuthorizer as u, resolveDiscordShouldRequireMention as v, resolveTimestampMs as w, formatDiscordReactionEmoji as x, resolveGroupDmAllow as y };
530
+ export { resolveDiscordEndpointMediaGuard as A, formatDiscordUserTag as C, assertDiscordEndpointGatewayUrl as D, parseDiscordRetryAfterBodySeconds as E, getDiscordEndpointRuntime as O, formatDiscordReactionEmoji as S, resolveTimestampMs as T, resolveDiscordOwnerAccess as _, normalizeDiscordAllowList as a, resolveGroupDmAllow as b, resolveDiscordAllowListMatch as c, resolveDiscordChannelPolicyCommandAuthorizer as d, resolveDiscordCommandAuthorized as f, resolveDiscordMentionPolicy as g, resolveDiscordMemberAllowed as h, isDiscordGroupAllowedByPolicy as i, resolveDiscordEndpointAttachmentGuard as k, resolveDiscordChannelConfig as l, resolveDiscordMemberAccessState as m, allowListMatches as n, normalizeDiscordDisplaySlug as o, resolveDiscordGuildEntry as p, hasConfiguredDiscordChannels as r, normalizeDiscordSlug as s, isDiscordThreadChannelType as t, resolveDiscordChannelConfigWithFallback as u, resolveDiscordOwnerAllowFrom as v, resolveDiscordSystemLocation as w, shouldEmitDiscordReactionNotification as x, resolveDiscordShouldRequireMention as y };