@kodelyth/discord 2026.5.39 → 2026.6.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-inspect-Dqw-enky.js +81 -0
- package/dist/account-inspect-api.js +10 -0
- package/dist/accounts-B7OBFePq.js +224 -0
- package/dist/action-runtime-api.js +2 -0
- package/dist/agent-components.runtime-DVY_1VB4.js +4 -0
- package/dist/allow-list-B0s7evD7.js +354 -0
- package/dist/api-CXAcv9nZ.js +130 -0
- package/dist/api.js +23 -0
- package/dist/approval-handler.runtime-B9xUAF3n.js +426 -0
- package/dist/audit-DoiK49WO.js +24 -0
- package/dist/audit-core-BGrq3G7r.js +105 -0
- package/dist/channel-U_aeoFwW.js +795 -0
- package/dist/channel-actions-BxEBnEuv.js +173 -0
- package/dist/channel-actions.runtime-CPtpH-yl.js +263 -0
- package/dist/channel-api-BfjklLby.js +21 -0
- package/dist/channel-config-api.js +2 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel.setup-BUSC0apv.js +337 -0
- package/dist/components-luonoe13.js +909 -0
- package/dist/config-api-DSYGqaLQ.js +2 -0
- package/dist/config-schema-DIqJBGwC.js +357 -0
- package/dist/configured-state.js +6 -0
- package/dist/contract-api.js +8 -0
- package/dist/conversation-identity-DXAm0_Mk.js +270 -0
- package/dist/directory-config-CYbuMmPS.js +49 -0
- package/dist/directory-contract-api.js +2 -0
- package/dist/directory-live-DX4dLRpJ.js +159 -0
- package/dist/doctor-bbKSvGVD.js +244 -0
- package/dist/doctor-contract-Btjt6NJD.js +383 -0
- package/dist/doctor-contract-api.js +2 -0
- package/dist/gateway-registry-BKSpa4GB.js +74 -0
- package/dist/handle-action.guild-admin-B5BArS2n.js +286 -0
- package/dist/inbound-context-WAOqhGlT.js +48 -0
- package/dist/inbound-event-delivery-C-1Ji3WP.js +65 -0
- package/dist/index.js +26 -0
- package/dist/manager.runtime-DXHynKE4.js +2356 -0
- package/dist/message-handler-mXzc3tA_.js +381 -0
- package/dist/message-handler.preflight-BPD1a347.js +1113 -0
- package/dist/message-handler.process-GUa3aV8z.js +1438 -0
- package/dist/message-utils-dUbem16p.js +549 -0
- package/dist/outbound-adapter-C18OAc1y.js +536 -0
- package/dist/pluralkit-D1Q2x0w5.js +22 -0
- package/dist/preflight-audio-CZtpWcIm.js +72 -0
- package/dist/preflight-audio.runtime-Brx_0_xW.js +7 -0
- package/dist/preview-streaming-D_slNIiO.js +8 -0
- package/dist/probe-D--Ca4JF.js +139 -0
- package/dist/probe.runtime-DQBchZzv.js +2 -0
- package/dist/provider-B2-31CIT.js +9565 -0
- package/dist/provider-session.runtime-BwzzSsrH.js +6 -0
- package/dist/provider.runtime-CP3oHLls.js +2 -0
- package/dist/resolve-allowlist-common-CqxPLcJO.js +34 -0
- package/dist/resolve-channels-0LX4pUbB.js +265 -0
- package/dist/resolve-users-CztOv0Qs.js +120 -0
- package/dist/runtime-DUaw66V_.js +1073 -0
- package/dist/runtime-api.actions.js +3 -0
- package/dist/runtime-api.js +30 -0
- package/dist/runtime-api.lookup.js +7 -0
- package/dist/runtime-api.monitor-CvVKvEXW.js +5 -0
- package/dist/runtime-api.monitor.js +8 -0
- package/dist/runtime-api.send.js +6 -0
- package/dist/runtime-api.threads.js +6 -0
- package/dist/runtime-fC6f4UF2.js +8 -0
- package/dist/runtime-setter-api.js +2 -0
- package/dist/secret-config-contract-B6WW5V88.js +115 -0
- package/dist/secret-contract-api.js +2 -0
- package/dist/security-audit-CnyIQKz6.js +120 -0
- package/dist/security-audit-contract-api.js +2 -0
- package/dist/security-audit.runtime-CQSkjNLu.js +2 -0
- package/dist/security-contract-DLvYOgLM.js +26 -0
- package/dist/security-contract-api.js +2 -0
- package/dist/security-doctor-DepqtNCI.js +18 -0
- package/dist/send-DCtPCHGk.js +881 -0
- package/dist/send.components-Bcgxvm52.js +474 -0
- package/dist/send.outbound-S9t0UuHc.js +330 -0
- package/dist/send.receipt-CDn3GBWC.js +3119 -0
- package/dist/send.shared-D4iBnAmn.js +669 -0
- package/dist/sender-identity-CxCe3_1a.js +43 -0
- package/dist/session-contract-Dwhw3RTY.js +6 -0
- package/dist/session-key-api.js +2 -0
- package/dist/session-key-normalization-CP8dPUid.js +23 -0
- package/dist/setup-entry.js +11 -0
- package/dist/setup-plugin-api.js +2 -0
- package/dist/shared-AIlvuZXt.js +171 -0
- package/dist/subagent-hooks-8bK-mgiU.js +120 -0
- package/dist/subagent-hooks-api.js +22 -0
- package/dist/system-events-Ba1TklaL.js +34 -0
- package/dist/target-resolver-BrtFQtoK.js +82 -0
- package/dist/targets-DWLLZE2l.js +3 -0
- package/dist/test-api.js +45 -0
- package/dist/thread-binding-api.js +4 -0
- package/dist/thread-bindings-9aKRmZv0.js +255 -0
- package/dist/thread-bindings.discord-api-ssGH5wc2.js +244 -0
- package/dist/thread-bindings.manager-0YBHGemk.js +534 -0
- package/dist/thread-bindings.session-updates-DJZGIwaU.js +54 -0
- package/dist/thread-bindings.state-eTFl-PqJ.js +318 -0
- package/dist/timeouts-CEwuGaWT.js +52 -0
- package/dist/timeouts.js +2 -0
- package/dist/typing-BmJKRpCS.js +14 -0
- package/package.json +19 -7
- package/account-inspect-api.js +0 -7
- package/action-runtime-api.js +0 -7
- package/api.js +0 -7
- package/channel-config-api.js +0 -7
- package/channel-plugin-api.js +0 -7
- package/configured-state.js +0 -7
- package/contract-api.js +0 -7
- package/directory-contract-api.js +0 -7
- package/doctor-contract-api.js +0 -7
- package/index.js +0 -7
- package/runtime-api.actions.js +0 -7
- package/runtime-api.js +0 -7
- package/runtime-api.lookup.js +0 -7
- package/runtime-api.monitor.js +0 -7
- package/runtime-api.send.js +0 -7
- package/runtime-api.threads.js +0 -7
- package/runtime-setter-api.js +0 -7
- package/secret-contract-api.js +0 -7
- package/security-audit-contract-api.js +0 -7
- package/security-contract-api.js +0 -7
- package/session-key-api.js +0 -7
- package/setup-entry.js +0 -7
- package/setup-plugin-api.js +0 -7
- package/subagent-hooks-api.js +0 -7
- package/test-api.js +0 -7
- package/thread-binding-api.js +0 -7
- package/timeouts.js +0 -7
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { N as createDiscordRestClient } from "./send.shared-D4iBnAmn.js";
|
|
2
|
+
import { d as resolveDiscordChannelNameSafe, l as resolveDiscordChannelIdSafe, p as resolveDiscordChannelParentSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-ssGH5wc2.js";
|
|
3
|
+
import { a as mergeAbortSignals } from "./timeouts-CEwuGaWT.js";
|
|
4
|
+
import { c as hasDiscordMessageStickers, d as resolveDiscordMessageChannelId, r as resolveDiscordMessageText } from "./message-utils-dUbem16p.js";
|
|
5
|
+
import { t as sendTyping } from "./typing-BmJKRpCS.js";
|
|
6
|
+
import { danger, logVerbose } from "klaw/plugin-sdk/runtime-env";
|
|
7
|
+
import { resolveOpenProviderRuntimeGroupPolicy } from "klaw/plugin-sdk/runtime-group-policy";
|
|
8
|
+
import { resolveBatchedReplyThreadingPolicy } from "klaw/plugin-sdk/reply-reference";
|
|
9
|
+
import { createChannelInboundDebouncer, shouldDebounceTextInbound } from "klaw/plugin-sdk/channel-inbound";
|
|
10
|
+
import { createClaimableDedupe } from "klaw/plugin-sdk/persistent-dedupe";
|
|
11
|
+
import { createChannelRunQueue } from "klaw/plugin-sdk/channel-lifecycle";
|
|
12
|
+
//#region extensions/discord/src/monitor/inbound-dedupe.ts
|
|
13
|
+
const RECENT_DISCORD_MESSAGE_TTL_MS = 5 * 6e4;
|
|
14
|
+
const RECENT_DISCORD_MESSAGE_MAX = 5e3;
|
|
15
|
+
function createDiscordInboundReplayGuard() {
|
|
16
|
+
return createClaimableDedupe({
|
|
17
|
+
ttlMs: RECENT_DISCORD_MESSAGE_TTL_MS,
|
|
18
|
+
memoryMaxSize: RECENT_DISCORD_MESSAGE_MAX
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
var DiscordRetryableInboundError = class extends Error {
|
|
22
|
+
constructor(message, options) {
|
|
23
|
+
super(message, options);
|
|
24
|
+
this.name = "DiscordRetryableInboundError";
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
function buildDiscordInboundReplayKey(params) {
|
|
28
|
+
const messageId = params.data.message?.id?.trim();
|
|
29
|
+
if (!messageId) return null;
|
|
30
|
+
const channelId = resolveDiscordMessageChannelId({
|
|
31
|
+
message: params.data.message,
|
|
32
|
+
eventChannelId: params.data.channel_id
|
|
33
|
+
});
|
|
34
|
+
if (!channelId) return null;
|
|
35
|
+
return `${params.accountId}:${channelId}:${messageId}`;
|
|
36
|
+
}
|
|
37
|
+
async function claimDiscordInboundReplay(params) {
|
|
38
|
+
const replayKey = params.replayKey?.trim();
|
|
39
|
+
if (!replayKey) return true;
|
|
40
|
+
return (await params.replayGuard.claim(replayKey)).kind === "claimed";
|
|
41
|
+
}
|
|
42
|
+
async function commitDiscordInboundReplay(params) {
|
|
43
|
+
const replayKeys = normalizeDiscordInboundReplayKeys(params.replayKeys);
|
|
44
|
+
await Promise.all(replayKeys.map((replayKey) => params.replayGuard.commit(replayKey)));
|
|
45
|
+
}
|
|
46
|
+
function releaseDiscordInboundReplay(params) {
|
|
47
|
+
normalizeDiscordInboundReplayKeys(params.replayKeys).forEach((replayKey) => params.replayGuard.release(replayKey, { error: params.error }));
|
|
48
|
+
}
|
|
49
|
+
function normalizeDiscordInboundReplayKeys(replayKeys) {
|
|
50
|
+
return [...new Set((replayKeys ?? []).map((replayKey) => replayKey?.trim()).filter((replayKey) => Boolean(replayKey)))];
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region extensions/discord/src/monitor/inbound-job.ts
|
|
54
|
+
function resolveDiscordInboundJobQueueKey(ctx) {
|
|
55
|
+
const sessionKey = ctx.route.sessionKey?.trim();
|
|
56
|
+
if (sessionKey) return sessionKey;
|
|
57
|
+
const baseSessionKey = ctx.baseSessionKey?.trim();
|
|
58
|
+
if (baseSessionKey) return baseSessionKey;
|
|
59
|
+
return ctx.messageChannelId;
|
|
60
|
+
}
|
|
61
|
+
function buildDiscordInboundJob(ctx, options) {
|
|
62
|
+
const { runtime, abortSignal, guildHistories, client, threadBindings, discordRestFetch, message, data, threadChannel, ...payload } = ctx;
|
|
63
|
+
const sanitizedMessage = sanitizeDiscordInboundMessage(message);
|
|
64
|
+
return {
|
|
65
|
+
queueKey: resolveDiscordInboundJobQueueKey(ctx),
|
|
66
|
+
payload: {
|
|
67
|
+
...payload,
|
|
68
|
+
message: sanitizedMessage,
|
|
69
|
+
data: {
|
|
70
|
+
...data,
|
|
71
|
+
message: sanitizedMessage
|
|
72
|
+
},
|
|
73
|
+
threadChannel: normalizeDiscordThreadChannel(threadChannel)
|
|
74
|
+
},
|
|
75
|
+
runtime: {
|
|
76
|
+
runtime,
|
|
77
|
+
abortSignal,
|
|
78
|
+
guildHistories,
|
|
79
|
+
client,
|
|
80
|
+
threadBindings,
|
|
81
|
+
discordRestFetch
|
|
82
|
+
},
|
|
83
|
+
replayKeys: options?.replayKeys ? [...options.replayKeys] : void 0
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function materializeDiscordInboundJob(job, abortSignal) {
|
|
87
|
+
return {
|
|
88
|
+
...job.payload,
|
|
89
|
+
...job.runtime,
|
|
90
|
+
abortSignal: abortSignal ?? job.runtime.abortSignal
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function sanitizeDiscordInboundMessage(message) {
|
|
94
|
+
const descriptors = Object.getOwnPropertyDescriptors(message);
|
|
95
|
+
delete descriptors.channel;
|
|
96
|
+
return Object.create(Object.getPrototypeOf(message), descriptors);
|
|
97
|
+
}
|
|
98
|
+
function normalizeDiscordThreadChannel(threadChannel) {
|
|
99
|
+
if (!threadChannel) return null;
|
|
100
|
+
const channelInfo = resolveDiscordChannelInfoSafe(threadChannel);
|
|
101
|
+
const parent = resolveDiscordChannelParentSafe(threadChannel);
|
|
102
|
+
return {
|
|
103
|
+
id: threadChannel.id,
|
|
104
|
+
name: channelInfo.name,
|
|
105
|
+
parentId: channelInfo.parentId,
|
|
106
|
+
parent: parent ? {
|
|
107
|
+
id: resolveDiscordChannelIdSafe(parent),
|
|
108
|
+
name: resolveDiscordChannelNameSafe(parent)
|
|
109
|
+
} : void 0,
|
|
110
|
+
ownerId: channelInfo.ownerId
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region extensions/discord/src/monitor/message-handler.batch-gate.ts
|
|
115
|
+
function applyImplicitReplyBatchGate(ctx, replyToMode, isBatched) {
|
|
116
|
+
const replyThreading = resolveBatchedReplyThreadingPolicy(replyToMode, isBatched);
|
|
117
|
+
if (!replyThreading) return;
|
|
118
|
+
ctx.ReplyThreading = replyThreading;
|
|
119
|
+
}
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region extensions/discord/src/monitor/message-run-queue.ts
|
|
122
|
+
let messageProcessRuntimePromise;
|
|
123
|
+
async function loadMessageProcessRuntime() {
|
|
124
|
+
messageProcessRuntimePromise ??= import("./message-handler.process-GUa3aV8z.js");
|
|
125
|
+
return await messageProcessRuntimePromise;
|
|
126
|
+
}
|
|
127
|
+
async function processDiscordQueuedMessage(params) {
|
|
128
|
+
const processDiscordMessageImpl = params.testing?.processDiscordMessage ?? (await loadMessageProcessRuntime()).processDiscordMessage;
|
|
129
|
+
const abortSignal = mergeAbortSignals([params.job.runtime.abortSignal, params.lifecycleSignal]);
|
|
130
|
+
try {
|
|
131
|
+
await processDiscordMessageImpl(materializeDiscordInboundJob(params.job, abortSignal));
|
|
132
|
+
await commitDiscordInboundReplay({
|
|
133
|
+
replayKeys: params.job.replayKeys,
|
|
134
|
+
replayGuard: params.replayGuard
|
|
135
|
+
});
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (error instanceof DiscordRetryableInboundError) releaseDiscordInboundReplay({
|
|
138
|
+
replayKeys: params.job.replayKeys,
|
|
139
|
+
error,
|
|
140
|
+
replayGuard: params.replayGuard
|
|
141
|
+
});
|
|
142
|
+
else await commitDiscordInboundReplay({
|
|
143
|
+
replayKeys: params.job.replayKeys,
|
|
144
|
+
replayGuard: params.replayGuard
|
|
145
|
+
});
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function createDiscordMessageRunQueue(params) {
|
|
150
|
+
const replayGuard = params.replayGuard ?? createDiscordInboundReplayGuard();
|
|
151
|
+
const runQueue = createChannelRunQueue({
|
|
152
|
+
setStatus: params.setStatus,
|
|
153
|
+
abortSignal: params.abortSignal,
|
|
154
|
+
onError: (error) => {
|
|
155
|
+
params.runtime.error?.(danger(`discord message run failed: ${String(error)}`));
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
enqueue(job) {
|
|
160
|
+
runQueue.enqueue(job.queueKey, async ({ lifecycleSignal }) => {
|
|
161
|
+
await processDiscordQueuedMessage({
|
|
162
|
+
job,
|
|
163
|
+
lifecycleSignal,
|
|
164
|
+
replayGuard,
|
|
165
|
+
testing: params.testing
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
},
|
|
169
|
+
deactivate: runQueue.deactivate
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
//#endregion
|
|
173
|
+
//#region extensions/discord/src/monitor/message-handler.ts
|
|
174
|
+
let messagePreflightRuntimePromise;
|
|
175
|
+
async function loadMessagePreflightRuntime() {
|
|
176
|
+
messagePreflightRuntimePromise ??= import("./message-handler.preflight-BPD1a347.js");
|
|
177
|
+
return await messagePreflightRuntimePromise;
|
|
178
|
+
}
|
|
179
|
+
function isNonEmptyString(value) {
|
|
180
|
+
return typeof value === "string" && value.length > 0;
|
|
181
|
+
}
|
|
182
|
+
function shouldSendAcceptedDiscordTypingCue(ctx) {
|
|
183
|
+
if (ctx.abortSignal?.aborted) return false;
|
|
184
|
+
if (!ctx.isDirectMessage || ctx.isGuildMessage || ctx.isGroupDm) return false;
|
|
185
|
+
if (!ctx.messageText.trim()) return false;
|
|
186
|
+
const configuredTypingMode = ctx.cfg.session?.typingMode ?? ctx.cfg.agents?.defaults?.typingMode;
|
|
187
|
+
return configuredTypingMode === void 0 || configuredTypingMode === "instant";
|
|
188
|
+
}
|
|
189
|
+
function queueAcceptedDiscordTypingCue(ctx) {
|
|
190
|
+
if (!shouldSendAcceptedDiscordTypingCue(ctx)) return;
|
|
191
|
+
const { rest } = createDiscordRestClient({
|
|
192
|
+
cfg: ctx.cfg,
|
|
193
|
+
token: ctx.token,
|
|
194
|
+
accountId: ctx.accountId
|
|
195
|
+
});
|
|
196
|
+
sendTyping({
|
|
197
|
+
rest,
|
|
198
|
+
channelId: ctx.messageChannelId
|
|
199
|
+
}).catch((err) => {
|
|
200
|
+
logVerbose(`discord early typing cue failed for channel ${ctx.messageChannelId}: ${String(err)}`);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
function createDiscordMessageHandler(params) {
|
|
204
|
+
const { groupPolicy } = resolveOpenProviderRuntimeGroupPolicy({
|
|
205
|
+
providerConfigPresent: params.cfg.channels?.discord !== void 0,
|
|
206
|
+
groupPolicy: params.discordConfig?.groupPolicy,
|
|
207
|
+
defaultGroupPolicy: params.cfg.channels?.defaults?.groupPolicy
|
|
208
|
+
});
|
|
209
|
+
const ackReactionScope = params.discordConfig?.ackReactionScope ?? params.cfg.messages?.ackReactionScope ?? "group-mentions";
|
|
210
|
+
const preflightDiscordMessageImpl = params.testing?.preflightDiscordMessage;
|
|
211
|
+
const replayGuard = createDiscordInboundReplayGuard();
|
|
212
|
+
const messageRunQueue = createDiscordMessageRunQueue({
|
|
213
|
+
runtime: params.runtime,
|
|
214
|
+
setStatus: params.setStatus,
|
|
215
|
+
abortSignal: params.abortSignal,
|
|
216
|
+
replayGuard,
|
|
217
|
+
testing: params.testing
|
|
218
|
+
});
|
|
219
|
+
const { debouncer } = createChannelInboundDebouncer({
|
|
220
|
+
cfg: params.cfg,
|
|
221
|
+
channel: "discord",
|
|
222
|
+
buildKey: (entry) => {
|
|
223
|
+
const message = entry.data.message;
|
|
224
|
+
const authorId = entry.data.author?.id;
|
|
225
|
+
if (!message || !authorId) return null;
|
|
226
|
+
const channelId = resolveDiscordMessageChannelId({
|
|
227
|
+
message,
|
|
228
|
+
eventChannelId: entry.data.channel_id
|
|
229
|
+
});
|
|
230
|
+
if (!channelId) return null;
|
|
231
|
+
return `discord:${params.accountId}:${channelId}:${authorId}`;
|
|
232
|
+
},
|
|
233
|
+
shouldDebounce: (entry) => {
|
|
234
|
+
const message = entry.data.message;
|
|
235
|
+
if (!message) return false;
|
|
236
|
+
return shouldDebounceTextInbound({
|
|
237
|
+
text: resolveDiscordMessageText(message, { includeForwarded: false }),
|
|
238
|
+
cfg: params.cfg,
|
|
239
|
+
hasMedia: message.attachments && message.attachments.length > 0 || hasDiscordMessageStickers(message)
|
|
240
|
+
});
|
|
241
|
+
},
|
|
242
|
+
onFlush: async (entries) => {
|
|
243
|
+
const last = entries.at(-1);
|
|
244
|
+
if (!last) return;
|
|
245
|
+
const replayKeys = entries.map((entry) => entry.replayKey).filter(isNonEmptyString);
|
|
246
|
+
const abortSignal = last.abortSignal;
|
|
247
|
+
if (abortSignal?.aborted) {
|
|
248
|
+
releaseDiscordInboundReplay({
|
|
249
|
+
replayKeys,
|
|
250
|
+
error: abortSignal.reason,
|
|
251
|
+
replayGuard
|
|
252
|
+
});
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
try {
|
|
256
|
+
if (entries.length === 1) {
|
|
257
|
+
const ctx = await (preflightDiscordMessageImpl ?? (await loadMessagePreflightRuntime()).preflightDiscordMessage)({
|
|
258
|
+
...params,
|
|
259
|
+
ackReactionScope,
|
|
260
|
+
groupPolicy,
|
|
261
|
+
abortSignal,
|
|
262
|
+
data: last.data,
|
|
263
|
+
client: last.client
|
|
264
|
+
});
|
|
265
|
+
if (!ctx) {
|
|
266
|
+
await commitDiscordInboundReplay({
|
|
267
|
+
replayKeys,
|
|
268
|
+
replayGuard
|
|
269
|
+
});
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
applyImplicitReplyBatchGate(ctx, params.replyToMode, false);
|
|
273
|
+
queueAcceptedDiscordTypingCue(ctx);
|
|
274
|
+
messageRunQueue.enqueue(buildDiscordInboundJob(ctx, { replayKeys }));
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const combinedBaseText = entries.map((entry) => resolveDiscordMessageText(entry.data.message, { includeForwarded: false })).filter(Boolean).join("\n");
|
|
278
|
+
const syntheticMessage = Object.create(Object.getPrototypeOf(last.data.message), {
|
|
279
|
+
...Object.getOwnPropertyDescriptors(last.data.message),
|
|
280
|
+
content: {
|
|
281
|
+
value: combinedBaseText,
|
|
282
|
+
enumerable: true,
|
|
283
|
+
configurable: true
|
|
284
|
+
},
|
|
285
|
+
attachments: {
|
|
286
|
+
value: [],
|
|
287
|
+
enumerable: true,
|
|
288
|
+
configurable: true
|
|
289
|
+
},
|
|
290
|
+
message_snapshots: {
|
|
291
|
+
value: last.data.message.message_snapshots,
|
|
292
|
+
enumerable: true,
|
|
293
|
+
configurable: true
|
|
294
|
+
},
|
|
295
|
+
messageSnapshots: {
|
|
296
|
+
value: last.data.message.messageSnapshots,
|
|
297
|
+
enumerable: true,
|
|
298
|
+
configurable: true
|
|
299
|
+
},
|
|
300
|
+
rawData: {
|
|
301
|
+
value: { ...last.data.message.rawData },
|
|
302
|
+
enumerable: true,
|
|
303
|
+
configurable: true
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
const syntheticData = {
|
|
307
|
+
...last.data,
|
|
308
|
+
message: syntheticMessage
|
|
309
|
+
};
|
|
310
|
+
const ctx = await (preflightDiscordMessageImpl ?? (await loadMessagePreflightRuntime()).preflightDiscordMessage)({
|
|
311
|
+
...params,
|
|
312
|
+
ackReactionScope,
|
|
313
|
+
groupPolicy,
|
|
314
|
+
abortSignal,
|
|
315
|
+
data: syntheticData,
|
|
316
|
+
client: last.client
|
|
317
|
+
});
|
|
318
|
+
if (!ctx) {
|
|
319
|
+
await commitDiscordInboundReplay({
|
|
320
|
+
replayKeys,
|
|
321
|
+
replayGuard
|
|
322
|
+
});
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
applyImplicitReplyBatchGate(ctx, params.replyToMode, true);
|
|
326
|
+
if (entries.length > 1) {
|
|
327
|
+
const ids = entries.map((entry) => entry.data.message?.id).filter(isNonEmptyString);
|
|
328
|
+
if (ids.length > 0) {
|
|
329
|
+
const ctxBatch = ctx;
|
|
330
|
+
ctxBatch.MessageSids = ids;
|
|
331
|
+
ctxBatch.MessageSidFirst = ids[0];
|
|
332
|
+
ctxBatch.MessageSidLast = ids[ids.length - 1];
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
queueAcceptedDiscordTypingCue(ctx);
|
|
336
|
+
messageRunQueue.enqueue(buildDiscordInboundJob(ctx, { replayKeys }));
|
|
337
|
+
} catch (error) {
|
|
338
|
+
if (error instanceof DiscordRetryableInboundError) releaseDiscordInboundReplay({
|
|
339
|
+
replayKeys,
|
|
340
|
+
error,
|
|
341
|
+
replayGuard
|
|
342
|
+
});
|
|
343
|
+
else await commitDiscordInboundReplay({
|
|
344
|
+
replayKeys,
|
|
345
|
+
replayGuard
|
|
346
|
+
});
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
onError: (err) => {
|
|
351
|
+
params.runtime.error?.(danger(`discord debounce flush failed: ${String(err)}`));
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
const handler = async (data, client, options) => {
|
|
355
|
+
try {
|
|
356
|
+
if (options?.abortSignal?.aborted) return;
|
|
357
|
+
const msgAuthorId = data.message?.author?.id ?? data.author?.id;
|
|
358
|
+
if (params.botUserId && msgAuthorId === params.botUserId) return;
|
|
359
|
+
const replayKey = buildDiscordInboundReplayKey({
|
|
360
|
+
accountId: params.accountId,
|
|
361
|
+
data
|
|
362
|
+
});
|
|
363
|
+
if (!await claimDiscordInboundReplay({
|
|
364
|
+
replayKey,
|
|
365
|
+
replayGuard
|
|
366
|
+
})) return;
|
|
367
|
+
await debouncer.enqueue({
|
|
368
|
+
data,
|
|
369
|
+
client,
|
|
370
|
+
abortSignal: options?.abortSignal,
|
|
371
|
+
replayKey: replayKey ?? void 0
|
|
372
|
+
});
|
|
373
|
+
} catch (err) {
|
|
374
|
+
params.runtime.error?.(danger(`handler failed: ${String(err)}`));
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
handler.deactivate = messageRunQueue.deactivate;
|
|
378
|
+
return handler;
|
|
379
|
+
}
|
|
380
|
+
//#endregion
|
|
381
|
+
export { createDiscordMessageHandler as t };
|