@openclaw/discord 2026.7.2-beta.7 → 2026.8.1-beta.3
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-inspect-SXiCBCgP.js → account-inspect-D5xmUpnj.js} +49 -43
- package/dist/account-inspect-api.js +1 -1
- package/dist/accounts-DNl-oCEw.js +371 -0
- package/dist/action-runtime-api.js +1 -1
- package/dist/{active-turn-thread-route-MlKWp8RD.js → active-turn-thread-route-fmHl1HNd.js} +9 -11
- package/dist/{activities-api-DTKsuDxf.js → activities-api-KCBAmWxD.js} +133 -175
- package/dist/activities-api.js +1 -1
- package/dist/{allow-list-DzKrtfah.js → allow-list-BDMimASD.js} +2 -3
- package/dist/{api-DnrK9gML.js → api-DNVbJyEy.js} +7 -2
- package/dist/api.js +18 -18
- package/dist/{approval-handler.runtime-HymvFTYn.js → approval-handler.runtime-B12RCYr8.js} +6 -6
- package/dist/{approval-message-safety-DEyKVsAw.js → approval-message-safety-XGFPbDoI.js} +89 -3
- package/dist/{audit-CjsrabP8.js → audit-Yc7eZDd6.js} +5 -5
- package/dist/{channel-actions-uXFTJX3o.js → channel-actions-Dr2QI8Bf.js} +11 -7
- package/dist/{channel-actions.runtime-CIYU90sl.js → channel-actions.runtime-CODTvo7c.js} +99 -97
- package/dist/{channel-vKa-76xY.js → channel-cXYzGc4L.js} +102 -104
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.setup-CmcwZ_qd.js → channel.setup-CSiwnMgs.js} +16 -54
- package/dist/{outbound-session-route-H-HoyH5U.js → components-ezGKo_Yh.js} +69 -142
- package/dist/{config-schema-WHRQcY19.js → config-schema-DC5kDtQ5.js} +42 -11
- package/dist/conversation-binding-route-D6rCQ5S0.js +43 -0
- package/dist/{directory-config-D_LojtCe.js → directory-config-XyCfoqLg.js} +2 -2
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-Bw5Ephzv.js → directory-live-Df0NbFJB.js} +7 -4
- package/dist/{doctor-Bc4S1qyd.js → doctor-DYY31GrO.js} +34 -13
- package/dist/{doctor-contract-CCFMIDk9.js → doctor-contract-DsWvKIXF.js} +2 -3
- package/dist/doctor-contract-api.js +147 -2
- package/dist/{handle-action.guild-admin-D6VRRW-C.js → handle-action.guild-admin-6Tvvinsa.js} +4 -7
- package/dist/{inbound-event-delivery-CEPlt2uz.js → inbound-event-delivery-De2qxTrP.js} +4 -25
- package/dist/index.js +5 -4
- package/dist/{message-handler-CeiSulIw.js → message-handler-B61q5MOF.js} +118 -33
- package/dist/{message-handler.preflight-DibgQFf2.js → message-handler.preflight-Bzg_Hawz.js} +75 -61
- package/dist/{message-handler.process-Dnc_oz9y.js → message-handler.process--4_712Ec.js} +236 -296
- package/dist/{message-utils-BgTwT_q7.js → message-utils-BXLLnFl6.js} +34 -35
- package/dist/{model-picker-preference-primitives-D25pnCOu.js → model-picker-preference-primitives-BHT1LkR_.js} +3 -3
- package/dist/{outbound-adapter-DtE-i2OJ.js → outbound-adapter-DxHTOqiN.js} +157 -68
- package/dist/{outbound-components-C7GVyfPh.js → outbound-components-B2PL0ooH.js} +3 -3
- package/dist/owner-access-Bg41VzAf.js +107 -0
- package/dist/{pluralkit-CD4B11JB.js → pluralkit-dUl4v1X3.js} +1 -1
- package/dist/{preflight-audio-BjnQZ5yS.js → preflight-audio-DrnqFA8U.js} +22 -28
- package/dist/{probe-BeWKhjqX.js → probe-BTdtVRwU.js} +37 -13
- package/dist/probe.runtime-Dq5-PRKT.js +2 -0
- package/dist/{provider-DfQJX3z5.js → provider-DlK_ynqt.js} +1131 -2021
- package/dist/{provider-session.runtime-Bo88k0pV.js → provider-session.runtime-CvvphHvs.js} +3 -3
- package/dist/provider.runtime-CzKGRiAF.js +2 -0
- package/dist/realtime-session.runtime-ysbMG8v7.js +1351 -0
- package/dist/{resolve-allowlist-common-DHERApxi.js → resolve-allowlist-common-DIVXbD1P.js} +3 -3
- package/dist/{resolve-channels-BjepAj8b.js → resolve-channels-CGeUoIqb.js} +4 -4
- package/dist/{resolve-users-Bc28htgt.js → resolve-users-BtKxLUZv.js} +3 -3
- package/dist/{chunk-DX4jpFQP.js → retry-DNsVTeTo.js} +308 -131
- package/dist/{runtime-BmW_j_hl.js → runtime-CQovMsH3.js} +12 -15
- package/dist/{runtime-_aRC6V2s.js → runtime-D71_VFLr.js} +49 -58
- package/dist/runtime-api.actions.js +2 -2
- package/dist/runtime-api.js +23 -23
- package/dist/runtime-api.lookup.js +5 -5
- package/dist/runtime-api.monitor-CzeTYF32.js +6 -0
- package/dist/runtime-api.monitor.js +6 -5
- package/dist/runtime-api.send.js +6 -6
- package/dist/runtime-api.threads.js +5 -6
- package/dist/sdk-runtime-37OU6_Yh.js +369 -0
- package/dist/{secret-config-contract-B1akrlyY.js → secret-config-contract-B3i6WxV5.js} +53 -25
- package/dist/secret-contract-api.js +1 -1
- package/dist/security-audit-contract-api.js +1 -1
- package/dist/{security-audit.runtime-CPN0xFYz.js → security-audit.runtime-BVKF9VtY.js} +1 -1
- package/dist/{send-CdkZ6zeW.js → send-rQIffSYu.js} +180 -91
- package/dist/{send.components-5uqwkjgE.js → send.components-ChK1wS7w.js} +32 -46
- package/dist/{send.outbound-D-80Ej-t.js → send.outbound-HIkgji_7.js} +57 -34
- package/dist/{send.reactions-CtlmGd_o.js → send.reactions-gmJ6yFPo.js} +14 -21
- package/dist/{send.receipt-CuwRrpFz.js → send.receipt-Cnhoautb.js} +29 -1
- package/dist/{send.shared-jpvAG_u6.js → send.shared-B3fpaLWJ.js} +112 -181
- package/dist/{sender-identity-mG_zsdox.js → sender-identity-BJtfyise.js} +1 -1
- package/dist/setup-entry.js +0 -5
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{shared-CXF1tup1.js → shared-CaAaoksy.js} +27 -23
- package/dist/subagent-hooks-CNT2ZJTJ.js +49 -0
- package/dist/subagent-hooks-api.js +2 -6
- package/dist/subagent-progress-FPLqBY1s.js +110 -0
- package/dist/{system-events-DdUqf91B.js → system-events-Nuwoq_au.js} +2 -2
- package/dist/{target-resolver-C3s_2m0t.js → target-resolver-DIXShHaZ.js} +3 -3
- package/dist/targets-B2pf49zc.js +3 -0
- package/dist/{thread-bindings-C-M-ly7P.js → thread-bindings-VlymUnbz.js} +29 -28
- package/dist/{thread-bindings.manager-DYvSlrva.js → thread-bindings.manager-CngsgErq.js} +258 -29
- package/dist/{thread-bindings.session-updates-DAIlp7Px.js → thread-bindings.session-updates-CJb-BpPL.js} +1 -1
- package/dist/{thread-bindings.state-Cgi5uRn-.js → thread-bindings.state-D8OMdk4O.js} +3 -16
- package/dist/threading-DU6pgeGm.js +456 -0
- package/dist/transcripts-source-DeIMNbRh.js +265 -0
- package/dist/transcripts-source-api.js +7 -2
- package/dist/{typing--Mzo2kM7.js → typing-oLiS5Z13.js} +1 -1
- package/dist/voice-runtime-CjNFaynA.js +2549 -0
- package/openclaw.plugin.json +215 -25
- package/package.json +15 -11
- package/skills/discord/SKILL.md +22 -115
- package/dist/accounts-DJTf1LtA.js +0 -219
- package/dist/channel-api-CAJ0wMoV.js +0 -21
- package/dist/legacy-state-migrations-api.js +0 -138
- package/dist/manager.runtime-Bjav3pfC.js +0 -3655
- package/dist/preflight-audio.runtime-CoCXMM8r.js +0 -7
- package/dist/probe.runtime-DqFGFMbZ.js +0 -2
- package/dist/provider.runtime-Cy7XZmyh.js +0 -2
- package/dist/runtime-api.monitor-CCRubd3-.js +0 -5
- package/dist/session-binding-contract-api.js +0 -2
- package/dist/subagent-hooks-Dxy7Fmnq.js +0 -120
- package/dist/subagent-progress-DI3sYLLo.js +0 -664
- package/dist/targets-Dv_RN7vT.js +0 -3
- package/dist/thread-bindings.discord-api-BoDNqamb.js +0 -246
- package/dist/transcripts-source-DIKGsTGT.js +0 -123
- 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/dist/{audit-core-xwjIczO0.js → audit-core-BCX8UeFH.js} +1 -1
- package/dist/{security-audit-jGnJF__m.js → security-audit-BfJhAXZp.js} +1 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { s as resolveDefaultDiscordAccountId } from "./accounts-DNl-oCEw.js";
|
|
2
|
+
import { t as discordVoiceTranscriptsSourceProvider } from "./transcripts-source-DeIMNbRh.js";
|
|
3
|
+
import { t as inspectDiscordAccount } from "./account-inspect-D5xmUpnj.js";
|
|
4
|
+
import { r as DISCORD_LEGACY_CONFIG_RULES } from "./shared-CaAaoksy.js";
|
|
5
|
+
import { n as normalizeCompatibilityConfig } from "./doctor-contract-DsWvKIXF.js";
|
|
5
6
|
import { t as isDiscordMutableAllowEntry } from "./security-doctor-nGgPm65L.js";
|
|
6
|
-
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
7
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
8
|
-
import {
|
|
8
|
+
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
9
|
+
import { asObjectRecord, collectChannelAccountScopes, collectProviderDangerousNameMatchingScopes } from "openclaw/plugin-sdk/runtime-doctor-migrations";
|
|
9
10
|
//#region extensions/discord/src/doctor.ts
|
|
10
11
|
function sanitizeForLog(value) {
|
|
11
12
|
return value.replace(/\p{Cc}+/gu, " ").trim();
|
|
@@ -165,6 +166,22 @@ function collectDiscordMissingEnvTokenWarnings(params) {
|
|
|
165
166
|
if (!account.enabled || account.tokenStatus !== "missing" || account.tokenSource !== "none") return [];
|
|
166
167
|
return ["- channels.discord: default account has no available bot token, and DISCORD_BOT_TOKEN is absent in this doctor environment. After migration, verify DISCORD_BOT_TOKEN is present in the state-dir .env or configure channels.discord.token / channels.discord.accounts.default.token as a SecretRef."];
|
|
167
168
|
}
|
|
169
|
+
function collectDiscordTranscriptsAutoStartWarnings(cfg) {
|
|
170
|
+
if (cfg.transcripts?.enabled === false || !Array.isArray(cfg.transcripts?.autoStart)) return [];
|
|
171
|
+
const ownership = discordVoiceTranscriptsSourceProvider.accessControl;
|
|
172
|
+
if (!ownership) return [];
|
|
173
|
+
return cfg.transcripts.autoStart.flatMap((entry, index) => {
|
|
174
|
+
const providerId = normalizeOptionalString(entry.providerId)?.toLowerCase();
|
|
175
|
+
if (providerId !== discordVoiceTranscriptsSourceProvider.id && !discordVoiceTranscriptsSourceProvider.aliases?.includes(providerId ?? "") || normalizeOptionalString(entry.accountId)) return [];
|
|
176
|
+
const resolution = ownership.resolveAccountId({
|
|
177
|
+
cfg,
|
|
178
|
+
source: entry
|
|
179
|
+
});
|
|
180
|
+
if (resolution.ok) return [];
|
|
181
|
+
const path = `transcripts.autoStart[${index}]`;
|
|
182
|
+
return [`- ${path} cannot select a Discord voice account: ${resolution.error} Set ${path}.accountId to the intended enabled voice account, or set channels.discord.defaultAccount when one account should be the global default.`];
|
|
183
|
+
});
|
|
184
|
+
}
|
|
168
185
|
function collectDiscordMutableAllowlistWarnings(cfg) {
|
|
169
186
|
const hits = [];
|
|
170
187
|
const addHits = (pathLabel, list) => {
|
|
@@ -215,13 +232,17 @@ const discordDoctor = {
|
|
|
215
232
|
warnOnEmptyGroupSenderAllowlist: false,
|
|
216
233
|
legacyConfigRules: DISCORD_LEGACY_CONFIG_RULES,
|
|
217
234
|
normalizeCompatibilityConfig,
|
|
218
|
-
collectPreviewWarnings: ({ cfg, doctorFixCommand, env }) => [
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
235
|
+
collectPreviewWarnings: ({ cfg, doctorFixCommand, env }) => [
|
|
236
|
+
...collectDiscordMissingEnvTokenWarnings({
|
|
237
|
+
cfg,
|
|
238
|
+
env
|
|
239
|
+
}),
|
|
240
|
+
...collectDiscordNumericIdWarnings({
|
|
241
|
+
hits: scanDiscordNumericIdEntries(cfg),
|
|
242
|
+
doctorFixCommand
|
|
243
|
+
}),
|
|
244
|
+
...collectDiscordTranscriptsAutoStartWarnings(cfg)
|
|
245
|
+
],
|
|
225
246
|
collectMutableAllowlistWarnings: ({ cfg }) => collectDiscordMutableAllowlistWarnings(cfg),
|
|
226
247
|
repairConfig: ({ cfg, doctorFixCommand }) => maybeRepairDiscordNumericIds(cfg, doctorFixCommand)
|
|
227
248
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { asObjectRecord, defineChannelAliasMigration, defineKeyMoveMigration, hasLegacyAccountStreamingAliases, normalizeChannelAccounts, stripRetiredChannelKeys } from "openclaw/plugin-sdk/runtime-doctor-migrations";
|
|
2
|
+
import { isSupportedRealtimeVoiceActivationName, normalizeRealtimeVoiceActivationNamePrefix } from "openclaw/plugin-sdk/realtime-voice-activation";
|
|
3
3
|
//#region extensions/discord/src/doctor-contract.ts
|
|
4
4
|
const LEGACY_TTS_PROVIDER_KEYS = [
|
|
5
5
|
"openai",
|
|
@@ -18,7 +18,6 @@ const streamingAliasMigration = defineChannelAliasMigration({
|
|
|
18
18
|
channelId: "discord",
|
|
19
19
|
streaming: {
|
|
20
20
|
defaultMode: "off",
|
|
21
|
-
absentObjectDefault: "progress",
|
|
22
21
|
includePreviewChunk: true
|
|
23
22
|
},
|
|
24
23
|
accountStreamingReplacesRoot: true,
|
|
@@ -1,2 +1,147 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
|
|
1
|
+
import { n as DISCORD_COMMAND_DEPLOY_HASH_NAMESPACE, t as DISCORD_COMMAND_DEPLOY_HASH_MAX_ENTRIES } from "./command-deploy-store-DFkBTViB.js";
|
|
2
|
+
import { a as THREAD_BINDINGS_MAX_ENTRIES, d as normalizePersistedBinding, k as toBindingRecordKey, o as THREAD_BINDINGS_NAMESPACE } from "./thread-bindings.state-D8OMdk4O.js";
|
|
3
|
+
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-DsWvKIXF.js";
|
|
4
|
+
import { i as sanitizeRecentModels, r as preferenceTimestampMs, t as buildPreferenceModelKey } from "./model-picker-preference-primitives-BHT1LkR_.js";
|
|
5
|
+
import { MAX_DATE_TIMESTAMP_MS, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
6
|
+
import { definePluginDoctorMigrationFromPlans } from "openclaw/plugin-sdk/runtime-doctor-migrations";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
//#region extensions/discord/src/monitor/model-picker-preferences-migrations.ts
|
|
10
|
+
const PREFERENCE_MAX_ENTRIES = 2e3;
|
|
11
|
+
const MAX_PLUGIN_STATE_KEY_BYTES = 512;
|
|
12
|
+
const textEncoder = new TextEncoder();
|
|
13
|
+
function fileExists(filePath) {
|
|
14
|
+
try {
|
|
15
|
+
return fs.statSync(filePath).isFile();
|
|
16
|
+
} catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function readLegacyStore(filePath) {
|
|
21
|
+
try {
|
|
22
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
23
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function readLegacyThreadBindingsStore(filePath) {
|
|
29
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
30
|
+
if (!parsed || typeof parsed !== "object") throw new Error("legacy Discord thread bindings store must be an object");
|
|
31
|
+
return parsed;
|
|
32
|
+
}
|
|
33
|
+
function normalizeLegacyPreferenceKey(key) {
|
|
34
|
+
const trimmed = key.trim();
|
|
35
|
+
if (!trimmed || textEncoder.encode(trimmed).length > MAX_PLUGIN_STATE_KEY_BYTES) return;
|
|
36
|
+
return trimmed;
|
|
37
|
+
}
|
|
38
|
+
function legacyUpdatedAtForIndex(updatedAt, index, total) {
|
|
39
|
+
const baseMs = preferenceTimestampMs(updatedAt);
|
|
40
|
+
return timestampMsToIsoString(Math.min(baseMs + Math.max(0, total), MAX_DATE_TIMESTAMP_MS) - Math.max(0, index)) ?? timestampMsToIsoString(baseMs) ?? timestampMsToIsoString(Math.max(0, total - index)) ?? "1970-01-01T00:00:00.000Z";
|
|
41
|
+
}
|
|
42
|
+
function readFiniteNumberField(entry, key) {
|
|
43
|
+
const value = entry[key];
|
|
44
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : void 0;
|
|
45
|
+
}
|
|
46
|
+
function upgradeLegacyThreadBindingShape(rawEntry) {
|
|
47
|
+
if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) return rawEntry;
|
|
48
|
+
const entry = { ...rawEntry };
|
|
49
|
+
if (entry.targetSessionKey === void 0 && typeof entry.sessionKey === "string") entry.targetSessionKey = entry.sessionKey;
|
|
50
|
+
delete entry.sessionKey;
|
|
51
|
+
const expiresAt = readFiniteNumberField(entry, "expiresAt");
|
|
52
|
+
delete entry.expiresAt;
|
|
53
|
+
if (entry.idleTimeoutMs === void 0 && entry.maxAgeMs === void 0 && expiresAt !== void 0) {
|
|
54
|
+
entry.idleTimeoutMs = 0;
|
|
55
|
+
if (expiresAt <= 0) entry.maxAgeMs = 0;
|
|
56
|
+
else {
|
|
57
|
+
const boundAt = readFiniteNumberField(entry, "boundAt") ?? 0;
|
|
58
|
+
const lastActivityAt = readFiniteNumberField(entry, "lastActivityAt") ?? 0;
|
|
59
|
+
entry.maxAgeMs = Math.max(1, expiresAt - Math.max(0, boundAt > 0 ? boundAt : lastActivityAt));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return entry;
|
|
63
|
+
}
|
|
64
|
+
const detectDiscordLegacyStateMigrations = ({ stateDir }) => {
|
|
65
|
+
const plans = [];
|
|
66
|
+
const commandDeployCacheSourcePath = path.join(stateDir, "discord", "command-deploy-cache.json");
|
|
67
|
+
if (fileExists(commandDeployCacheSourcePath)) plans.push({
|
|
68
|
+
kind: "plugin-state-import",
|
|
69
|
+
label: "Discord command deployment cache",
|
|
70
|
+
sourcePath: commandDeployCacheSourcePath,
|
|
71
|
+
targetPath: `plugin state:${DISCORD_COMMAND_DEPLOY_HASH_NAMESPACE}`,
|
|
72
|
+
pluginId: "discord",
|
|
73
|
+
namespace: DISCORD_COMMAND_DEPLOY_HASH_NAMESPACE,
|
|
74
|
+
maxEntries: DISCORD_COMMAND_DEPLOY_HASH_MAX_ENTRIES,
|
|
75
|
+
scopeKey: "",
|
|
76
|
+
cleanupSource: "remove",
|
|
77
|
+
cleanupWhenEmpty: true,
|
|
78
|
+
readEntries: () => []
|
|
79
|
+
});
|
|
80
|
+
const modelPickerSourcePath = path.join(stateDir, "discord", "model-picker-preferences.json");
|
|
81
|
+
if (fileExists(modelPickerSourcePath)) plans.push({
|
|
82
|
+
kind: "plugin-state-import",
|
|
83
|
+
label: "Discord model picker preferences",
|
|
84
|
+
sourcePath: modelPickerSourcePath,
|
|
85
|
+
targetPath: "plugin state:model-picker-preferences",
|
|
86
|
+
pluginId: "discord",
|
|
87
|
+
namespace: "model-picker-preferences",
|
|
88
|
+
maxEntries: PREFERENCE_MAX_ENTRIES,
|
|
89
|
+
scopeKey: "",
|
|
90
|
+
cleanupSource: "rename",
|
|
91
|
+
readEntries: () => {
|
|
92
|
+
const store = readLegacyStore(modelPickerSourcePath);
|
|
93
|
+
if (!store || !store.entries || typeof store.entries !== "object") return [];
|
|
94
|
+
const out = [];
|
|
95
|
+
for (const [rawKey, rawEntry] of Object.entries(store.entries)) {
|
|
96
|
+
const scopeKey = normalizeLegacyPreferenceKey(rawKey);
|
|
97
|
+
if (!scopeKey || !rawEntry || typeof rawEntry !== "object") continue;
|
|
98
|
+
const recent = sanitizeRecentModels(rawEntry.recent, 10);
|
|
99
|
+
for (const [index, modelRef] of recent.entries()) out.push({
|
|
100
|
+
key: buildPreferenceModelKey(scopeKey, modelRef),
|
|
101
|
+
value: {
|
|
102
|
+
scopeKey,
|
|
103
|
+
modelRef,
|
|
104
|
+
updatedAt: legacyUpdatedAtForIndex(rawEntry.updatedAt, index, recent.length)
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
const threadBindingsSourcePath = path.join(stateDir, "discord", "thread-bindings.json");
|
|
112
|
+
if (fileExists(threadBindingsSourcePath)) plans.push({
|
|
113
|
+
kind: "plugin-state-import",
|
|
114
|
+
label: "Discord thread bindings",
|
|
115
|
+
sourcePath: threadBindingsSourcePath,
|
|
116
|
+
targetPath: `plugin state:${THREAD_BINDINGS_NAMESPACE}`,
|
|
117
|
+
pluginId: "discord",
|
|
118
|
+
namespace: THREAD_BINDINGS_NAMESPACE,
|
|
119
|
+
maxEntries: THREAD_BINDINGS_MAX_ENTRIES,
|
|
120
|
+
scopeKey: "",
|
|
121
|
+
cleanupSource: "rename",
|
|
122
|
+
cleanupWhenEmpty: true,
|
|
123
|
+
readEntries: () => {
|
|
124
|
+
const store = readLegacyThreadBindingsStore(threadBindingsSourcePath);
|
|
125
|
+
if (store?.version !== 1 || !store.bindings || typeof store.bindings !== "object") throw new Error("legacy Discord thread bindings store must have version 1 bindings");
|
|
126
|
+
const out = [];
|
|
127
|
+
for (const [rawKey, rawEntry] of Object.entries(store.bindings)) {
|
|
128
|
+
const normalized = normalizePersistedBinding(rawKey, upgradeLegacyThreadBindingShape(rawEntry));
|
|
129
|
+
if (normalized) out.push({
|
|
130
|
+
key: toBindingRecordKey(normalized),
|
|
131
|
+
value: normalized
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
return plans;
|
|
138
|
+
};
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region extensions/discord/doctor-contract-api.ts
|
|
141
|
+
const stateMigrations = [definePluginDoctorMigrationFromPlans({
|
|
142
|
+
id: "discord-legacy-state",
|
|
143
|
+
label: "Discord legacy state",
|
|
144
|
+
resolvePlans: detectDiscordLegacyStateMigrations
|
|
145
|
+
})];
|
|
146
|
+
//#endregion
|
|
147
|
+
export { legacyConfigRules, normalizeCompatibilityConfig, stateMigrations };
|
package/dist/{handle-action.guild-admin-D6VRRW-C.js → handle-action.guild-admin-6Tvvinsa.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as readDiscordChannelMoveParams, n as isDiscordModerationAction, o as readDiscordChannelCreateParams, r as readDiscordModerationCommand, s as readDiscordChannelEditParams, t as handleDiscordAction } from "./runtime-
|
|
1
|
+
import { c as readDiscordChannelMoveParams, n as isDiscordModerationAction, o as readDiscordChannelCreateParams, r as readDiscordModerationCommand, s as readDiscordChannelEditParams, t as handleDiscordAction } from "./runtime-D71_VFLr.js";
|
|
2
2
|
import "./action-runtime-api.js";
|
|
3
|
-
import { n as isTrustedRequesterGuildAdminAction } from "./channel-actions-
|
|
3
|
+
import { n as isTrustedRequesterGuildAdminAction } from "./channel-actions-Dr2QI8Bf.js";
|
|
4
4
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
import { readNonNegativeIntegerParam, readPositiveIntegerParam, readStringArrayParam, readStringParam } from "openclaw/plugin-sdk/agent-runtime";
|
|
6
6
|
//#region extensions/discord/src/actions/handle-action.guild-admin.ts
|
|
@@ -13,7 +13,7 @@ function senderParam(senderUserId) {
|
|
|
13
13
|
return senderUserId ? { senderUserId } : {};
|
|
14
14
|
}
|
|
15
15
|
async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
16
|
-
const { ctx, resolveChannelId, readPolicyOptions } = params;
|
|
16
|
+
const { ctx, resolveChannelId, readPolicyOptions, actionOptions } = params;
|
|
17
17
|
const { action, params: actionParams, cfg } = ctx;
|
|
18
18
|
const accountId = ctx.accountId ?? readStringParam(actionParams, "accountId");
|
|
19
19
|
const senderUserId = readDiscordRequesterSenderId(ctx);
|
|
@@ -284,10 +284,7 @@ async function tryHandleDiscordMessageActionGuildAdmin(params) {
|
|
|
284
284
|
content,
|
|
285
285
|
mediaUrl: mediaUrl ?? void 0,
|
|
286
286
|
replyTo: replyTo ?? void 0
|
|
287
|
-
}, cfg,
|
|
288
|
-
mediaLocalRoots: ctx.mediaLocalRoots,
|
|
289
|
-
mediaReadFile: ctx.mediaReadFile
|
|
290
|
-
});
|
|
287
|
+
}, cfg, actionOptions);
|
|
291
288
|
}
|
|
292
289
|
if (action === "search") {
|
|
293
290
|
const guildId = readStringParam(actionParams, "guildId");
|
|
@@ -1,32 +1,11 @@
|
|
|
1
1
|
import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
|
+
import { createInboundEventDeliveryCorrelation } from "openclaw/plugin-sdk/inbound-event-delivery";
|
|
2
3
|
//#region extensions/discord/src/inbound-event-delivery.ts
|
|
3
4
|
const DISCORD_INBOUND_EVENT_DELIVERY_KEY = "__openclawInboundEventDelivery";
|
|
4
|
-
const registry = /* @__PURE__ */ new Map();
|
|
5
5
|
function normalizeDiscordDeliveryTarget(value) {
|
|
6
6
|
return value.trim().replace(/^discord:/iu, "").replace(/^channel:/iu, "").toLowerCase();
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
const key = sessionKey?.trim();
|
|
10
|
-
if (!key) return;
|
|
11
|
-
return inboundEventKind === "room_event" ? `${key}:room_event` : key;
|
|
12
|
-
}
|
|
13
|
-
function beginDiscordInboundEventDeliveryCorrelation(sessionKey, event, options) {
|
|
14
|
-
const key = resolveDiscordInboundEventDeliveryCorrelationKey(sessionKey, options?.inboundEventKind);
|
|
15
|
-
if (!key) return () => {};
|
|
16
|
-
registry.set(key, event);
|
|
17
|
-
return () => {
|
|
18
|
-
if (registry.get(key) === event) registry.delete(key);
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
function notifyDiscordInboundEventOutboundSuccess(params) {
|
|
22
|
-
const key = resolveDiscordInboundEventDeliveryCorrelationKey(params.sessionKey, params.inboundEventKind);
|
|
23
|
-
if (!key) return;
|
|
24
|
-
const event = registry.get(key);
|
|
25
|
-
if (!event || normalizeDiscordDeliveryTarget(event.outboundTo) !== normalizeDiscordDeliveryTarget(params.to)) return;
|
|
26
|
-
if (event.outboundAccountId && params.accountId && params.accountId !== event.outboundAccountId) return;
|
|
27
|
-
registry.delete(key);
|
|
28
|
-
event.markInboundEventDelivered();
|
|
29
|
-
}
|
|
8
|
+
const discordInboundEventDelivery = createInboundEventDeliveryCorrelation({ targetsMatch: (expected, actual) => normalizeDiscordDeliveryTarget(expected) === normalizeDiscordDeliveryTarget(actual) });
|
|
30
9
|
function withDiscordInboundEventDeliveryMetadata(payload, params) {
|
|
31
10
|
const sessionKey = params.sessionKey?.trim();
|
|
32
11
|
if (!sessionKey || params.inboundEventKind !== "room_event") return payload;
|
|
@@ -49,7 +28,7 @@ function withDiscordInboundEventDeliveryMetadata(payload, params) {
|
|
|
49
28
|
function notifyDiscordInboundEventOutboundPayloadSuccess(params) {
|
|
50
29
|
const metadata = asOptionalRecord(asOptionalRecord(asOptionalRecord(params.payload.channelData)?.discord)?.[DISCORD_INBOUND_EVENT_DELIVERY_KEY]);
|
|
51
30
|
if (!metadata) return;
|
|
52
|
-
|
|
31
|
+
discordInboundEventDelivery.notify({
|
|
53
32
|
sessionKey: normalizeOptionalString(metadata.sessionKey),
|
|
54
33
|
inboundEventKind: normalizeOptionalString(metadata.inboundEventKind),
|
|
55
34
|
to: params.to,
|
|
@@ -57,4 +36,4 @@ function notifyDiscordInboundEventOutboundPayloadSuccess(params) {
|
|
|
57
36
|
});
|
|
58
37
|
}
|
|
59
38
|
//#endregion
|
|
60
|
-
export {
|
|
39
|
+
export { notifyDiscordInboundEventOutboundPayloadSuccess as n, withDiscordInboundEventDeliveryMetadata as r, discordInboundEventDelivery as t };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { t as registerDiscordActivities } from "./activities-api-
|
|
1
|
+
import { t as registerDiscordActivities } from "./activities-api-KCBAmWxD.js";
|
|
2
2
|
import { registerDiscordSubagentHooks } from "./subagent-hooks-api.js";
|
|
3
|
-
import {
|
|
4
|
-
import "./transcripts-source-api.js";
|
|
3
|
+
import { registerDiscordTranscriptSourceProvider } from "./transcripts-source-api.js";
|
|
5
4
|
import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
|
|
6
5
|
//#region extensions/discord/index.ts
|
|
7
6
|
var discord_default = defineBundledChannelEntry({
|
|
@@ -24,7 +23,9 @@ var discord_default = defineBundledChannelEntry({
|
|
|
24
23
|
registerFull(api) {
|
|
25
24
|
registerDiscordActivities(api);
|
|
26
25
|
registerDiscordSubagentHooks(api);
|
|
27
|
-
|
|
26
|
+
},
|
|
27
|
+
registerCapabilities(api) {
|
|
28
|
+
registerDiscordTranscriptSourceProvider(api);
|
|
28
29
|
}
|
|
29
30
|
});
|
|
30
31
|
//#endregion
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { c as resolveDiscordChannelInfoSafe, d as resolveDiscordChannelParentSafe, l as resolveDiscordChannelNameSafe, s as resolveDiscordChannelIdSafe } from "./thread-bindings.manager-CngsgErq.js";
|
|
3
|
+
import { _ as mapGatewayDispatchData } from "./provider-DlK_ynqt.js";
|
|
4
|
+
import { i as resolveDiscordMessageText, l as resolveDiscordCdnPolicy, p as resolveDiscordMessageChannelId, u as hasDiscordMessageStickers } from "./message-utils-BXLLnFl6.js";
|
|
5
|
+
import { logDebug } from "openclaw/plugin-sdk/logging-core";
|
|
6
6
|
import { GatewayDispatchEvents } from "discord-api-types/v10";
|
|
7
|
+
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
8
|
+
import { normalizeNullableString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
9
|
import { danger } from "openclaw/plugin-sdk/runtime-env";
|
|
8
10
|
import { resolveBatchedReplyThreadingPolicy } from "openclaw/plugin-sdk/reply-reference";
|
|
9
|
-
import { createChannelIngressError, createChannelIngressMonitor, createChannelRunQueue } from "openclaw/plugin-sdk/channel-outbound";
|
|
11
|
+
import { DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS, createChannelIngressError, createChannelIngressMonitor, createChannelRunQueue } from "openclaw/plugin-sdk/channel-outbound";
|
|
12
|
+
import { saveRemoteMedia } from "openclaw/plugin-sdk/media-runtime";
|
|
10
13
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
11
14
|
import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
12
15
|
import { fanInChannelIngressLifecycles } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
@@ -43,9 +46,6 @@ function decodeDiscordIngressPayload(payload, claimedId) {
|
|
|
43
46
|
}
|
|
44
47
|
};
|
|
45
48
|
}
|
|
46
|
-
function errorText(error) {
|
|
47
|
-
return error instanceof Error ? error.message : String(error);
|
|
48
|
-
}
|
|
49
49
|
function isDiscordAuthenticationFailure(error) {
|
|
50
50
|
let current = error;
|
|
51
51
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -87,6 +87,10 @@ function createDiscordIngressMonitor(params) {
|
|
|
87
87
|
},
|
|
88
88
|
appendRetryDelaysMs: [0],
|
|
89
89
|
drain: {
|
|
90
|
+
retryPolicy: {
|
|
91
|
+
maxAttempts: DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS,
|
|
92
|
+
deadLetterMinAgeMs: 0
|
|
93
|
+
},
|
|
90
94
|
resolveNonRetryableFailure: (error) => {
|
|
91
95
|
if (error instanceof DiscordIngressPayloadError) return {
|
|
92
96
|
reason: "invalid-event",
|
|
@@ -94,13 +98,13 @@ function createDiscordIngressMonitor(params) {
|
|
|
94
98
|
};
|
|
95
99
|
if (isDiscordAuthenticationFailure(error)) return {
|
|
96
100
|
reason: "authentication-failed",
|
|
97
|
-
message:
|
|
101
|
+
message: formatErrorMessage(error)
|
|
98
102
|
};
|
|
99
103
|
return null;
|
|
100
104
|
},
|
|
101
105
|
onLog: (message) => params.runtime.error?.(danger(`discord ingress: ${message}`))
|
|
102
106
|
},
|
|
103
|
-
onError: (error) => params.runtime.error?.(danger(`discord ingress drain failed: ${
|
|
107
|
+
onError: (error) => params.runtime.error?.(danger(`discord ingress drain failed: ${formatErrorMessage(error)}`))
|
|
104
108
|
});
|
|
105
109
|
return {
|
|
106
110
|
accept: async (rawMessage) => {
|
|
@@ -112,18 +116,10 @@ function createDiscordIngressMonitor(params) {
|
|
|
112
116
|
}
|
|
113
117
|
//#endregion
|
|
114
118
|
//#region extensions/discord/src/monitor/inbound-job.ts
|
|
115
|
-
function resolveDiscordInboundJobQueueKey(ctx) {
|
|
116
|
-
const sessionKey = ctx.route.sessionKey?.trim();
|
|
117
|
-
if (sessionKey) return sessionKey;
|
|
118
|
-
const baseSessionKey = ctx.baseSessionKey?.trim();
|
|
119
|
-
if (baseSessionKey) return baseSessionKey;
|
|
120
|
-
return ctx.messageChannelId;
|
|
121
|
-
}
|
|
122
119
|
function buildDiscordInboundJob(ctx, options) {
|
|
123
120
|
const { runtime, abortSignal, guildHistories, client, turnAdoptionLifecycle, threadBindings, discordRestFetch, message, data, threadChannel, ...payload } = ctx;
|
|
124
121
|
const sanitizedMessage = sanitizeDiscordInboundMessage(message);
|
|
125
122
|
return {
|
|
126
|
-
queueKey: resolveDiscordInboundJobQueueKey(ctx),
|
|
127
123
|
payload: {
|
|
128
124
|
...payload,
|
|
129
125
|
message: sanitizedMessage,
|
|
@@ -173,6 +169,77 @@ function normalizeDiscordThreadChannel(threadChannel) {
|
|
|
173
169
|
};
|
|
174
170
|
}
|
|
175
171
|
//#endregion
|
|
172
|
+
//#region extensions/discord/src/monitor/message-avatar.ts
|
|
173
|
+
const DISCORD_AVATAR_MAX_BYTES = 256 * 1024;
|
|
174
|
+
const DISCORD_AVATAR_CACHE_MAX_ENTRIES = 128;
|
|
175
|
+
const DISCORD_GUILD_ICON_TTL_MS = 5 * 6e4;
|
|
176
|
+
function setBoundedEntry(map, key, value) {
|
|
177
|
+
map.delete(key);
|
|
178
|
+
map.set(key, value);
|
|
179
|
+
while (map.size > DISCORD_AVATAR_CACHE_MAX_ENTRIES) {
|
|
180
|
+
const oldest = map.keys().next().value;
|
|
181
|
+
if (oldest === void 0) break;
|
|
182
|
+
map.delete(oldest);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function discordAvatarUrl(owner, id, hash) {
|
|
186
|
+
return `https://cdn.discordapp.com/${owner}/${id}/${hash}.png?size=128`;
|
|
187
|
+
}
|
|
188
|
+
/** Dispatcher-lifetime resolver for eventually available Discord conversation images. */
|
|
189
|
+
function createDiscordAvatarResolver() {
|
|
190
|
+
const saved = /* @__PURE__ */ new Map();
|
|
191
|
+
const pending = /* @__PURE__ */ new Set();
|
|
192
|
+
const guildIcons = /* @__PURE__ */ new Map();
|
|
193
|
+
const pendingGuilds = /* @__PURE__ */ new Set();
|
|
194
|
+
const resolveSavedAvatar = (key, url) => {
|
|
195
|
+
const cached = saved.get(key);
|
|
196
|
+
if (cached) {
|
|
197
|
+
saved.delete(key);
|
|
198
|
+
saved.set(key, cached);
|
|
199
|
+
return cached;
|
|
200
|
+
}
|
|
201
|
+
if (pending.has(key) || pending.size >= DISCORD_AVATAR_CACHE_MAX_ENTRIES) return;
|
|
202
|
+
pending.add(key);
|
|
203
|
+
saveRemoteMedia({
|
|
204
|
+
url,
|
|
205
|
+
filePathHint: "conversation-avatar.png",
|
|
206
|
+
maxBytes: DISCORD_AVATAR_MAX_BYTES,
|
|
207
|
+
ssrfPolicy: resolveDiscordCdnPolicy()
|
|
208
|
+
}).then((media) => {
|
|
209
|
+
setBoundedEntry(saved, key, media.path);
|
|
210
|
+
}).catch((error) => {
|
|
211
|
+
logDebug(`discord conversation avatar download failed: ${formatErrorMessage(error)}`);
|
|
212
|
+
}).finally(() => {
|
|
213
|
+
pending.delete(key);
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
const refreshGuildIcon = (client, guildId, conversationId) => {
|
|
217
|
+
if (pendingGuilds.has(guildId) || pendingGuilds.size >= DISCORD_AVATAR_CACHE_MAX_ENTRIES) return;
|
|
218
|
+
pendingGuilds.add(guildId);
|
|
219
|
+
client.fetchGuild(guildId).then((guild) => {
|
|
220
|
+
const hash = guild.icon ?? null;
|
|
221
|
+
setBoundedEntry(guildIcons, guildId, {
|
|
222
|
+
expiresAt: Date.now() + DISCORD_GUILD_ICON_TTL_MS,
|
|
223
|
+
hash
|
|
224
|
+
});
|
|
225
|
+
if (hash) resolveSavedAvatar(`${conversationId}\0${hash}`, discordAvatarUrl("icons", guildId, hash));
|
|
226
|
+
}).catch((error) => {
|
|
227
|
+
logDebug(`discord guild icon lookup failed: ${formatErrorMessage(error)}`);
|
|
228
|
+
}).finally(() => {
|
|
229
|
+
pendingGuilds.delete(guildId);
|
|
230
|
+
});
|
|
231
|
+
};
|
|
232
|
+
return { resolve(params) {
|
|
233
|
+
if (!params.guildId) {
|
|
234
|
+
const hash = params.author.avatar;
|
|
235
|
+
return hash ? resolveSavedAvatar(`${params.conversationId}\0${hash}`, discordAvatarUrl("avatars", params.author.id, hash)) : void 0;
|
|
236
|
+
}
|
|
237
|
+
const guildIcon = guildIcons.get(params.guildId);
|
|
238
|
+
if (!guildIcon || guildIcon.expiresAt <= Date.now()) refreshGuildIcon(params.client, params.guildId, params.conversationId);
|
|
239
|
+
return guildIcon?.hash ? resolveSavedAvatar(`${params.conversationId}\0${guildIcon.hash}`, discordAvatarUrl("icons", params.guildId, guildIcon.hash)) : void 0;
|
|
240
|
+
} };
|
|
241
|
+
}
|
|
242
|
+
//#endregion
|
|
176
243
|
//#region extensions/discord/src/monitor/message-handler.batch-gate.ts
|
|
177
244
|
function applyImplicitReplyBatchGate(ctx, replyToMode, isBatched) {
|
|
178
245
|
const replyThreading = resolveBatchedReplyThreadingPolicy(replyToMode, isBatched);
|
|
@@ -181,20 +248,21 @@ function applyImplicitReplyBatchGate(ctx, replyToMode, isBatched) {
|
|
|
181
248
|
}
|
|
182
249
|
//#endregion
|
|
183
250
|
//#region extensions/discord/src/monitor/message-run-queue.ts
|
|
184
|
-
const loadMessageProcessRuntime = createLazyRuntimeModule(() => import("./message-handler.process
|
|
251
|
+
const loadMessageProcessRuntime = createLazyRuntimeModule(() => import("./message-handler.process--4_712Ec.js"));
|
|
185
252
|
async function processDiscordQueuedMessage(params) {
|
|
186
253
|
const abortSignal = params.job.runtime.abortSignal && params.lifecycleSignal ? AbortSignal.any([params.job.runtime.abortSignal, params.lifecycleSignal]) : params.job.runtime.abortSignal ?? params.lifecycleSignal;
|
|
187
254
|
try {
|
|
188
255
|
await (params.testing?.processDiscordMessage ?? (await loadMessageProcessRuntime()).processDiscordMessage)(materializeDiscordInboundJob(params.job, abortSignal));
|
|
189
|
-
if (abortSignal?.aborted) await params.job.ingressSettlement?.
|
|
256
|
+
if (abortSignal?.aborted) await params.job.ingressSettlement?.cancel();
|
|
190
257
|
else await params.job.ingressSettlement?.settle();
|
|
191
258
|
} catch (error) {
|
|
192
|
-
await params.job.ingressSettlement?.
|
|
259
|
+
if (abortSignal?.aborted) await params.job.ingressSettlement?.cancel();
|
|
260
|
+
else await params.job.ingressSettlement?.abandon(error);
|
|
193
261
|
throw error;
|
|
194
262
|
}
|
|
195
263
|
}
|
|
196
264
|
async function cleanupSkippedDiscordQueuedMessage(params) {
|
|
197
|
-
await params.job.ingressSettlement?.
|
|
265
|
+
await params.job.ingressSettlement?.cancel();
|
|
198
266
|
}
|
|
199
267
|
function createDiscordMessageRunQueue(params) {
|
|
200
268
|
const skippedCleanup = /* @__PURE__ */ new Set();
|
|
@@ -232,6 +300,10 @@ function createDiscordMessageRunQueue(params) {
|
|
|
232
300
|
const cleanupSkipped = async () => {
|
|
233
301
|
try {
|
|
234
302
|
await cleanupSkippedDiscordQueuedMessage({ job });
|
|
303
|
+
} catch (error) {
|
|
304
|
+
try {
|
|
305
|
+
params.runtime.error(danger(`discord queued message cleanup failed: ${String(error)}`));
|
|
306
|
+
} catch {}
|
|
235
307
|
} finally {
|
|
236
308
|
settlePending();
|
|
237
309
|
}
|
|
@@ -241,7 +313,7 @@ function createDiscordMessageRunQueue(params) {
|
|
|
241
313
|
return;
|
|
242
314
|
}
|
|
243
315
|
skippedCleanup.add(cleanupSkipped);
|
|
244
|
-
runQueue.enqueue(job.
|
|
316
|
+
runQueue.enqueue(job.payload.message.id, async ({ lifecycleSignal }) => {
|
|
245
317
|
skippedCleanup.delete(cleanupSkipped);
|
|
246
318
|
try {
|
|
247
319
|
await processDiscordQueuedMessage({
|
|
@@ -263,7 +335,7 @@ function createDiscordMessageRunQueue(params) {
|
|
|
263
335
|
}
|
|
264
336
|
//#endregion
|
|
265
337
|
//#region extensions/discord/src/monitor/message-dispatcher.ts
|
|
266
|
-
const loadMessagePreflightRuntime = createLazyRuntimeModule(() => import("./message-handler.preflight-
|
|
338
|
+
const loadMessagePreflightRuntime = createLazyRuntimeModule(() => import("./message-handler.preflight-Bzg_Hawz.js"));
|
|
267
339
|
function isNonEmptyString(value) {
|
|
268
340
|
return typeof value === "string" && value.length > 0;
|
|
269
341
|
}
|
|
@@ -282,6 +354,7 @@ function createDiscordMessageDispatcher(params) {
|
|
|
282
354
|
testing: params.testing
|
|
283
355
|
});
|
|
284
356
|
const dispatcherShutdown = new AbortController();
|
|
357
|
+
const avatarResolver = createDiscordAvatarResolver();
|
|
285
358
|
const pendingDebounceEntries = /* @__PURE__ */ new Set();
|
|
286
359
|
const pendingCancellationSettlements = /* @__PURE__ */ new Set();
|
|
287
360
|
const resolveDebounceKey = (entry) => {
|
|
@@ -317,13 +390,14 @@ function createDiscordMessageDispatcher(params) {
|
|
|
317
390
|
if (!last) return;
|
|
318
391
|
const abortSignal = last.abortSignal;
|
|
319
392
|
if (abortSignal?.aborted) {
|
|
320
|
-
await
|
|
393
|
+
await ingress.cancel();
|
|
321
394
|
return;
|
|
322
395
|
}
|
|
323
396
|
try {
|
|
324
397
|
if (entries.length === 1) {
|
|
325
398
|
const ctx = await (preflightDiscordMessageImpl ?? (await loadMessagePreflightRuntime()).preflightDiscordMessage)({
|
|
326
399
|
...params,
|
|
400
|
+
avatarResolver,
|
|
327
401
|
ackReactionScope,
|
|
328
402
|
groupPolicy,
|
|
329
403
|
abortSignal,
|
|
@@ -332,7 +406,7 @@ function createDiscordMessageDispatcher(params) {
|
|
|
332
406
|
turnAdoptionLifecycle: admissionLifecycle
|
|
333
407
|
});
|
|
334
408
|
if (abortSignal?.aborted) {
|
|
335
|
-
await ingress.
|
|
409
|
+
await ingress.cancel();
|
|
336
410
|
return;
|
|
337
411
|
}
|
|
338
412
|
if (!ctx) {
|
|
@@ -378,6 +452,7 @@ function createDiscordMessageDispatcher(params) {
|
|
|
378
452
|
};
|
|
379
453
|
const ctx = await (preflightDiscordMessageImpl ?? (await loadMessagePreflightRuntime()).preflightDiscordMessage)({
|
|
380
454
|
...params,
|
|
455
|
+
avatarResolver,
|
|
381
456
|
ackReactionScope,
|
|
382
457
|
groupPolicy,
|
|
383
458
|
abortSignal,
|
|
@@ -386,7 +461,7 @@ function createDiscordMessageDispatcher(params) {
|
|
|
386
461
|
turnAdoptionLifecycle: admissionLifecycle
|
|
387
462
|
});
|
|
388
463
|
if (abortSignal?.aborted) {
|
|
389
|
-
await ingress.
|
|
464
|
+
await ingress.cancel();
|
|
390
465
|
return;
|
|
391
466
|
}
|
|
392
467
|
if (!ctx) {
|
|
@@ -403,7 +478,10 @@ function createDiscordMessageDispatcher(params) {
|
|
|
403
478
|
}
|
|
404
479
|
messageRunQueue.enqueue(buildDiscordInboundJob(ctx, { ingressSettlement: ingress }));
|
|
405
480
|
} catch (error) {
|
|
406
|
-
|
|
481
|
+
if (abortSignal?.aborted) {
|
|
482
|
+
await ingress.cancel();
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
407
485
|
throw error;
|
|
408
486
|
}
|
|
409
487
|
}
|
|
@@ -415,7 +493,7 @@ function createDiscordMessageDispatcher(params) {
|
|
|
415
493
|
onCancel: (entries) => {
|
|
416
494
|
for (const entry of entries) {
|
|
417
495
|
pendingDebounceEntries.delete(entry);
|
|
418
|
-
const settlement =
|
|
496
|
+
const settlement = fanInChannelIngressLifecycles([entry.turnAdoptionLifecycle]).cancel().catch((error) => {
|
|
419
497
|
params.runtime.error(danger(`discord ingress cancellation settlement failed: ${String(error)}`));
|
|
420
498
|
}).finally(() => {
|
|
421
499
|
pendingCancellationSettlements.delete(settlement);
|
|
@@ -426,10 +504,17 @@ function createDiscordMessageDispatcher(params) {
|
|
|
426
504
|
});
|
|
427
505
|
const dispatchMessage = async (data, client, options) => {
|
|
428
506
|
try {
|
|
429
|
-
if (dispatcherShutdown.signal.aborted || options?.abortSignal?.aborted)
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
507
|
+
if (dispatcherShutdown.signal.aborted || options?.abortSignal?.aborted) {
|
|
508
|
+
const reason = dispatcherShutdown.signal.aborted ? dispatcherShutdown.signal.reason ?? /* @__PURE__ */ new Error("discord dispatcher shut down") : options?.abortSignal?.reason ?? /* @__PURE__ */ new Error("discord dispatch aborted");
|
|
509
|
+
if (options?.turnAdoptionLifecycle) {
|
|
510
|
+
await fanInChannelIngressLifecycles([options.turnAdoptionLifecycle]).cancel();
|
|
511
|
+
return { kind: "deferred" };
|
|
512
|
+
}
|
|
513
|
+
return {
|
|
514
|
+
kind: "failed-retryable",
|
|
515
|
+
error: reason
|
|
516
|
+
};
|
|
517
|
+
}
|
|
433
518
|
const msgAuthorId = data.message?.author?.id ?? data.author?.id;
|
|
434
519
|
if (params.botUserId && msgAuthorId === params.botUserId) return { kind: "completed" };
|
|
435
520
|
const entry = {
|