@openclaw/discord 2026.7.2-beta.2 → 2026.7.2-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/action-runtime-api.js +1 -1
- package/dist/{activities-api-D0D_87n3.js → activities-api-DS1L7KRY.js} +15 -42
- package/dist/activities-api.js +1 -1
- package/dist/{allow-list-B7qOH5xu.js → allow-list-DzKrtfah.js} +18 -7
- package/dist/{api-B88T4rFN.js → api-C43z8vUm.js} +3 -1
- package/dist/api.js +25 -16
- package/dist/{approval-handler.runtime-B7E1-x5q.js → approval-handler.runtime-BbkfPoGc.js} +5 -6
- package/dist/{conversation-identity-BPcbhCAH.js → approval-message-safety-DrLlgIPz.js} +48 -2
- package/dist/{audit-CjpnY1yb.js → audit-BC6bgPMX.js} +3 -3
- package/dist/{channel-BDfKr14H.js → channel-5MfaC2IE.js} +18 -18
- package/dist/{channel-actions-BQct-o4T.js → channel-actions-DicWTbYH.js} +2 -2
- package/dist/{channel-actions.runtime-CC4QwYVO.js → channel-actions.runtime-D9Qadn-l.js} +8 -8
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.setup-BS4gd8sc.js → channel.setup-CJXfFclP.js} +3 -3
- package/dist/{chunk-CHpY_lsO.js → chunk-CWzmeWf_.js} +9 -49
- package/dist/{config-schema-CoDck1GW.js → config-schema-BxrgfSMD.js} +4 -0
- package/dist/{directory-config-G1QwBIdi.js → directory-config-CmukHSms.js} +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-nfvekMil.js → directory-live-BYlCRO__.js} +3 -3
- package/dist/{doctor-Bq4pJAQk.js → doctor-Ci7USQAW.js} +1 -1
- package/dist/{handle-action.guild-admin-LYY75_Oa.js → handle-action.guild-admin-Bsk2YBPs.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/{manager.runtime-w6VVYQMl.js → manager.runtime-Cc8vS-M7.js} +98 -145
- package/dist/message-handler-CWJ-mQvH.js +590 -0
- package/dist/{message-handler.preflight-DnAH04Ss.js → message-handler.preflight-DK46_qbS.js} +16 -15
- package/dist/{message-handler.process-ClgKz8I5.js → message-handler.process-BK0mjFJH.js} +37 -61
- package/dist/{message-utils-BU3gc01v.js → message-utils-Cfe6CZ6N.js} +1 -1
- package/dist/{outbound-adapter-ByoXsR-V.js → outbound-adapter-B2_oa-zV.js} +36 -5
- package/dist/{outbound-components-7wAolLuS.js → outbound-components-BGhk6HI3.js} +3 -3
- package/dist/{outbound-session-route-D4QqePZN.js → outbound-session-route-M2bEY9tI.js} +36 -6
- package/dist/{pluralkit-r4wiI2yy.js → pluralkit-CT0VRsZd.js} +1 -1
- package/dist/{probe-WKeTYyJX.js → probe-C3SCKyYU.js} +1 -1
- package/dist/{probe.runtime-CRY-qUke.js → probe.runtime-D55QqC9u.js} +1 -1
- package/dist/{provider-PRlF_lZm.js → provider-HW0G-2l6.js} +868 -794
- package/dist/{provider-session.runtime-BZPUZRjn.js → provider-session.runtime-cCfGMsF_.js} +3 -3
- package/dist/provider.runtime-BWCRsVoT.js +2 -0
- package/dist/{resolve-allowlist-common-QN7VMZaC.js → resolve-allowlist-common-CJlqw_nC.js} +2 -2
- package/dist/{resolve-channels-BO9NUPlS.js → resolve-channels-9KcG3mLg.js} +4 -4
- package/dist/{resolve-users-CU3oG5-m.js → resolve-users-GCGf3oV0.js} +3 -3
- package/dist/{runtime-CCf5nkV3.js → runtime-CD5MRZkD.js} +1 -2
- package/dist/{runtime-BsefAQ9q.js → runtime-Z2qkKakn.js} +9 -8
- package/dist/runtime-api.actions.js +2 -2
- package/dist/runtime-api.js +23 -22
- package/dist/runtime-api.lookup.js +5 -5
- package/dist/runtime-api.monitor-C3EDYJqk.js +6 -0
- package/dist/runtime-api.monitor.js +8 -8
- package/dist/runtime-api.send.js +6 -5
- package/dist/runtime-api.threads.js +3 -3
- package/dist/{secret-config-contract-BDNrRWvd.js → secret-config-contract-B1akrlyY.js} +1 -0
- package/dist/secret-contract-api.js +1 -1
- package/dist/security-audit-contract-api.js +1 -1
- package/dist/{security-audit.runtime-K0nkzjzJ.js → security-audit.runtime-DEEywczv.js} +1 -1
- package/dist/{send-JJzVo_sK.js → send-CSRxNNgq.js} +7 -86
- package/dist/{send.components-CCRW54gK.js → send.components-DLqzOEPJ.js} +5 -4
- package/dist/{send.outbound-Cvulb-k_.js → send.outbound-C1SfX20w.js} +4 -3
- package/dist/send.reactions-Cj4ugX3F.js +85 -0
- package/dist/send.receipt-CuwRrpFz.js +48 -0
- package/dist/{send.shared-XuOTO1dW.js → send.shared-Dber6X57.js} +2 -2
- package/dist/{sender-identity-C62lBe18.js → sender-identity-mG_zsdox.js} +1 -1
- package/dist/session-binding-contract-api.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{shared-Bngr0I-v.js → shared-BEhmAdMY.js} +5 -5
- package/dist/{subagent-hooks-mSxRv4AE.js → subagent-hooks-Wrk61DwY.js} +2 -2
- package/dist/subagent-hooks-api.js +10 -1
- package/dist/subagent-progress-B2fpHe3m.js +662 -0
- package/dist/{system-events-BANBRAe3.js → system-events-AhfcKRRb.js} +2 -2
- package/dist/{target-resolver-BaEmTxeK.js → target-resolver-vqLA450R.js} +2 -2
- package/dist/targets-BjEMIe8t.js +3 -0
- package/dist/{thread-bindings-4MV-u8vU.js → thread-bindings-CJQoXuWY.js} +4 -4
- package/dist/{thread-bindings.discord-api-DXfXsHGZ.js → thread-bindings.discord-api-mNCWlgvM.js} +4 -4
- package/dist/{thread-bindings.manager-DJ4cO5Eu.js → thread-bindings.manager-D1z8mK4b.js} +3 -3
- package/dist/{timeouts-D5lWili0.js → timeouts-B9cy6RvQ.js} +1 -6
- package/dist/{transcripts-source-TDZcMriu.js → transcripts-source-DjDbt14x.js} +1 -1
- package/dist/transcripts-source-api.js +1 -1
- package/dist/{typing-CKd2NMWG.js → typing-wxtm1NlF.js} +2 -2
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +10 -0
- package/package.json +4 -4
- package/dist/approval-message-safety-C-8BL6Kv.js +0 -47
- package/dist/message-handler-DExaghWK.js +0 -331
- package/dist/provider.runtime-BX8GcCYx.js +0 -2
- package/dist/runtime-api.monitor-DCS_ETft.js +0 -6
- package/dist/targets-fjJt3PYG.js +0 -3
- package/dist/{security-audit-aLbWmUjl.js → security-audit-DtT0SIns.js} +1 -1
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as Client, D as RateLimitError, F as Message, I as User, K as Container, M as Command, N as CommandWithSubcommands, P as Guild, Q as Row, V as Modal, W as Button, Yt as __exportAll, _ as MessageReactionRemoveListener, _t as editChannel, at as BaseMessageInteractiveComponent, bt as getChannelMessage, d as discord_exports, et as Separator, f as GuildCreateListener, g as MessageReactionAddListener, h as MessageCreateListener, m as InteractionCreateListener, mt as createThread, nt as TextDisplay, p as GuildDeleteListener, t as chunkDiscordTextWithMode, tt as StringSelectMenu, v as PresenceUpdateListener, w as Plugin, x as ThreadUpdateListener, y as ReadyListener } from "./chunk-CWzmeWf_.js";
|
|
2
2
|
import { c as resolveDiscordAccountAllowFrom, d as resolveDiscordAccountDmPolicy, f as resolveDiscordMaxLinesPerMessage, p as normalizeDiscordToken, s as resolveDiscordAccount } from "./accounts-CMd4nzLB.js";
|
|
3
|
-
import { n as getDiscordActivitiesRuntime } from "./runtime-
|
|
4
|
-
import { C as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { _ as resolveDiscordModalEntryWithPersistence, g as resolveDiscordComponentEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-CCRW54gK.js";
|
|
3
|
+
import { n as getDiscordActivitiesRuntime } from "./runtime-CD5MRZkD.js";
|
|
4
|
+
import { C as parseDiscordActivityCustomIdForInteraction, D as parseDiscordModalCustomIdForInteraction, E as parseDiscordModalCustomId, O as decodeCustomIdComponent, T as parseDiscordComponentCustomIdForInteraction, k as encodeCustomIdComponent, l as parseExecApprovalData, s as parseDiscordQuestionData, w as parseDiscordComponentCustomId, y as buildDiscordActivityCustomId } from "./outbound-session-route-M2bEY9tI.js";
|
|
5
|
+
import { D as canViewDiscordGuildChannel, F as createDiscordRestClient, H as registerGateway, K as validateDiscordProxyUrl, U as unregisterGateway, q as withValidatedDiscordProxy, z as DISCORD_REST_TIMEOUT_MS } from "./send.shared-Dber6X57.js";
|
|
6
|
+
import { _ as resolveDiscordModalEntryWithPersistence, g as resolveDiscordComponentEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-DLqzOEPJ.js";
|
|
8
7
|
import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
|
|
9
|
-
import { a as isDiscordRateLimitResponseBody, o as summarizeDiscordResponseBody } from "./api-
|
|
10
|
-
import { a as
|
|
8
|
+
import { a as isDiscordRateLimitResponseBody, o as summarizeDiscordResponseBody } from "./api-C43z8vUm.js";
|
|
9
|
+
import { C as resolveTimestampMs, a as normalizeDiscordSlug, b as formatDiscordReactionEmoji, c as resolveDiscordChannelConfigWithFallback, d as resolveDiscordCommandOwnerAllowFrom, f as resolveDiscordGuildEntry, g as resolveDiscordOwnerAllowFrom, h as resolveDiscordOwnerAccess, i as normalizeDiscordDisplaySlug, l as resolveDiscordChannelPolicyCommandAuthorizer, m as resolveDiscordMemberAllowed, n as isDiscordGroupAllowedByPolicy, o as resolveDiscordAllowListMatch, p as resolveDiscordMemberAccessState, r as normalizeDiscordAllowList, t as allowListMatches, v as resolveGroupDmAllow, x as formatDiscordUserTag, y as shouldEmitDiscordReactionNotification } from "./allow-list-DzKrtfah.js";
|
|
10
|
+
import { a as formatMention, t as sendMessageDiscord } from "./send.outbound-C1SfX20w.js";
|
|
11
11
|
import { i as setPresence, t as clearPresences } from "./presence-cache-z1N8MbJ3.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { a as
|
|
15
|
-
import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-
|
|
16
|
-
import { t as resolveDiscordUserAllowlist } from "./resolve-users-
|
|
17
|
-
import { _ as formatThreadBindingDurationLabel, a as isThreadArchived, d as resolveDiscordChannelNameSafe, f as resolveDiscordChannelParentIdSafe, l as resolveDiscordChannelIdSafe, m as resolveDiscordChannelTopicSafe, p as resolveDiscordChannelParentSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-
|
|
18
|
-
import { r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-
|
|
19
|
-
import { d as resolveDiscordMessageChannelId, n as resolveDiscordForwardedMessagesTextFromSnapshots, t as resolveDiscordEmbedText, u as resolveDiscordChannelInfo } from "./message-utils-
|
|
20
|
-
import { t as resolveDiscordSenderIdentity } from "./sender-identity-
|
|
21
|
-
import { n as formatDiscordApprovalDisplayValue, t as DISCORD_APPROVAL_ALLOWED_MENTIONS } from "./approval-message-safety-C-8BL6Kv.js";
|
|
12
|
+
import { n as sendVoiceMessageDiscord } from "./send-CSRxNNgq.js";
|
|
13
|
+
import { c as raceWithTimeout, u as withAbortTimeout } from "./timeouts-B9cy6RvQ.js";
|
|
14
|
+
import { a as getDiscordExecApprovalApprovers, n as formatDiscordApprovalDisplayValue, r as resolveDiscordConversationIdentity, s as isDiscordExecApprovalClientEnabled, t as DISCORD_APPROVAL_ALLOWED_MENTIONS } from "./approval-message-safety-DrLlgIPz.js";
|
|
15
|
+
import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-9KcG3mLg.js";
|
|
16
|
+
import { t as resolveDiscordUserAllowlist } from "./resolve-users-GCGf3oV0.js";
|
|
17
|
+
import { _ as formatThreadBindingDurationLabel, a as isThreadArchived, d as resolveDiscordChannelNameSafe, f as resolveDiscordChannelParentIdSafe, l as resolveDiscordChannelIdSafe, m as resolveDiscordChannelTopicSafe, p as resolveDiscordChannelParentSafe, u as resolveDiscordChannelInfoSafe } from "./thread-bindings.discord-api-mNCWlgvM.js";
|
|
18
|
+
import { r as parseApplicationIdFromToken, t as fetchDiscordApplicationId } from "./probe-C3SCKyYU.js";
|
|
19
|
+
import { d as resolveDiscordMessageChannelId, n as resolveDiscordForwardedMessagesTextFromSnapshots, t as resolveDiscordEmbedText, u as resolveDiscordChannelInfo } from "./message-utils-Cfe6CZ6N.js";
|
|
20
|
+
import { t as resolveDiscordSenderIdentity } from "./sender-identity-mG_zsdox.js";
|
|
22
21
|
import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
23
22
|
import { buildAgentSessionKey, deriveLastRoutePolicy, isAcpSessionKey, isSubagentSessionKey, parseAgentSessionKey, resolveAgentIdFromSessionKey, resolveAgentRoute } from "openclaw/plugin-sdk/routing";
|
|
24
23
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeOptionalStringifiedId, normalizeStringEntries, normalizeStringEntriesLower, summarizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
@@ -33,11 +32,11 @@ import { Check, Errors } from "typebox/value";
|
|
|
33
32
|
import { inspect } from "node:util";
|
|
34
33
|
import { readResponseWithLimit } from "openclaw/plugin-sdk/response-limit-runtime";
|
|
35
34
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
36
|
-
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
|
|
37
35
|
import { fetchWithSsrFGuard, formatErrorMessage as formatErrorMessage$1 } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
38
36
|
import { createHttp1EnvHttpProxyAgent, createHttp1ProxyAgent, createNodeProxyAgent, resolveEnvHttpProxyAgentOptions, wrapFetchWithAbortSignal } from "openclaw/plugin-sdk/fetch-runtime";
|
|
39
37
|
import { createNonExitingRuntime, createSubsystemLogger, danger, formatDurationSeconds, isVerbose, logVerbose, shouldLogVerbose, sleepWithAbort, warn } from "openclaw/plugin-sdk/runtime-env";
|
|
40
38
|
import { sliceUtf16Safe, truncateUtf16Safe, withTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
39
|
+
import { addAllowlistUserEntriesFromConfigEntry, buildAllowlistResolutionSummary, canonicalizeAllowlistWithResolvedIds, patchAllowlistUsersInConfigEntries, summarizeMapping } from "openclaw/plugin-sdk/allow-from";
|
|
41
40
|
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
42
41
|
import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
|
|
43
42
|
import { chunkItems, sanitizeAssistantVisibleText, sanitizeAssistantVisibleTextWithProfile } from "openclaw/plugin-sdk/text-chunking";
|
|
@@ -51,9 +50,10 @@ import { resolvePinnedMainDmOwnerFromAllowlist as resolvePinnedMainDmOwnerFromAl
|
|
|
51
50
|
import { GROUP_POLICY_BLOCKED_LABEL, resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
52
51
|
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
|
|
53
52
|
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
|
54
|
-
import {
|
|
53
|
+
import { questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
|
|
55
54
|
import { buildPairingReply, upsertChannelPairingRequest, upsertChannelPairingRequest as upsertChannelPairingRequest$1 } from "openclaw/plugin-sdk/conversation-runtime";
|
|
56
55
|
import { clearExpiredCooldowns, ensureAuthProfileStore, formatReasoningMessage, isProfileInCooldown, loadModelCatalog, resolveAgentAvatar, resolveDefaultModelForAgent, resolveHumanDelayConfig, resolveProfilesUnavailableReason } from "openclaw/plugin-sdk/agent-runtime";
|
|
56
|
+
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
|
|
57
57
|
import { resolveNativeCommandsEnabled, resolveNativeSkillsEnabled } from "openclaw/plugin-sdk/native-command-config-runtime";
|
|
58
58
|
import { normalizeProviderId } from "openclaw/plugin-sdk/provider-model-shared";
|
|
59
59
|
import { requestHeartbeat } from "openclaw/plugin-sdk/heartbeat-runtime";
|
|
@@ -62,7 +62,7 @@ import { createChannelIngressResolver, defineStableChannelIngressIdentity, readC
|
|
|
62
62
|
import { ModelSelectionLockedError, applyModelOverrideToSessionEntry, resolveChannelModelOverride } from "openclaw/plugin-sdk/model-session-runtime";
|
|
63
63
|
import { completeWithPreparedSimpleCompletionModel, extractAssistantText, prepareSimpleCompletionModelForAgent } from "openclaw/plugin-sdk/simple-completion-runtime";
|
|
64
64
|
import { getSessionEntry, listSessionEntries, patchSessionEntry, readSessionUpdatedAt as readSessionUpdatedAt$1, resolveStorePath, resolveStorePath as resolveStorePath$1 } from "openclaw/plugin-sdk/session-store-runtime";
|
|
65
|
-
import { formatInboundEnvelope, resolveEnvelopeFormatOptions, runChannelInboundEvent } from "openclaw/plugin-sdk/channel-inbound";
|
|
65
|
+
import { formatInboundEnvelope, resolveEnvelopeFormatOptions, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent } from "openclaw/plugin-sdk/channel-inbound";
|
|
66
66
|
import { buildCommandTextFromArgs, findCommandByNativeName, formatCommandArgMenuTitle, listChatCommands, listNativeCommandSpecsForConfig, listSkillCommandsForAgents, resolveCommandAuthorizedFromAuthorizers, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverride, serializeCommandArgs } from "openclaw/plugin-sdk/command-auth-native";
|
|
67
67
|
import { buildCommandTextFromArgs as buildCommandTextFromArgs$1, findCommandByNativeName as findCommandByNativeName$1, parseCommandArgs, resolveCommandArgChoices, resolveCommandArgMenu, serializeCommandArgs as serializeCommandArgs$1 } from "openclaw/plugin-sdk/native-command-registry";
|
|
68
68
|
import { resolveDirectStatusReplyForSession } from "openclaw/plugin-sdk/command-status-runtime";
|
|
@@ -1439,9 +1439,11 @@ var DiscordMessageListener = class extends MessageCreateListener {
|
|
|
1439
1439
|
}
|
|
1440
1440
|
async handle(data, client) {
|
|
1441
1441
|
this.onEvent?.();
|
|
1442
|
-
|
|
1442
|
+
try {
|
|
1443
|
+
await this.handler(data, client);
|
|
1444
|
+
} catch (err) {
|
|
1443
1445
|
(this.logger ?? discordEventQueueLog).error(danger(`discord handler failed: ${String(err)}`));
|
|
1444
|
-
}
|
|
1446
|
+
}
|
|
1445
1447
|
}
|
|
1446
1448
|
};
|
|
1447
1449
|
var DiscordInteractionListener = class extends InteractionCreateListener {
|
|
@@ -1719,6 +1721,62 @@ var DiscordThreadUpdateListener = class extends ThreadUpdateListener {
|
|
|
1719
1721
|
}
|
|
1720
1722
|
};
|
|
1721
1723
|
//#endregion
|
|
1724
|
+
//#region extensions/discord/src/internal/gateway-dispatch.ts
|
|
1725
|
+
function dispatchVoiceGatewayEvent(client, type, data) {
|
|
1726
|
+
const guildId = readGuildId(data);
|
|
1727
|
+
if (!guildId) return;
|
|
1728
|
+
const adapter = (client.getPlugin("voice")?.adapters)?.get(guildId);
|
|
1729
|
+
const voiceServerUpdate = GatewayDispatchEvents.VoiceServerUpdate;
|
|
1730
|
+
const voiceStateUpdate = GatewayDispatchEvents.VoiceStateUpdate;
|
|
1731
|
+
if (type === voiceServerUpdate) adapter?.onVoiceServerUpdate?.(data);
|
|
1732
|
+
if (type === voiceStateUpdate) adapter?.onVoiceStateUpdate?.(data);
|
|
1733
|
+
}
|
|
1734
|
+
function mapGatewayDispatchData(client, type, data) {
|
|
1735
|
+
const messageCreate = GatewayDispatchEvents.MessageCreate;
|
|
1736
|
+
const reactionAdd = GatewayDispatchEvents.MessageReactionAdd;
|
|
1737
|
+
const reactionRemove = GatewayDispatchEvents.MessageReactionRemove;
|
|
1738
|
+
if (type === messageCreate) return createMessageDispatchData(client, data);
|
|
1739
|
+
if (type === reactionAdd || type === reactionRemove) return createReactionDispatchData(client, data);
|
|
1740
|
+
return data;
|
|
1741
|
+
}
|
|
1742
|
+
function createMessageDispatchData(client, data) {
|
|
1743
|
+
const message = new Message(client, data);
|
|
1744
|
+
return {
|
|
1745
|
+
...data,
|
|
1746
|
+
id: data.id,
|
|
1747
|
+
channel_id: data.channel_id,
|
|
1748
|
+
channelId: data.channel_id,
|
|
1749
|
+
message,
|
|
1750
|
+
author: message.author ?? (data.author ? new User(client, data.author) : null),
|
|
1751
|
+
member: data.member,
|
|
1752
|
+
rawMember: data.member,
|
|
1753
|
+
guild: data.guild_id ? new Guild(client, data.guild_id) : null
|
|
1754
|
+
};
|
|
1755
|
+
}
|
|
1756
|
+
function createReactionDispatchData(client, data) {
|
|
1757
|
+
const userRaw = data.member?.user && typeof data.member.user === "object" ? {
|
|
1758
|
+
id: data.user_id,
|
|
1759
|
+
username: "",
|
|
1760
|
+
...data.member.user
|
|
1761
|
+
} : {
|
|
1762
|
+
id: data.user_id,
|
|
1763
|
+
username: ""
|
|
1764
|
+
};
|
|
1765
|
+
return {
|
|
1766
|
+
...data,
|
|
1767
|
+
user: new User(client, userRaw),
|
|
1768
|
+
rawMember: data.member,
|
|
1769
|
+
guild: data.guild_id ? new Guild(client, data.guild_id) : null,
|
|
1770
|
+
message: new Message(client, {
|
|
1771
|
+
id: data.message_id,
|
|
1772
|
+
channelId: data.channel_id
|
|
1773
|
+
})
|
|
1774
|
+
};
|
|
1775
|
+
}
|
|
1776
|
+
function readGuildId(data) {
|
|
1777
|
+
return data && typeof data === "object" && typeof data.guild_id === "string" ? data.guild_id : void 0;
|
|
1778
|
+
}
|
|
1779
|
+
//#endregion
|
|
1722
1780
|
//#region extensions/discord/src/monitor/dm-command-decision.ts
|
|
1723
1781
|
async function handleDiscordDmCommandDecision(params) {
|
|
1724
1782
|
if (params.senderAccess.decision === "allow") return true;
|
|
@@ -2326,16 +2384,23 @@ function shouldBypassConfiguredAcpGuildGuards(commandName) {
|
|
|
2326
2384
|
//#endregion
|
|
2327
2385
|
//#region extensions/discord/src/monitor/inbound-context.ts
|
|
2328
2386
|
function createDiscordSupplementalContextAccessChecker(params) {
|
|
2387
|
+
const userAllowList = params.channelConfig?.users ?? params.guildInfo?.users ?? [];
|
|
2388
|
+
const roleAllowList = params.channelConfig?.roles ?? params.guildInfo?.roles ?? [];
|
|
2389
|
+
const allowFrom = [...userAllowList, ...roleAllowList];
|
|
2329
2390
|
return (sender) => {
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2391
|
+
return resolveInboundSupplementalSenderAllowed({
|
|
2392
|
+
isGroup: params.isGuild,
|
|
2393
|
+
groupPolicy: allowFrom.length === 0 ? "open" : "allowlist",
|
|
2394
|
+
allowFrom,
|
|
2395
|
+
isSenderAllowed: () => resolveDiscordMemberAllowed({
|
|
2396
|
+
userAllowList,
|
|
2397
|
+
roleAllowList,
|
|
2398
|
+
memberRoleIds: sender.memberRoleIds ?? [],
|
|
2399
|
+
userId: sender.id ?? "",
|
|
2400
|
+
userName: sender.name,
|
|
2401
|
+
userTag: sender.tag,
|
|
2402
|
+
allowNameMatching: params.allowNameMatching
|
|
2403
|
+
})
|
|
2339
2404
|
});
|
|
2340
2405
|
};
|
|
2341
2406
|
}
|
|
@@ -5240,62 +5305,6 @@ function canResumeAfterGatewayClose(code) {
|
|
|
5240
5305
|
return !nonResumableGatewayCloseCodes.has(code);
|
|
5241
5306
|
}
|
|
5242
5307
|
//#endregion
|
|
5243
|
-
//#region extensions/discord/src/internal/gateway-dispatch.ts
|
|
5244
|
-
function dispatchVoiceGatewayEvent(client, type, data) {
|
|
5245
|
-
const guildId = readGuildId(data);
|
|
5246
|
-
if (!guildId) return;
|
|
5247
|
-
const adapter = (client.getPlugin("voice")?.adapters)?.get(guildId);
|
|
5248
|
-
const voiceServerUpdate = GatewayDispatchEvents.VoiceServerUpdate;
|
|
5249
|
-
const voiceStateUpdate = GatewayDispatchEvents.VoiceStateUpdate;
|
|
5250
|
-
if (type === voiceServerUpdate) adapter?.onVoiceServerUpdate?.(data);
|
|
5251
|
-
if (type === voiceStateUpdate) adapter?.onVoiceStateUpdate?.(data);
|
|
5252
|
-
}
|
|
5253
|
-
function mapGatewayDispatchData(client, type, data) {
|
|
5254
|
-
const messageCreate = GatewayDispatchEvents.MessageCreate;
|
|
5255
|
-
const reactionAdd = GatewayDispatchEvents.MessageReactionAdd;
|
|
5256
|
-
const reactionRemove = GatewayDispatchEvents.MessageReactionRemove;
|
|
5257
|
-
if (type === messageCreate) return createMessageDispatchData(client, data);
|
|
5258
|
-
if (type === reactionAdd || type === reactionRemove) return createReactionDispatchData(client, data);
|
|
5259
|
-
return data;
|
|
5260
|
-
}
|
|
5261
|
-
function createMessageDispatchData(client, data) {
|
|
5262
|
-
const message = new Message(client, data);
|
|
5263
|
-
return {
|
|
5264
|
-
...data,
|
|
5265
|
-
id: data.id,
|
|
5266
|
-
channel_id: data.channel_id,
|
|
5267
|
-
channelId: data.channel_id,
|
|
5268
|
-
message,
|
|
5269
|
-
author: message.author ?? (data.author ? new User(client, data.author) : null),
|
|
5270
|
-
member: data.member,
|
|
5271
|
-
rawMember: data.member,
|
|
5272
|
-
guild: data.guild_id ? new Guild(client, data.guild_id) : null
|
|
5273
|
-
};
|
|
5274
|
-
}
|
|
5275
|
-
function createReactionDispatchData(client, data) {
|
|
5276
|
-
const userRaw = data.member?.user && typeof data.member.user === "object" ? {
|
|
5277
|
-
id: data.user_id,
|
|
5278
|
-
username: "",
|
|
5279
|
-
...data.member.user
|
|
5280
|
-
} : {
|
|
5281
|
-
id: data.user_id,
|
|
5282
|
-
username: ""
|
|
5283
|
-
};
|
|
5284
|
-
return {
|
|
5285
|
-
...data,
|
|
5286
|
-
user: new User(client, userRaw),
|
|
5287
|
-
rawMember: data.member,
|
|
5288
|
-
guild: data.guild_id ? new Guild(client, data.guild_id) : null,
|
|
5289
|
-
message: new Message(client, {
|
|
5290
|
-
id: data.message_id,
|
|
5291
|
-
channelId: data.channel_id
|
|
5292
|
-
})
|
|
5293
|
-
};
|
|
5294
|
-
}
|
|
5295
|
-
function readGuildId(data) {
|
|
5296
|
-
return data && typeof data === "object" && typeof data.guild_id === "string" ? data.guild_id : void 0;
|
|
5297
|
-
}
|
|
5298
|
-
//#endregion
|
|
5299
5308
|
//#region extensions/discord/src/internal/gateway-identify-limiter.ts
|
|
5300
5309
|
const IDENTIFY_WINDOW_MS = 5e3;
|
|
5301
5310
|
function normalizeMaxConcurrency(value) {
|
|
@@ -5825,7 +5834,7 @@ var GatewayPlugin = class extends Plugin {
|
|
|
5825
5834
|
}
|
|
5826
5835
|
this.voiceStateCache.apply(payload);
|
|
5827
5836
|
dispatchVoiceGatewayEvent(this.client, payload.t, payload.d);
|
|
5828
|
-
const data = mapGatewayDispatchData(this.client, payload.t, payload.d);
|
|
5837
|
+
const data = payload.t === GatewayDispatchEvents.MessageCreate ? payload.d : mapGatewayDispatchData(this.client, payload.t, payload.d);
|
|
5829
5838
|
await this.client.dispatchGatewayEvent(payload.t, data);
|
|
5830
5839
|
if (payload.t === GatewayDispatchEvents.InteractionCreate && this.options.autoInteractions) await this.client.handleInteraction(payload.d);
|
|
5831
5840
|
}
|
|
@@ -7239,7 +7248,7 @@ async function runDiscordGatewayLifecycle(params) {
|
|
|
7239
7248
|
gatewayEmitter?.removeListener(DISCORD_GATEWAY_TRANSPORT_ACTIVITY_EVENT, onGatewayTransportActivity);
|
|
7240
7249
|
if (params.voiceManager) {
|
|
7241
7250
|
await params.voiceManager.destroy();
|
|
7242
|
-
const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-
|
|
7251
|
+
const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-DjDbt14x.js").then((n) => n.n);
|
|
7243
7252
|
setDiscordTranscriptsVoiceManager({
|
|
7244
7253
|
accountId: params.accountId,
|
|
7245
7254
|
manager: null
|
|
@@ -7254,7 +7263,7 @@ async function runDiscordGatewayLifecycle(params) {
|
|
|
7254
7263
|
let discordVoiceRuntimePromise;
|
|
7255
7264
|
let discordProviderSessionRuntimePromise;
|
|
7256
7265
|
async function loadDiscordVoiceRuntime() {
|
|
7257
|
-
const promise = discordVoiceRuntimePromise ?? import("./manager.runtime-
|
|
7266
|
+
const promise = discordVoiceRuntimePromise ?? import("./manager.runtime-Cc8vS-M7.js");
|
|
7258
7267
|
discordVoiceRuntimePromise = promise;
|
|
7259
7268
|
try {
|
|
7260
7269
|
return await promise;
|
|
@@ -7264,7 +7273,7 @@ async function loadDiscordVoiceRuntime() {
|
|
|
7264
7273
|
}
|
|
7265
7274
|
}
|
|
7266
7275
|
async function loadDiscordProviderSessionRuntime() {
|
|
7267
|
-
const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-
|
|
7276
|
+
const promise = discordProviderSessionRuntimePromise ?? import("./provider-session.runtime-cCfGMsF_.js");
|
|
7268
7277
|
discordProviderSessionRuntimePromise = promise;
|
|
7269
7278
|
try {
|
|
7270
7279
|
return await promise;
|
|
@@ -7612,8 +7621,8 @@ async function resolveDiscordAllowlistConfig(params) {
|
|
|
7612
7621
|
}
|
|
7613
7622
|
//#endregion
|
|
7614
7623
|
//#region extensions/discord/src/monitor/provider.cleanup.ts
|
|
7615
|
-
function cleanupDiscordProviderStartup(params) {
|
|
7616
|
-
params.deactivateMessageHandler?.();
|
|
7624
|
+
async function cleanupDiscordProviderStartup(params) {
|
|
7625
|
+
await params.deactivateMessageHandler?.();
|
|
7617
7626
|
params.autoPresenceController?.stop();
|
|
7618
7627
|
params.setStatus?.({ connected: false });
|
|
7619
7628
|
if (params.onEarlyGatewayDebug) params.earlyGatewayEmitter?.removeListener("debug", params.onEarlyGatewayDebug);
|
|
@@ -8019,107 +8028,6 @@ function runDiscordCommandDeployInBackground(params) {
|
|
|
8019
8028
|
});
|
|
8020
8029
|
}
|
|
8021
8030
|
//#endregion
|
|
8022
|
-
//#region extensions/discord/src/monitor/agent-components-context.ts
|
|
8023
|
-
function formatUsername(user) {
|
|
8024
|
-
if (user.discriminator && user.discriminator !== "0") return `${user.username}#${user.discriminator}`;
|
|
8025
|
-
return user.username;
|
|
8026
|
-
}
|
|
8027
|
-
function isThreadChannelType(channelType) {
|
|
8028
|
-
return channelType === ChannelType.PublicThread || channelType === ChannelType.PrivateThread || channelType === ChannelType.AnnouncementThread;
|
|
8029
|
-
}
|
|
8030
|
-
function resolveAgentComponentRoute(params) {
|
|
8031
|
-
return resolveAgentRoute({
|
|
8032
|
-
cfg: params.ctx.cfg,
|
|
8033
|
-
channel: "discord",
|
|
8034
|
-
accountId: params.ctx.accountId,
|
|
8035
|
-
guildId: params.rawGuildId,
|
|
8036
|
-
memberRoleIds: params.memberRoleIds,
|
|
8037
|
-
peer: {
|
|
8038
|
-
kind: params.isDirectMessage ? "direct" : params.isGroupDm ? "group" : "channel",
|
|
8039
|
-
id: params.isDirectMessage ? params.userId : params.channelId
|
|
8040
|
-
},
|
|
8041
|
-
parentPeer: params.parentId ? {
|
|
8042
|
-
kind: "channel",
|
|
8043
|
-
id: params.parentId
|
|
8044
|
-
} : void 0
|
|
8045
|
-
});
|
|
8046
|
-
}
|
|
8047
|
-
async function ackComponentInteraction(params) {
|
|
8048
|
-
try {
|
|
8049
|
-
await params.interaction.reply({
|
|
8050
|
-
content: "✓",
|
|
8051
|
-
...params.replyOpts
|
|
8052
|
-
});
|
|
8053
|
-
} catch (err) {
|
|
8054
|
-
logError(`${params.label}: failed to acknowledge interaction: ${String(err)}`);
|
|
8055
|
-
}
|
|
8056
|
-
}
|
|
8057
|
-
function resolveDiscordChannelContext(interaction) {
|
|
8058
|
-
const channel = interaction.channel;
|
|
8059
|
-
const channelInfo = resolveDiscordChannelInfoSafe(channel);
|
|
8060
|
-
const channelName = channelInfo.name;
|
|
8061
|
-
const channelSlug = channelName ? normalizeDiscordSlug(channelName) : "";
|
|
8062
|
-
const displayChannelSlug = channelName ? normalizeDiscordDisplaySlug(channelName) : "";
|
|
8063
|
-
const channelType = channelInfo.type;
|
|
8064
|
-
const isThread = isThreadChannelType(channelType);
|
|
8065
|
-
let parentId;
|
|
8066
|
-
let parentName;
|
|
8067
|
-
let parentSlug = "";
|
|
8068
|
-
if (isThread) {
|
|
8069
|
-
parentId = channelInfo.parentId;
|
|
8070
|
-
parentName = channelInfo.parentName;
|
|
8071
|
-
if (parentName) parentSlug = normalizeDiscordSlug(parentName);
|
|
8072
|
-
}
|
|
8073
|
-
return {
|
|
8074
|
-
channelName,
|
|
8075
|
-
channelSlug,
|
|
8076
|
-
displayChannelSlug,
|
|
8077
|
-
channelType,
|
|
8078
|
-
isThread,
|
|
8079
|
-
parentId,
|
|
8080
|
-
parentName,
|
|
8081
|
-
parentSlug
|
|
8082
|
-
};
|
|
8083
|
-
}
|
|
8084
|
-
async function resolveComponentInteractionContext(params) {
|
|
8085
|
-
const { interaction, label } = params;
|
|
8086
|
-
const channelId = interaction.rawData.channel_id;
|
|
8087
|
-
if (!channelId) {
|
|
8088
|
-
logError(`${label}: missing channel_id in interaction`);
|
|
8089
|
-
return null;
|
|
8090
|
-
}
|
|
8091
|
-
const user = interaction.user;
|
|
8092
|
-
if (!user) {
|
|
8093
|
-
logError(`${label}: missing user in interaction`);
|
|
8094
|
-
return null;
|
|
8095
|
-
}
|
|
8096
|
-
const shouldDefer = params.defer !== false && "defer" in interaction;
|
|
8097
|
-
let didDefer = false;
|
|
8098
|
-
if (shouldDefer) try {
|
|
8099
|
-
await interaction.defer({ ephemeral: true });
|
|
8100
|
-
didDefer = true;
|
|
8101
|
-
} catch (err) {
|
|
8102
|
-
logError(`${label}: failed to defer interaction: ${String(err)}`);
|
|
8103
|
-
}
|
|
8104
|
-
const replyOpts = didDefer ? {} : { ephemeral: true };
|
|
8105
|
-
const username = formatUsername(user);
|
|
8106
|
-
const userId = user.id;
|
|
8107
|
-
const rawGuildId = interaction.rawData.guild_id;
|
|
8108
|
-
const channelType = resolveDiscordChannelContext(interaction).channelType;
|
|
8109
|
-
const isGroupDm = channelType === ChannelType.GroupDM;
|
|
8110
|
-
return {
|
|
8111
|
-
channelId,
|
|
8112
|
-
user,
|
|
8113
|
-
username,
|
|
8114
|
-
userId,
|
|
8115
|
-
replyOpts,
|
|
8116
|
-
rawGuildId,
|
|
8117
|
-
isDirectMessage: channelType === ChannelType.DM || !rawGuildId && !isGroupDm && channelType == null,
|
|
8118
|
-
isGroupDm,
|
|
8119
|
-
memberRoleIds: Array.isArray(interaction.rawData.member?.roles) ? interaction.rawData.member.roles.map((roleId) => roleId) : []
|
|
8120
|
-
};
|
|
8121
|
-
}
|
|
8122
|
-
//#endregion
|
|
8123
8031
|
//#region extensions/discord/src/monitor/agent-components-reply.ts
|
|
8124
8032
|
async function replySilently(interaction, params) {
|
|
8125
8033
|
try {
|
|
@@ -8127,463 +8035,118 @@ async function replySilently(interaction, params) {
|
|
|
8127
8035
|
} catch {}
|
|
8128
8036
|
}
|
|
8129
8037
|
//#endregion
|
|
8130
|
-
//#region extensions/discord/src/
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8038
|
+
//#region extensions/discord/src/activities/interaction.ts
|
|
8039
|
+
const REGISTRATION_WIDGET_ID = "AAAAAAAAAAAAAAAAAAAAAA";
|
|
8040
|
+
const PENDING_LAUNCH_WRITE_BUDGET_MS = 250;
|
|
8041
|
+
var DiscordActivityButton = class extends Button {
|
|
8042
|
+
constructor(ctx, deps) {
|
|
8043
|
+
super();
|
|
8044
|
+
this.ctx = ctx;
|
|
8045
|
+
this.deps = deps;
|
|
8046
|
+
this.label = "Open widget";
|
|
8047
|
+
this.customId = buildDiscordActivityCustomId(REGISTRATION_WIDGET_ID);
|
|
8048
|
+
this.customIdParser = parseDiscordActivityCustomIdForInteraction;
|
|
8049
|
+
this.pendingLaunchFailureLogged = false;
|
|
8141
8050
|
}
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
sender: {
|
|
8147
|
-
id: user.id,
|
|
8148
|
-
name: user.username,
|
|
8149
|
-
tag: formatDiscordUserTag(user)
|
|
8150
|
-
},
|
|
8151
|
-
allowNameMatching: isDangerousNameMatchingEnabled(ctx.discordConfig),
|
|
8152
|
-
cfg: ctx.cfg,
|
|
8153
|
-
token: ctx.token,
|
|
8154
|
-
readStoreAllowFrom: async ({ accountId, dmPolicy: dmPolicyLocal }) => await readChannelIngressStoreAllowFromForDmPolicy({
|
|
8155
|
-
provider: "discord",
|
|
8156
|
-
accountId,
|
|
8157
|
-
dmPolicy: dmPolicyLocal
|
|
8158
|
-
}),
|
|
8159
|
-
eventKind: "button"
|
|
8160
|
-
});
|
|
8161
|
-
if (access.senderAccess.decision === "allow") return true;
|
|
8162
|
-
if (access.senderAccess.decision !== "pairing") {
|
|
8163
|
-
logVerbose(`agent ${componentLabel}: blocked DM user ${user.id} (not in allowFrom)`);
|
|
8164
|
-
await replySilently(interaction, {
|
|
8165
|
-
content: `You are not authorized to use this ${componentLabel}.`,
|
|
8166
|
-
...replyOpts
|
|
8167
|
-
});
|
|
8168
|
-
return false;
|
|
8051
|
+
logPendingLaunchFailure(error) {
|
|
8052
|
+
if (this.pendingLaunchFailureLogged) return;
|
|
8053
|
+
this.pendingLaunchFailureLogged = true;
|
|
8054
|
+
this.deps.logError(`discord activity: failed to record pending launch: ${String(error)}`);
|
|
8169
8055
|
}
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
channel: "discord",
|
|
8176
|
-
id,
|
|
8177
|
-
accountId: ctx.accountId,
|
|
8178
|
-
meta
|
|
8056
|
+
async run(interaction, data) {
|
|
8057
|
+
if (typeof data.widgetId !== "string") {
|
|
8058
|
+
await this.deps.reply(interaction, {
|
|
8059
|
+
content: "This widget is no longer valid.",
|
|
8060
|
+
ephemeral: true
|
|
8179
8061
|
});
|
|
8062
|
+
return;
|
|
8180
8063
|
}
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8064
|
+
const runtime = getDiscordActivitiesRuntime();
|
|
8065
|
+
const channelId = interaction.rawData.channel_id;
|
|
8066
|
+
const discordUserId = interaction.userId;
|
|
8067
|
+
if (!runtime || !channelId || !discordUserId) this.logPendingLaunchFailure(/* @__PURE__ */ new Error("missing activity runtime or interaction identity"));
|
|
8068
|
+
else {
|
|
8069
|
+
const write = runtime.store.recordPendingLaunch({
|
|
8070
|
+
accountId: this.ctx.accountId,
|
|
8071
|
+
channelId,
|
|
8072
|
+
discordUserId,
|
|
8073
|
+
widgetId: data.widgetId,
|
|
8074
|
+
createdAt: Date.now()
|
|
8075
|
+
}).then(() => "written").catch((error) => {
|
|
8076
|
+
this.logPendingLaunchFailure(error);
|
|
8077
|
+
return "failed";
|
|
8078
|
+
});
|
|
8079
|
+
const timeout = new Promise((resolve) => {
|
|
8080
|
+
setTimeout(() => resolve("timeout"), PENDING_LAUNCH_WRITE_BUDGET_MS).unref?.();
|
|
8192
8081
|
});
|
|
8082
|
+
if (await Promise.race([write, timeout]) === "timeout") this.logPendingLaunchFailure(/* @__PURE__ */ new Error(`pending launch write exceeded ${PENDING_LAUNCH_WRITE_BUDGET_MS}ms`));
|
|
8193
8083
|
}
|
|
8194
|
-
|
|
8195
|
-
content: "Pairing already requested. Ask the bot owner to approve your code.",
|
|
8196
|
-
...replyOpts
|
|
8197
|
-
});
|
|
8198
|
-
return false;
|
|
8199
|
-
}
|
|
8200
|
-
async function ensureGroupDmComponentAuthorized(params) {
|
|
8201
|
-
const { ctx, interaction, channelId, componentLabel, replyOpts } = params;
|
|
8202
|
-
if (!(ctx.discordConfig?.dm?.groupEnabled ?? false)) {
|
|
8203
|
-
logVerbose(`agent ${componentLabel}: blocked group dm ${channelId} (group DMs disabled)`);
|
|
8204
|
-
await replySilently(interaction, {
|
|
8205
|
-
content: "Group DM interactions are disabled.",
|
|
8206
|
-
...replyOpts
|
|
8207
|
-
});
|
|
8208
|
-
return false;
|
|
8084
|
+
await interaction.launchActivity();
|
|
8209
8085
|
}
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
content: `You are not authorized to use this ${componentLabel}.`,
|
|
8220
|
-
...replyOpts
|
|
8221
|
-
});
|
|
8222
|
-
return false;
|
|
8223
|
-
}
|
|
8224
|
-
async function resolveInteractionContextWithDmAuth(params) {
|
|
8225
|
-
const interactionCtx = await resolveComponentInteractionContext({
|
|
8226
|
-
interaction: params.interaction,
|
|
8227
|
-
label: params.label,
|
|
8228
|
-
defer: params.defer
|
|
8086
|
+
};
|
|
8087
|
+
function createDiscordActivityButton(ctx, applicationId, deps = {}) {
|
|
8088
|
+
const runtime = getDiscordActivitiesRuntime();
|
|
8089
|
+
if (!runtime || !runtime.isAccountEnabled(ctx.accountId, ctx.cfg)) return null;
|
|
8090
|
+
if (applicationId) runtime.registerApplicationId(ctx.accountId, applicationId);
|
|
8091
|
+
if (!runtime.resolveAccount(ctx.accountId, ctx.cfg)) return null;
|
|
8092
|
+
return new DiscordActivityButton(ctx, {
|
|
8093
|
+
reply: deps.reply ?? replySilently,
|
|
8094
|
+
logError: deps.logError ?? logError
|
|
8229
8095
|
});
|
|
8230
|
-
if (!interactionCtx) return null;
|
|
8231
|
-
if (interactionCtx.isDirectMessage) {
|
|
8232
|
-
if (!await ensureDmComponentAuthorized({
|
|
8233
|
-
ctx: params.ctx,
|
|
8234
|
-
interaction: params.interaction,
|
|
8235
|
-
user: interactionCtx.user,
|
|
8236
|
-
componentLabel: params.componentLabel,
|
|
8237
|
-
replyOpts: interactionCtx.replyOpts
|
|
8238
|
-
})) return null;
|
|
8239
|
-
}
|
|
8240
|
-
if (interactionCtx.isGroupDm) {
|
|
8241
|
-
if (!await ensureGroupDmComponentAuthorized({
|
|
8242
|
-
ctx: params.ctx,
|
|
8243
|
-
interaction: params.interaction,
|
|
8244
|
-
channelId: interactionCtx.channelId,
|
|
8245
|
-
componentLabel: params.componentLabel,
|
|
8246
|
-
replyOpts: interactionCtx.replyOpts
|
|
8247
|
-
})) return null;
|
|
8248
|
-
}
|
|
8249
|
-
return interactionCtx;
|
|
8250
8096
|
}
|
|
8251
8097
|
//#endregion
|
|
8252
|
-
//#region extensions/discord/src/
|
|
8253
|
-
function
|
|
8254
|
-
|
|
8255
|
-
providerConfigPresent:
|
|
8256
|
-
groupPolicy:
|
|
8257
|
-
defaultGroupPolicy:
|
|
8098
|
+
//#region extensions/discord/src/voice/access.ts
|
|
8099
|
+
async function authorizeDiscordVoiceIngress(params) {
|
|
8100
|
+
const groupPolicy = params.groupPolicy ?? resolveOpenProviderRuntimeGroupPolicy({
|
|
8101
|
+
providerConfigPresent: params.cfg.channels?.discord !== void 0,
|
|
8102
|
+
groupPolicy: params.discordConfig.groupPolicy,
|
|
8103
|
+
defaultGroupPolicy: params.cfg.channels?.defaults?.groupPolicy
|
|
8258
8104
|
}).groupPolicy;
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
8262
|
-
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
...replyOpts
|
|
8267
|
-
});
|
|
8268
|
-
};
|
|
8269
|
-
const channelConfig = resolveDiscordChannelConfigWithFallback({
|
|
8270
|
-
guildInfo,
|
|
8271
|
-
channelId,
|
|
8272
|
-
channelName: channelCtx.channelName,
|
|
8273
|
-
channelSlug: channelCtx.channelSlug,
|
|
8274
|
-
parentId: channelCtx.parentId,
|
|
8275
|
-
parentName: channelCtx.parentName,
|
|
8276
|
-
parentSlug: channelCtx.parentSlug,
|
|
8277
|
-
scope: channelCtx.isThread ? "thread" : "channel"
|
|
8105
|
+
const guildInfo = resolveDiscordGuildEntry({
|
|
8106
|
+
guild: params.guild ?? {
|
|
8107
|
+
id: params.guildId,
|
|
8108
|
+
...params.guildName ? { name: params.guildName } : {}
|
|
8109
|
+
},
|
|
8110
|
+
guildId: params.guildId,
|
|
8111
|
+
guildEntries: params.discordConfig.guilds
|
|
8278
8112
|
});
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8113
|
+
const channelConfig = params.channelId ? resolveDiscordChannelConfigWithFallback({
|
|
8114
|
+
guildInfo,
|
|
8115
|
+
channelId: params.channelId,
|
|
8116
|
+
channelName: params.channelName,
|
|
8117
|
+
channelSlug: params.channelSlug,
|
|
8118
|
+
parentId: params.parentId,
|
|
8119
|
+
parentName: params.parentName,
|
|
8120
|
+
parentSlug: params.parentSlug,
|
|
8121
|
+
scope: params.scope
|
|
8122
|
+
}) : null;
|
|
8123
|
+
if (channelConfig?.enabled === false) return {
|
|
8124
|
+
ok: false,
|
|
8125
|
+
message: "This channel is disabled."
|
|
8126
|
+
};
|
|
8283
8127
|
const channelAllowlistConfigured = Boolean(guildInfo?.channels) && Object.keys(guildInfo?.channels ?? {}).length > 0;
|
|
8284
|
-
|
|
8128
|
+
if (!params.channelId && groupPolicy === "allowlist" && channelAllowlistConfigured) return {
|
|
8129
|
+
ok: false,
|
|
8130
|
+
message: `${params.channelLabel ?? "This channel"} is not allowlisted for voice commands.`
|
|
8131
|
+
};
|
|
8132
|
+
const channelAllowed = channelConfig ? channelConfig.allowed : !channelAllowlistConfigured;
|
|
8285
8133
|
if (!isDiscordGroupAllowedByPolicy({
|
|
8286
|
-
groupPolicy
|
|
8134
|
+
groupPolicy,
|
|
8287
8135
|
guildAllowlisted: Boolean(guildInfo),
|
|
8288
8136
|
channelAllowlistConfigured,
|
|
8289
8137
|
channelAllowed
|
|
8290
|
-
})) {
|
|
8291
|
-
|
|
8292
|
-
|
|
8293
|
-
}
|
|
8294
|
-
|
|
8295
|
-
await replyUnauthorized();
|
|
8296
|
-
return false;
|
|
8297
|
-
}
|
|
8298
|
-
const { memberAllowed } = resolveDiscordMemberAccessState({
|
|
8138
|
+
}) || channelConfig?.allowed === false) return {
|
|
8139
|
+
ok: false,
|
|
8140
|
+
message: `${params.channelLabel ?? "This channel"} is not allowlisted for voice commands.`
|
|
8141
|
+
};
|
|
8142
|
+
const { hasAccessRestrictions, memberAllowed } = resolveDiscordMemberAccessState({
|
|
8299
8143
|
channelConfig,
|
|
8300
8144
|
guildInfo,
|
|
8301
|
-
memberRoleIds,
|
|
8302
|
-
sender:
|
|
8303
|
-
|
|
8304
|
-
name: user.username,
|
|
8305
|
-
tag: user.discriminator ? `${user.username}#${user.discriminator}` : void 0
|
|
8306
|
-
},
|
|
8307
|
-
allowNameMatching: params.allowNameMatching
|
|
8145
|
+
memberRoleIds: params.memberRoleIds,
|
|
8146
|
+
sender: params.sender,
|
|
8147
|
+
allowNameMatching: false
|
|
8308
8148
|
});
|
|
8309
|
-
|
|
8310
|
-
logVerbose(`agent ${componentLabel}: blocked user ${user.id} (not in users/roles allowlist)`);
|
|
8311
|
-
await replyUnauthorized();
|
|
8312
|
-
return false;
|
|
8313
|
-
}
|
|
8314
|
-
async function ensureComponentUserAllowed(params) {
|
|
8315
|
-
const allowList = normalizeDiscordAllowList(params.entry.allowedUsers, [
|
|
8316
|
-
"discord:",
|
|
8317
|
-
"user:",
|
|
8318
|
-
"pk:"
|
|
8319
|
-
]);
|
|
8320
|
-
if (!allowList) return true;
|
|
8321
|
-
if (resolveDiscordAllowListMatch({
|
|
8322
|
-
allowList,
|
|
8323
|
-
candidate: {
|
|
8324
|
-
id: params.user.id,
|
|
8325
|
-
name: params.user.username,
|
|
8326
|
-
tag: formatDiscordUserTag(params.user)
|
|
8327
|
-
},
|
|
8328
|
-
allowNameMatching: params.allowNameMatching
|
|
8329
|
-
}).allowed) return true;
|
|
8330
|
-
logVerbose(`discord component ${params.componentLabel}: blocked user ${params.user.id} (not in allowedUsers)`);
|
|
8331
|
-
await replySilently(params.interaction, {
|
|
8332
|
-
content: params.unauthorizedReply,
|
|
8333
|
-
...params.replyOpts
|
|
8334
|
-
});
|
|
8335
|
-
return false;
|
|
8336
|
-
}
|
|
8337
|
-
async function ensureAgentComponentInteractionAllowed(params) {
|
|
8338
|
-
const guildInfo = resolveDiscordGuildEntry({
|
|
8339
|
-
guild: params.interaction.guild ?? void 0,
|
|
8340
|
-
guildId: params.rawGuildId,
|
|
8341
|
-
guildEntries: params.ctx.guildEntries
|
|
8342
|
-
});
|
|
8343
|
-
const channelCtx = resolveDiscordChannelContext(params.interaction);
|
|
8344
|
-
if (!await ensureGuildComponentMemberAllowed({
|
|
8345
|
-
interaction: params.interaction,
|
|
8346
|
-
guildInfo,
|
|
8347
|
-
channelId: params.channelId,
|
|
8348
|
-
rawGuildId: params.rawGuildId,
|
|
8349
|
-
channelCtx,
|
|
8350
|
-
memberRoleIds: params.memberRoleIds,
|
|
8351
|
-
user: params.user,
|
|
8352
|
-
replyOpts: params.replyOpts,
|
|
8353
|
-
componentLabel: params.componentLabel,
|
|
8354
|
-
unauthorizedReply: params.unauthorizedReply,
|
|
8355
|
-
allowNameMatching: isDangerousNameMatchingEnabled(params.ctx.discordConfig),
|
|
8356
|
-
groupPolicy: resolveComponentRuntimeGroupPolicy(params.ctx)
|
|
8357
|
-
})) return null;
|
|
8358
|
-
return { parentId: channelCtx.parentId };
|
|
8359
|
-
}
|
|
8360
|
-
async function resolveAuthorizedComponentInteraction(params) {
|
|
8361
|
-
const interactionCtx = await resolveInteractionContextWithDmAuth({
|
|
8362
|
-
ctx: params.ctx,
|
|
8363
|
-
interaction: params.interaction,
|
|
8364
|
-
label: params.label,
|
|
8365
|
-
componentLabel: params.componentLabel,
|
|
8366
|
-
defer: params.defer
|
|
8367
|
-
});
|
|
8368
|
-
if (!interactionCtx) return null;
|
|
8369
|
-
const { channelId, user, replyOpts, rawGuildId, memberRoleIds } = interactionCtx;
|
|
8370
|
-
const guildInfo = resolveDiscordGuildEntry({
|
|
8371
|
-
guild: params.interaction.guild ?? void 0,
|
|
8372
|
-
guildId: rawGuildId,
|
|
8373
|
-
guildEntries: params.ctx.guildEntries
|
|
8374
|
-
});
|
|
8375
|
-
const channelCtx = resolveDiscordChannelContext(params.interaction);
|
|
8376
|
-
const allowNameMatching = isDangerousNameMatchingEnabled(params.ctx.discordConfig);
|
|
8377
|
-
const channelConfig = resolveDiscordChannelConfigWithFallback({
|
|
8378
|
-
guildInfo,
|
|
8379
|
-
channelId,
|
|
8380
|
-
channelName: channelCtx.channelName,
|
|
8381
|
-
channelSlug: channelCtx.channelSlug,
|
|
8382
|
-
parentId: channelCtx.parentId,
|
|
8383
|
-
parentName: channelCtx.parentName,
|
|
8384
|
-
parentSlug: channelCtx.parentSlug,
|
|
8385
|
-
scope: channelCtx.isThread ? "thread" : "channel"
|
|
8386
|
-
});
|
|
8387
|
-
if (!await ensureGuildComponentMemberAllowed({
|
|
8388
|
-
interaction: params.interaction,
|
|
8389
|
-
guildInfo,
|
|
8390
|
-
channelId,
|
|
8391
|
-
rawGuildId,
|
|
8392
|
-
channelCtx,
|
|
8393
|
-
memberRoleIds,
|
|
8394
|
-
user,
|
|
8395
|
-
replyOpts,
|
|
8396
|
-
componentLabel: params.componentLabel,
|
|
8397
|
-
unauthorizedReply: params.unauthorizedReply,
|
|
8398
|
-
allowNameMatching,
|
|
8399
|
-
groupPolicy: resolveComponentRuntimeGroupPolicy(params.ctx)
|
|
8400
|
-
})) return null;
|
|
8401
|
-
return {
|
|
8402
|
-
interactionCtx,
|
|
8403
|
-
channelCtx,
|
|
8404
|
-
guildInfo,
|
|
8405
|
-
channelConfig,
|
|
8406
|
-
allowNameMatching,
|
|
8407
|
-
commandAuthorized: await resolveComponentCommandAuthorized({
|
|
8408
|
-
ctx: params.ctx,
|
|
8409
|
-
interactionCtx,
|
|
8410
|
-
channelConfig,
|
|
8411
|
-
guildInfo,
|
|
8412
|
-
allowNameMatching
|
|
8413
|
-
}),
|
|
8414
|
-
user,
|
|
8415
|
-
replyOpts
|
|
8416
|
-
};
|
|
8417
|
-
}
|
|
8418
|
-
async function resolveComponentCommandAuthorized(params) {
|
|
8419
|
-
const { ctx, interactionCtx, channelConfig, guildInfo } = params;
|
|
8420
|
-
if (interactionCtx.isDirectMessage) return true;
|
|
8421
|
-
const { ownerAllowList, ownerAllowed: ownerOk } = resolveDiscordOwnerAccess({
|
|
8422
|
-
allowFrom: ctx.allowFrom,
|
|
8423
|
-
sender: {
|
|
8424
|
-
id: interactionCtx.user.id,
|
|
8425
|
-
name: interactionCtx.user.username,
|
|
8426
|
-
tag: formatDiscordUserTag(interactionCtx.user)
|
|
8427
|
-
},
|
|
8428
|
-
allowNameMatching: params.allowNameMatching
|
|
8429
|
-
});
|
|
8430
|
-
const { hasAccessRestrictions, memberAllowed } = resolveDiscordMemberAccessState({
|
|
8431
|
-
channelConfig,
|
|
8432
|
-
guildInfo,
|
|
8433
|
-
memberRoleIds: interactionCtx.memberRoleIds,
|
|
8434
|
-
sender: {
|
|
8435
|
-
id: interactionCtx.user.id,
|
|
8436
|
-
name: interactionCtx.user.username,
|
|
8437
|
-
tag: formatDiscordUserTag(interactionCtx.user)
|
|
8438
|
-
},
|
|
8439
|
-
allowNameMatching: params.allowNameMatching
|
|
8440
|
-
});
|
|
8441
|
-
const useAccessGroups = ctx.cfg.commands?.useAccessGroups !== false;
|
|
8442
|
-
return resolveCommandAuthorizedFromAuthorizers({
|
|
8443
|
-
useAccessGroups,
|
|
8444
|
-
authorizers: useAccessGroups ? [{
|
|
8445
|
-
configured: ownerAllowList != null,
|
|
8446
|
-
allowed: ownerOk
|
|
8447
|
-
}, {
|
|
8448
|
-
configured: hasAccessRestrictions,
|
|
8449
|
-
allowed: memberAllowed
|
|
8450
|
-
}] : [{
|
|
8451
|
-
configured: hasAccessRestrictions,
|
|
8452
|
-
allowed: memberAllowed
|
|
8453
|
-
}],
|
|
8454
|
-
modeWhenAccessGroupsOff: "configured"
|
|
8455
|
-
});
|
|
8456
|
-
}
|
|
8457
|
-
//#endregion
|
|
8458
|
-
//#region extensions/discord/src/activities/interaction.ts
|
|
8459
|
-
const REGISTRATION_WIDGET_ID = "AAAAAAAAAAAAAAAAAAAAAA";
|
|
8460
|
-
const PENDING_LAUNCH_WRITE_BUDGET_MS = 250;
|
|
8461
|
-
var DiscordActivityButton = class extends Button {
|
|
8462
|
-
constructor(ctx, deps) {
|
|
8463
|
-
super();
|
|
8464
|
-
this.ctx = ctx;
|
|
8465
|
-
this.deps = deps;
|
|
8466
|
-
this.label = "Open widget";
|
|
8467
|
-
this.customId = buildDiscordActivityCustomId(REGISTRATION_WIDGET_ID);
|
|
8468
|
-
this.customIdParser = parseDiscordActivityCustomIdForInteraction;
|
|
8469
|
-
this.pendingLaunchFailureLogged = false;
|
|
8470
|
-
}
|
|
8471
|
-
logPendingLaunchFailure(error) {
|
|
8472
|
-
if (this.pendingLaunchFailureLogged) return;
|
|
8473
|
-
this.pendingLaunchFailureLogged = true;
|
|
8474
|
-
this.deps.logError(`discord activity: failed to record pending launch: ${String(error)}`);
|
|
8475
|
-
}
|
|
8476
|
-
async run(interaction, data) {
|
|
8477
|
-
if (typeof data.widgetId !== "string") {
|
|
8478
|
-
await this.deps.reply(interaction, {
|
|
8479
|
-
content: "This widget is no longer valid.",
|
|
8480
|
-
ephemeral: true
|
|
8481
|
-
});
|
|
8482
|
-
return;
|
|
8483
|
-
}
|
|
8484
|
-
const authorized = await this.deps.authorize({
|
|
8485
|
-
ctx: this.ctx,
|
|
8486
|
-
interaction,
|
|
8487
|
-
label: "discord activity",
|
|
8488
|
-
componentLabel: "widget button",
|
|
8489
|
-
unauthorizedReply: "not allowed",
|
|
8490
|
-
defer: false
|
|
8491
|
-
});
|
|
8492
|
-
if (!authorized) return;
|
|
8493
|
-
if (!authorized.commandAuthorized) {
|
|
8494
|
-
await this.deps.reply(interaction, {
|
|
8495
|
-
content: "not allowed",
|
|
8496
|
-
ephemeral: true
|
|
8497
|
-
});
|
|
8498
|
-
return;
|
|
8499
|
-
}
|
|
8500
|
-
const runtime = getDiscordActivitiesRuntime();
|
|
8501
|
-
const channelId = interaction.rawData.channel_id;
|
|
8502
|
-
const discordUserId = interaction.userId;
|
|
8503
|
-
if (!runtime || !channelId || !discordUserId) this.logPendingLaunchFailure(/* @__PURE__ */ new Error("missing activity runtime or interaction identity"));
|
|
8504
|
-
else {
|
|
8505
|
-
const write = runtime.store.recordPendingLaunch({
|
|
8506
|
-
accountId: this.ctx.accountId,
|
|
8507
|
-
channelId,
|
|
8508
|
-
discordUserId,
|
|
8509
|
-
widgetId: data.widgetId,
|
|
8510
|
-
createdAt: Date.now()
|
|
8511
|
-
}).then(() => "written").catch((error) => {
|
|
8512
|
-
this.logPendingLaunchFailure(error);
|
|
8513
|
-
return "failed";
|
|
8514
|
-
});
|
|
8515
|
-
const timeout = new Promise((resolve) => {
|
|
8516
|
-
setTimeout(() => resolve("timeout"), PENDING_LAUNCH_WRITE_BUDGET_MS).unref?.();
|
|
8517
|
-
});
|
|
8518
|
-
if (await Promise.race([write, timeout]) === "timeout") this.logPendingLaunchFailure(/* @__PURE__ */ new Error(`pending launch write exceeded ${PENDING_LAUNCH_WRITE_BUDGET_MS}ms`));
|
|
8519
|
-
}
|
|
8520
|
-
await interaction.launchActivity();
|
|
8521
|
-
}
|
|
8522
|
-
};
|
|
8523
|
-
function createDiscordActivityButton(ctx, applicationId, deps = {}) {
|
|
8524
|
-
const runtime = getDiscordActivitiesRuntime();
|
|
8525
|
-
if (!runtime || !runtime.isAccountEnabled(ctx.accountId, ctx.cfg)) return null;
|
|
8526
|
-
if (applicationId) runtime.registerApplicationId(ctx.accountId, applicationId);
|
|
8527
|
-
if (!runtime.resolveAccount(ctx.accountId, ctx.cfg)) return null;
|
|
8528
|
-
return new DiscordActivityButton(ctx, {
|
|
8529
|
-
authorize: deps.authorize ?? resolveAuthorizedComponentInteraction,
|
|
8530
|
-
reply: deps.reply ?? replySilently,
|
|
8531
|
-
logError: deps.logError ?? logError
|
|
8532
|
-
});
|
|
8533
|
-
}
|
|
8534
|
-
//#endregion
|
|
8535
|
-
//#region extensions/discord/src/voice/access.ts
|
|
8536
|
-
async function authorizeDiscordVoiceIngress(params) {
|
|
8537
|
-
const groupPolicy = params.groupPolicy ?? resolveOpenProviderRuntimeGroupPolicy({
|
|
8538
|
-
providerConfigPresent: params.cfg.channels?.discord !== void 0,
|
|
8539
|
-
groupPolicy: params.discordConfig.groupPolicy,
|
|
8540
|
-
defaultGroupPolicy: params.cfg.channels?.defaults?.groupPolicy
|
|
8541
|
-
}).groupPolicy;
|
|
8542
|
-
const guildInfo = resolveDiscordGuildEntry({
|
|
8543
|
-
guild: params.guild ?? {
|
|
8544
|
-
id: params.guildId,
|
|
8545
|
-
...params.guildName ? { name: params.guildName } : {}
|
|
8546
|
-
},
|
|
8547
|
-
guildId: params.guildId,
|
|
8548
|
-
guildEntries: params.discordConfig.guilds
|
|
8549
|
-
});
|
|
8550
|
-
const channelConfig = params.channelId ? resolveDiscordChannelConfigWithFallback({
|
|
8551
|
-
guildInfo,
|
|
8552
|
-
channelId: params.channelId,
|
|
8553
|
-
channelName: params.channelName,
|
|
8554
|
-
channelSlug: params.channelSlug,
|
|
8555
|
-
parentId: params.parentId,
|
|
8556
|
-
parentName: params.parentName,
|
|
8557
|
-
parentSlug: params.parentSlug,
|
|
8558
|
-
scope: params.scope
|
|
8559
|
-
}) : null;
|
|
8560
|
-
if (channelConfig?.enabled === false) return {
|
|
8561
|
-
ok: false,
|
|
8562
|
-
message: "This channel is disabled."
|
|
8563
|
-
};
|
|
8564
|
-
const channelAllowlistConfigured = Boolean(guildInfo?.channels) && Object.keys(guildInfo?.channels ?? {}).length > 0;
|
|
8565
|
-
if (!params.channelId && groupPolicy === "allowlist" && channelAllowlistConfigured) return {
|
|
8566
|
-
ok: false,
|
|
8567
|
-
message: `${params.channelLabel ?? "This channel"} is not allowlisted for voice commands.`
|
|
8568
|
-
};
|
|
8569
|
-
const channelAllowed = channelConfig ? channelConfig.allowed : !channelAllowlistConfigured;
|
|
8570
|
-
if (!isDiscordGroupAllowedByPolicy({
|
|
8571
|
-
groupPolicy,
|
|
8572
|
-
guildAllowlisted: Boolean(guildInfo),
|
|
8573
|
-
channelAllowlistConfigured,
|
|
8574
|
-
channelAllowed
|
|
8575
|
-
}) || channelConfig?.allowed === false) return {
|
|
8576
|
-
ok: false,
|
|
8577
|
-
message: `${params.channelLabel ?? "This channel"} is not allowlisted for voice commands.`
|
|
8578
|
-
};
|
|
8579
|
-
const { hasAccessRestrictions, memberAllowed } = resolveDiscordMemberAccessState({
|
|
8580
|
-
channelConfig,
|
|
8581
|
-
guildInfo,
|
|
8582
|
-
memberRoleIds: params.memberRoleIds,
|
|
8583
|
-
sender: params.sender,
|
|
8584
|
-
allowNameMatching: false
|
|
8585
|
-
});
|
|
8586
|
-
const admissionAllowList = normalizeDiscordAllowList(params.admissionAllowFrom ?? params.discordConfig.allowFrom ?? params.discordConfig.dm?.allowFrom, [
|
|
8149
|
+
const admissionAllowList = normalizeDiscordAllowList(params.admissionAllowFrom ?? params.discordConfig.allowFrom ?? params.discordConfig.dm?.allowFrom, [
|
|
8587
8150
|
"discord:",
|
|
8588
8151
|
"user:",
|
|
8589
8152
|
"pk:"
|
|
@@ -8708,160 +8271,589 @@ async function resolveVoiceCommandRuntimeContext(interaction, params) {
|
|
|
8708
8271
|
return null;
|
|
8709
8272
|
}
|
|
8710
8273
|
return {
|
|
8711
|
-
guildId,
|
|
8712
|
-
manager
|
|
8274
|
+
guildId,
|
|
8275
|
+
manager
|
|
8276
|
+
};
|
|
8277
|
+
}
|
|
8278
|
+
async function ensureVoiceCommandAccess(params) {
|
|
8279
|
+
const access = await authorizeVoiceCommand(params.interaction, params.context, { channelOverride: params.channelOverride });
|
|
8280
|
+
if (access.ok) return true;
|
|
8281
|
+
await params.interaction.reply({
|
|
8282
|
+
content: access.message ?? "Not authorized.",
|
|
8283
|
+
ephemeral: true
|
|
8284
|
+
});
|
|
8285
|
+
return false;
|
|
8286
|
+
}
|
|
8287
|
+
function createDiscordVoiceCommand(params) {
|
|
8288
|
+
const resolveSessionChannelId = (manager, guildId) => manager.status().find((entry) => entry.guildId === guildId)?.channelId;
|
|
8289
|
+
class JoinCommand extends Command {
|
|
8290
|
+
constructor(..._args) {
|
|
8291
|
+
super(..._args);
|
|
8292
|
+
this.name = "join";
|
|
8293
|
+
this.description = "Join a voice channel";
|
|
8294
|
+
this.defer = true;
|
|
8295
|
+
this.ephemeral = params.ephemeralDefault;
|
|
8296
|
+
this.options = [{
|
|
8297
|
+
name: "channel",
|
|
8298
|
+
description: "Voice channel to join",
|
|
8299
|
+
type: ApplicationCommandOptionType.Channel,
|
|
8300
|
+
required: true,
|
|
8301
|
+
channel_types: VOICE_CHANNEL_TYPES
|
|
8302
|
+
}];
|
|
8303
|
+
}
|
|
8304
|
+
async run(interaction) {
|
|
8305
|
+
const channel = await interaction.options.getChannel("channel", true);
|
|
8306
|
+
if (!channel || !("id" in channel)) {
|
|
8307
|
+
await interaction.reply({
|
|
8308
|
+
content: "Voice channel not found.",
|
|
8309
|
+
ephemeral: true
|
|
8310
|
+
});
|
|
8311
|
+
return;
|
|
8312
|
+
}
|
|
8313
|
+
const access = await authorizeVoiceCommand(interaction, params, { channelOverride: {
|
|
8314
|
+
id: channel.id,
|
|
8315
|
+
name: resolveDiscordChannelNameSafe(channel)
|
|
8316
|
+
} });
|
|
8317
|
+
if (!access.ok) {
|
|
8318
|
+
await interaction.reply({
|
|
8319
|
+
content: access.message ?? "Not authorized.",
|
|
8320
|
+
ephemeral: true
|
|
8321
|
+
});
|
|
8322
|
+
return;
|
|
8323
|
+
}
|
|
8324
|
+
if (!isVoiceChannelType(channel.type)) {
|
|
8325
|
+
await interaction.reply({
|
|
8326
|
+
content: "That is not a voice channel.",
|
|
8327
|
+
ephemeral: true
|
|
8328
|
+
});
|
|
8329
|
+
return;
|
|
8330
|
+
}
|
|
8331
|
+
const guildId = access.guildId ?? ("guildId" in channel ? channel.guildId : void 0);
|
|
8332
|
+
if (!guildId) {
|
|
8333
|
+
await interaction.reply({
|
|
8334
|
+
content: "Unable to resolve guild for this voice channel.",
|
|
8335
|
+
ephemeral: true
|
|
8336
|
+
});
|
|
8337
|
+
return;
|
|
8338
|
+
}
|
|
8339
|
+
const manager = params.getManager();
|
|
8340
|
+
if (!manager) {
|
|
8341
|
+
await interaction.reply({
|
|
8342
|
+
content: "Voice manager is not available yet.",
|
|
8343
|
+
ephemeral: true
|
|
8344
|
+
});
|
|
8345
|
+
return;
|
|
8346
|
+
}
|
|
8347
|
+
const result = await manager.join({
|
|
8348
|
+
guildId,
|
|
8349
|
+
channelId: channel.id
|
|
8350
|
+
});
|
|
8351
|
+
await interaction.reply({
|
|
8352
|
+
content: result.message,
|
|
8353
|
+
ephemeral: true
|
|
8354
|
+
});
|
|
8355
|
+
}
|
|
8356
|
+
}
|
|
8357
|
+
class LeaveCommand extends Command {
|
|
8358
|
+
constructor(..._args2) {
|
|
8359
|
+
super(..._args2);
|
|
8360
|
+
this.name = "leave";
|
|
8361
|
+
this.description = "Leave the current voice channel";
|
|
8362
|
+
this.defer = true;
|
|
8363
|
+
this.ephemeral = params.ephemeralDefault;
|
|
8364
|
+
}
|
|
8365
|
+
async run(interaction) {
|
|
8366
|
+
const runtimeContext = await resolveVoiceCommandRuntimeContext(interaction, params);
|
|
8367
|
+
if (!runtimeContext) return;
|
|
8368
|
+
const sessionChannelId = resolveSessionChannelId(runtimeContext.manager, runtimeContext.guildId);
|
|
8369
|
+
if (!await ensureVoiceCommandAccess({
|
|
8370
|
+
interaction,
|
|
8371
|
+
context: params,
|
|
8372
|
+
channelOverride: sessionChannelId ? { id: sessionChannelId } : void 0
|
|
8373
|
+
})) return;
|
|
8374
|
+
const result = await runtimeContext.manager.leave({ guildId: runtimeContext.guildId });
|
|
8375
|
+
await interaction.reply({
|
|
8376
|
+
content: result.message,
|
|
8377
|
+
ephemeral: true
|
|
8378
|
+
});
|
|
8379
|
+
}
|
|
8380
|
+
}
|
|
8381
|
+
class StatusCommand extends Command {
|
|
8382
|
+
constructor(..._args3) {
|
|
8383
|
+
super(..._args3);
|
|
8384
|
+
this.name = "status";
|
|
8385
|
+
this.description = "Show active voice sessions";
|
|
8386
|
+
this.defer = true;
|
|
8387
|
+
this.ephemeral = params.ephemeralDefault;
|
|
8388
|
+
}
|
|
8389
|
+
async run(interaction) {
|
|
8390
|
+
const runtimeContext = await resolveVoiceCommandRuntimeContext(interaction, params);
|
|
8391
|
+
if (!runtimeContext) return;
|
|
8392
|
+
const sessions = runtimeContext.manager.status().filter((entry) => entry.guildId === runtimeContext.guildId);
|
|
8393
|
+
const sessionChannelId = sessions[0]?.channelId;
|
|
8394
|
+
if (!await ensureVoiceCommandAccess({
|
|
8395
|
+
interaction,
|
|
8396
|
+
context: params,
|
|
8397
|
+
channelOverride: sessionChannelId ? { id: sessionChannelId } : void 0
|
|
8398
|
+
})) return;
|
|
8399
|
+
if (sessions.length === 0) {
|
|
8400
|
+
await interaction.reply({
|
|
8401
|
+
content: "No active voice sessions.",
|
|
8402
|
+
ephemeral: true
|
|
8403
|
+
});
|
|
8404
|
+
return;
|
|
8405
|
+
}
|
|
8406
|
+
const lines = sessions.map((entry) => `• ${formatMention({ channelId: entry.channelId })} (guild ${entry.guildId})`);
|
|
8407
|
+
await interaction.reply({
|
|
8408
|
+
content: lines.join("\n"),
|
|
8409
|
+
ephemeral: true
|
|
8410
|
+
});
|
|
8411
|
+
}
|
|
8412
|
+
}
|
|
8413
|
+
return new class extends CommandWithSubcommands {
|
|
8414
|
+
constructor(..._args4) {
|
|
8415
|
+
super(..._args4);
|
|
8416
|
+
this.name = "vc";
|
|
8417
|
+
this.description = "Voice channel controls";
|
|
8418
|
+
this.subcommands = [
|
|
8419
|
+
new JoinCommand(),
|
|
8420
|
+
new LeaveCommand(),
|
|
8421
|
+
new StatusCommand()
|
|
8422
|
+
];
|
|
8423
|
+
}
|
|
8424
|
+
}();
|
|
8425
|
+
}
|
|
8426
|
+
function isVoiceChannelType(type) {
|
|
8427
|
+
return type === ChannelType.GuildVoice || type === ChannelType.GuildStageVoice;
|
|
8428
|
+
}
|
|
8429
|
+
//#endregion
|
|
8430
|
+
//#region extensions/discord/src/monitor/agent-components-context.ts
|
|
8431
|
+
function formatUsername(user) {
|
|
8432
|
+
if (user.discriminator && user.discriminator !== "0") return `${user.username}#${user.discriminator}`;
|
|
8433
|
+
return user.username;
|
|
8434
|
+
}
|
|
8435
|
+
function isThreadChannelType(channelType) {
|
|
8436
|
+
return channelType === ChannelType.PublicThread || channelType === ChannelType.PrivateThread || channelType === ChannelType.AnnouncementThread;
|
|
8437
|
+
}
|
|
8438
|
+
function resolveAgentComponentRoute(params) {
|
|
8439
|
+
return resolveAgentRoute({
|
|
8440
|
+
cfg: params.ctx.cfg,
|
|
8441
|
+
channel: "discord",
|
|
8442
|
+
accountId: params.ctx.accountId,
|
|
8443
|
+
guildId: params.rawGuildId,
|
|
8444
|
+
memberRoleIds: params.memberRoleIds,
|
|
8445
|
+
peer: {
|
|
8446
|
+
kind: params.isDirectMessage ? "direct" : params.isGroupDm ? "group" : "channel",
|
|
8447
|
+
id: params.isDirectMessage ? params.userId : params.channelId
|
|
8448
|
+
},
|
|
8449
|
+
parentPeer: params.parentId ? {
|
|
8450
|
+
kind: "channel",
|
|
8451
|
+
id: params.parentId
|
|
8452
|
+
} : void 0
|
|
8453
|
+
});
|
|
8454
|
+
}
|
|
8455
|
+
async function ackComponentInteraction(params) {
|
|
8456
|
+
try {
|
|
8457
|
+
await params.interaction.reply({
|
|
8458
|
+
content: "✓",
|
|
8459
|
+
...params.replyOpts
|
|
8460
|
+
});
|
|
8461
|
+
} catch (err) {
|
|
8462
|
+
logError(`${params.label}: failed to acknowledge interaction: ${String(err)}`);
|
|
8463
|
+
}
|
|
8464
|
+
}
|
|
8465
|
+
function resolveDiscordChannelContext(interaction) {
|
|
8466
|
+
const channel = interaction.channel;
|
|
8467
|
+
const channelInfo = resolveDiscordChannelInfoSafe(channel);
|
|
8468
|
+
const channelName = channelInfo.name;
|
|
8469
|
+
const channelSlug = channelName ? normalizeDiscordSlug(channelName) : "";
|
|
8470
|
+
const displayChannelSlug = channelName ? normalizeDiscordDisplaySlug(channelName) : "";
|
|
8471
|
+
const channelType = channelInfo.type;
|
|
8472
|
+
const isThread = isThreadChannelType(channelType);
|
|
8473
|
+
let parentId;
|
|
8474
|
+
let parentName;
|
|
8475
|
+
let parentSlug = "";
|
|
8476
|
+
if (isThread) {
|
|
8477
|
+
parentId = channelInfo.parentId;
|
|
8478
|
+
parentName = channelInfo.parentName;
|
|
8479
|
+
if (parentName) parentSlug = normalizeDiscordSlug(parentName);
|
|
8480
|
+
}
|
|
8481
|
+
return {
|
|
8482
|
+
channelName,
|
|
8483
|
+
channelSlug,
|
|
8484
|
+
displayChannelSlug,
|
|
8485
|
+
channelType,
|
|
8486
|
+
isThread,
|
|
8487
|
+
parentId,
|
|
8488
|
+
parentName,
|
|
8489
|
+
parentSlug
|
|
8490
|
+
};
|
|
8491
|
+
}
|
|
8492
|
+
async function resolveComponentInteractionContext(params) {
|
|
8493
|
+
const { interaction, label } = params;
|
|
8494
|
+
const channelId = interaction.rawData.channel_id;
|
|
8495
|
+
if (!channelId) {
|
|
8496
|
+
logError(`${label}: missing channel_id in interaction`);
|
|
8497
|
+
return null;
|
|
8498
|
+
}
|
|
8499
|
+
const user = interaction.user;
|
|
8500
|
+
if (!user) {
|
|
8501
|
+
logError(`${label}: missing user in interaction`);
|
|
8502
|
+
return null;
|
|
8503
|
+
}
|
|
8504
|
+
const shouldDefer = params.defer !== false && "defer" in interaction;
|
|
8505
|
+
let didDefer = false;
|
|
8506
|
+
if (shouldDefer) try {
|
|
8507
|
+
await interaction.defer({ ephemeral: true });
|
|
8508
|
+
didDefer = true;
|
|
8509
|
+
} catch (err) {
|
|
8510
|
+
logError(`${label}: failed to defer interaction: ${String(err)}`);
|
|
8511
|
+
}
|
|
8512
|
+
const replyOpts = didDefer ? {} : { ephemeral: true };
|
|
8513
|
+
const username = formatUsername(user);
|
|
8514
|
+
const userId = user.id;
|
|
8515
|
+
const rawGuildId = interaction.rawData.guild_id;
|
|
8516
|
+
const channelType = resolveDiscordChannelContext(interaction).channelType;
|
|
8517
|
+
const isGroupDm = channelType === ChannelType.GroupDM;
|
|
8518
|
+
return {
|
|
8519
|
+
channelId,
|
|
8520
|
+
user,
|
|
8521
|
+
username,
|
|
8522
|
+
userId,
|
|
8523
|
+
replyOpts,
|
|
8524
|
+
rawGuildId,
|
|
8525
|
+
isDirectMessage: channelType === ChannelType.DM || !rawGuildId && !isGroupDm && channelType == null,
|
|
8526
|
+
isGroupDm,
|
|
8527
|
+
memberRoleIds: Array.isArray(interaction.rawData.member?.roles) ? interaction.rawData.member.roles.map((roleId) => roleId) : []
|
|
8528
|
+
};
|
|
8529
|
+
}
|
|
8530
|
+
//#endregion
|
|
8531
|
+
//#region extensions/discord/src/monitor/agent-components-dm-auth.ts
|
|
8532
|
+
async function ensureDmComponentAuthorized(params) {
|
|
8533
|
+
const { ctx, interaction, user, componentLabel, replyOpts } = params;
|
|
8534
|
+
const dmPolicy = ctx.dmPolicy ?? "pairing";
|
|
8535
|
+
if (dmPolicy === "disabled") {
|
|
8536
|
+
logVerbose(`agent ${componentLabel}: blocked (DM policy disabled)`);
|
|
8537
|
+
await replySilently(interaction, {
|
|
8538
|
+
content: "DM interactions are disabled.",
|
|
8539
|
+
...replyOpts
|
|
8540
|
+
});
|
|
8541
|
+
return false;
|
|
8542
|
+
}
|
|
8543
|
+
const access = await resolveDiscordDmCommandAccess({
|
|
8544
|
+
accountId: ctx.accountId,
|
|
8545
|
+
dmPolicy,
|
|
8546
|
+
configuredAllowFrom: ctx.allowFrom ?? [],
|
|
8547
|
+
sender: {
|
|
8548
|
+
id: user.id,
|
|
8549
|
+
name: user.username,
|
|
8550
|
+
tag: formatDiscordUserTag(user)
|
|
8551
|
+
},
|
|
8552
|
+
allowNameMatching: isDangerousNameMatchingEnabled(ctx.discordConfig),
|
|
8553
|
+
cfg: ctx.cfg,
|
|
8554
|
+
token: ctx.token,
|
|
8555
|
+
readStoreAllowFrom: async ({ accountId, dmPolicy: dmPolicyLocal }) => await readChannelIngressStoreAllowFromForDmPolicy({
|
|
8556
|
+
provider: "discord",
|
|
8557
|
+
accountId,
|
|
8558
|
+
dmPolicy: dmPolicyLocal
|
|
8559
|
+
}),
|
|
8560
|
+
eventKind: "button"
|
|
8561
|
+
});
|
|
8562
|
+
if (access.senderAccess.decision === "allow") return true;
|
|
8563
|
+
if (access.senderAccess.decision !== "pairing") {
|
|
8564
|
+
logVerbose(`agent ${componentLabel}: blocked DM user ${user.id} (not in allowFrom)`);
|
|
8565
|
+
await replySilently(interaction, {
|
|
8566
|
+
content: `You are not authorized to use this ${componentLabel}.`,
|
|
8567
|
+
...replyOpts
|
|
8568
|
+
});
|
|
8569
|
+
return false;
|
|
8570
|
+
}
|
|
8571
|
+
if (!(await createChannelPairingChallengeIssuer({
|
|
8572
|
+
channel: "discord",
|
|
8573
|
+
accountId: ctx.accountId,
|
|
8574
|
+
upsertPairingRequest: async ({ id, meta }) => {
|
|
8575
|
+
return await upsertChannelPairingRequest$1({
|
|
8576
|
+
channel: "discord",
|
|
8577
|
+
id,
|
|
8578
|
+
accountId: ctx.accountId,
|
|
8579
|
+
meta
|
|
8580
|
+
});
|
|
8581
|
+
}
|
|
8582
|
+
})({
|
|
8583
|
+
senderId: user.id,
|
|
8584
|
+
senderIdLine: `Your Discord user id: ${user.id}`,
|
|
8585
|
+
meta: {
|
|
8586
|
+
tag: formatDiscordUserTag(user),
|
|
8587
|
+
name: user.username
|
|
8588
|
+
},
|
|
8589
|
+
sendPairingReply: async (text) => {
|
|
8590
|
+
await interaction.reply({
|
|
8591
|
+
content: text,
|
|
8592
|
+
...replyOpts
|
|
8593
|
+
});
|
|
8594
|
+
}
|
|
8595
|
+
})).created) await replySilently(interaction, {
|
|
8596
|
+
content: "Pairing already requested. Ask the bot owner to approve your code.",
|
|
8597
|
+
...replyOpts
|
|
8598
|
+
});
|
|
8599
|
+
return false;
|
|
8600
|
+
}
|
|
8601
|
+
async function ensureGroupDmComponentAuthorized(params) {
|
|
8602
|
+
const { ctx, interaction, channelId, componentLabel, replyOpts } = params;
|
|
8603
|
+
if (!(ctx.discordConfig?.dm?.groupEnabled ?? false)) {
|
|
8604
|
+
logVerbose(`agent ${componentLabel}: blocked group dm ${channelId} (group DMs disabled)`);
|
|
8605
|
+
await replySilently(interaction, {
|
|
8606
|
+
content: "Group DM interactions are disabled.",
|
|
8607
|
+
...replyOpts
|
|
8608
|
+
});
|
|
8609
|
+
return false;
|
|
8610
|
+
}
|
|
8611
|
+
const channelCtx = resolveDiscordChannelContext(interaction);
|
|
8612
|
+
if (resolveGroupDmAllow({
|
|
8613
|
+
channels: ctx.discordConfig?.dm?.groupChannels,
|
|
8614
|
+
channelId,
|
|
8615
|
+
channelName: channelCtx.channelName,
|
|
8616
|
+
channelSlug: channelCtx.channelSlug
|
|
8617
|
+
})) return true;
|
|
8618
|
+
logVerbose(`agent ${componentLabel}: blocked group dm ${channelId} (not allowlisted)`);
|
|
8619
|
+
await replySilently(interaction, {
|
|
8620
|
+
content: `You are not authorized to use this ${componentLabel}.`,
|
|
8621
|
+
...replyOpts
|
|
8622
|
+
});
|
|
8623
|
+
return false;
|
|
8624
|
+
}
|
|
8625
|
+
async function resolveInteractionContextWithDmAuth(params) {
|
|
8626
|
+
const interactionCtx = await resolveComponentInteractionContext({
|
|
8627
|
+
interaction: params.interaction,
|
|
8628
|
+
label: params.label,
|
|
8629
|
+
defer: params.defer
|
|
8630
|
+
});
|
|
8631
|
+
if (!interactionCtx) return null;
|
|
8632
|
+
if (interactionCtx.isDirectMessage) {
|
|
8633
|
+
if (!await ensureDmComponentAuthorized({
|
|
8634
|
+
ctx: params.ctx,
|
|
8635
|
+
interaction: params.interaction,
|
|
8636
|
+
user: interactionCtx.user,
|
|
8637
|
+
componentLabel: params.componentLabel,
|
|
8638
|
+
replyOpts: interactionCtx.replyOpts
|
|
8639
|
+
})) return null;
|
|
8640
|
+
}
|
|
8641
|
+
if (interactionCtx.isGroupDm) {
|
|
8642
|
+
if (!await ensureGroupDmComponentAuthorized({
|
|
8643
|
+
ctx: params.ctx,
|
|
8644
|
+
interaction: params.interaction,
|
|
8645
|
+
channelId: interactionCtx.channelId,
|
|
8646
|
+
componentLabel: params.componentLabel,
|
|
8647
|
+
replyOpts: interactionCtx.replyOpts
|
|
8648
|
+
})) return null;
|
|
8649
|
+
}
|
|
8650
|
+
return interactionCtx;
|
|
8651
|
+
}
|
|
8652
|
+
//#endregion
|
|
8653
|
+
//#region extensions/discord/src/monitor/agent-components-guild-auth.ts
|
|
8654
|
+
function resolveComponentRuntimeGroupPolicy(ctx) {
|
|
8655
|
+
return resolveOpenProviderRuntimeGroupPolicy({
|
|
8656
|
+
providerConfigPresent: ctx.cfg.channels?.discord !== void 0,
|
|
8657
|
+
groupPolicy: ctx.discordConfig?.groupPolicy,
|
|
8658
|
+
defaultGroupPolicy: ctx.cfg.channels?.defaults?.groupPolicy
|
|
8659
|
+
}).groupPolicy;
|
|
8660
|
+
}
|
|
8661
|
+
async function ensureGuildComponentMemberAllowed(params) {
|
|
8662
|
+
const { interaction, guildInfo, channelId, rawGuildId, channelCtx, memberRoleIds, user, replyOpts, componentLabel, unauthorizedReply } = params;
|
|
8663
|
+
if (!rawGuildId) return true;
|
|
8664
|
+
const replyUnauthorized = async () => {
|
|
8665
|
+
await replySilently(interaction, {
|
|
8666
|
+
content: unauthorizedReply,
|
|
8667
|
+
...replyOpts
|
|
8668
|
+
});
|
|
8669
|
+
};
|
|
8670
|
+
const channelConfig = resolveDiscordChannelConfigWithFallback({
|
|
8671
|
+
guildInfo,
|
|
8672
|
+
channelId,
|
|
8673
|
+
channelName: channelCtx.channelName,
|
|
8674
|
+
channelSlug: channelCtx.channelSlug,
|
|
8675
|
+
parentId: channelCtx.parentId,
|
|
8676
|
+
parentName: channelCtx.parentName,
|
|
8677
|
+
parentSlug: channelCtx.parentSlug,
|
|
8678
|
+
scope: channelCtx.isThread ? "thread" : "channel"
|
|
8679
|
+
});
|
|
8680
|
+
if (channelConfig?.enabled === false) {
|
|
8681
|
+
await replyUnauthorized();
|
|
8682
|
+
return false;
|
|
8683
|
+
}
|
|
8684
|
+
const channelAllowlistConfigured = Boolean(guildInfo?.channels) && Object.keys(guildInfo?.channels ?? {}).length > 0;
|
|
8685
|
+
const channelAllowed = channelConfig?.allowed !== false;
|
|
8686
|
+
if (!isDiscordGroupAllowedByPolicy({
|
|
8687
|
+
groupPolicy: params.groupPolicy,
|
|
8688
|
+
guildAllowlisted: Boolean(guildInfo),
|
|
8689
|
+
channelAllowlistConfigured,
|
|
8690
|
+
channelAllowed
|
|
8691
|
+
})) {
|
|
8692
|
+
await replyUnauthorized();
|
|
8693
|
+
return false;
|
|
8694
|
+
}
|
|
8695
|
+
if (channelConfig?.allowed === false) {
|
|
8696
|
+
await replyUnauthorized();
|
|
8697
|
+
return false;
|
|
8698
|
+
}
|
|
8699
|
+
const { memberAllowed } = resolveDiscordMemberAccessState({
|
|
8700
|
+
channelConfig,
|
|
8701
|
+
guildInfo,
|
|
8702
|
+
memberRoleIds,
|
|
8703
|
+
sender: {
|
|
8704
|
+
id: user.id,
|
|
8705
|
+
name: user.username,
|
|
8706
|
+
tag: user.discriminator ? `${user.username}#${user.discriminator}` : void 0
|
|
8707
|
+
},
|
|
8708
|
+
allowNameMatching: params.allowNameMatching
|
|
8709
|
+
});
|
|
8710
|
+
if (memberAllowed) return true;
|
|
8711
|
+
logVerbose(`agent ${componentLabel}: blocked user ${user.id} (not in users/roles allowlist)`);
|
|
8712
|
+
await replyUnauthorized();
|
|
8713
|
+
return false;
|
|
8714
|
+
}
|
|
8715
|
+
async function ensureComponentUserAllowed(params) {
|
|
8716
|
+
const allowList = normalizeDiscordAllowList(params.entry.allowedUsers, [
|
|
8717
|
+
"discord:",
|
|
8718
|
+
"user:",
|
|
8719
|
+
"pk:"
|
|
8720
|
+
]);
|
|
8721
|
+
if (!allowList) return true;
|
|
8722
|
+
if (resolveDiscordAllowListMatch({
|
|
8723
|
+
allowList,
|
|
8724
|
+
candidate: {
|
|
8725
|
+
id: params.user.id,
|
|
8726
|
+
name: params.user.username,
|
|
8727
|
+
tag: formatDiscordUserTag(params.user)
|
|
8728
|
+
},
|
|
8729
|
+
allowNameMatching: params.allowNameMatching
|
|
8730
|
+
}).allowed) return true;
|
|
8731
|
+
logVerbose(`discord component ${params.componentLabel}: blocked user ${params.user.id} (not in allowedUsers)`);
|
|
8732
|
+
await replySilently(params.interaction, {
|
|
8733
|
+
content: params.unauthorizedReply,
|
|
8734
|
+
...params.replyOpts
|
|
8735
|
+
});
|
|
8736
|
+
return false;
|
|
8737
|
+
}
|
|
8738
|
+
async function ensureAgentComponentInteractionAllowed(params) {
|
|
8739
|
+
const guildInfo = resolveDiscordGuildEntry({
|
|
8740
|
+
guild: params.interaction.guild ?? void 0,
|
|
8741
|
+
guildId: params.rawGuildId,
|
|
8742
|
+
guildEntries: params.ctx.guildEntries
|
|
8743
|
+
});
|
|
8744
|
+
const channelCtx = resolveDiscordChannelContext(params.interaction);
|
|
8745
|
+
if (!await ensureGuildComponentMemberAllowed({
|
|
8746
|
+
interaction: params.interaction,
|
|
8747
|
+
guildInfo,
|
|
8748
|
+
channelId: params.channelId,
|
|
8749
|
+
rawGuildId: params.rawGuildId,
|
|
8750
|
+
channelCtx,
|
|
8751
|
+
memberRoleIds: params.memberRoleIds,
|
|
8752
|
+
user: params.user,
|
|
8753
|
+
replyOpts: params.replyOpts,
|
|
8754
|
+
componentLabel: params.componentLabel,
|
|
8755
|
+
unauthorizedReply: params.unauthorizedReply,
|
|
8756
|
+
allowNameMatching: isDangerousNameMatchingEnabled(params.ctx.discordConfig),
|
|
8757
|
+
groupPolicy: resolveComponentRuntimeGroupPolicy(params.ctx)
|
|
8758
|
+
})) return null;
|
|
8759
|
+
return { parentId: channelCtx.parentId };
|
|
8760
|
+
}
|
|
8761
|
+
async function resolveAuthorizedComponentInteraction(params) {
|
|
8762
|
+
const interactionCtx = await resolveInteractionContextWithDmAuth({
|
|
8763
|
+
ctx: params.ctx,
|
|
8764
|
+
interaction: params.interaction,
|
|
8765
|
+
label: params.label,
|
|
8766
|
+
componentLabel: params.componentLabel,
|
|
8767
|
+
defer: params.defer
|
|
8768
|
+
});
|
|
8769
|
+
if (!interactionCtx) return null;
|
|
8770
|
+
const { channelId, user, replyOpts, rawGuildId, memberRoleIds } = interactionCtx;
|
|
8771
|
+
const guildInfo = resolveDiscordGuildEntry({
|
|
8772
|
+
guild: params.interaction.guild ?? void 0,
|
|
8773
|
+
guildId: rawGuildId,
|
|
8774
|
+
guildEntries: params.ctx.guildEntries
|
|
8775
|
+
});
|
|
8776
|
+
const channelCtx = resolveDiscordChannelContext(params.interaction);
|
|
8777
|
+
const allowNameMatching = isDangerousNameMatchingEnabled(params.ctx.discordConfig);
|
|
8778
|
+
const channelConfig = resolveDiscordChannelConfigWithFallback({
|
|
8779
|
+
guildInfo,
|
|
8780
|
+
channelId,
|
|
8781
|
+
channelName: channelCtx.channelName,
|
|
8782
|
+
channelSlug: channelCtx.channelSlug,
|
|
8783
|
+
parentId: channelCtx.parentId,
|
|
8784
|
+
parentName: channelCtx.parentName,
|
|
8785
|
+
parentSlug: channelCtx.parentSlug,
|
|
8786
|
+
scope: channelCtx.isThread ? "thread" : "channel"
|
|
8787
|
+
});
|
|
8788
|
+
if (!await ensureGuildComponentMemberAllowed({
|
|
8789
|
+
interaction: params.interaction,
|
|
8790
|
+
guildInfo,
|
|
8791
|
+
channelId,
|
|
8792
|
+
rawGuildId,
|
|
8793
|
+
channelCtx,
|
|
8794
|
+
memberRoleIds,
|
|
8795
|
+
user,
|
|
8796
|
+
replyOpts,
|
|
8797
|
+
componentLabel: params.componentLabel,
|
|
8798
|
+
unauthorizedReply: params.unauthorizedReply,
|
|
8799
|
+
allowNameMatching,
|
|
8800
|
+
groupPolicy: resolveComponentRuntimeGroupPolicy(params.ctx)
|
|
8801
|
+
})) return null;
|
|
8802
|
+
return {
|
|
8803
|
+
interactionCtx,
|
|
8804
|
+
channelCtx,
|
|
8805
|
+
guildInfo,
|
|
8806
|
+
channelConfig,
|
|
8807
|
+
allowNameMatching,
|
|
8808
|
+
commandAuthorized: await resolveComponentCommandAuthorized({
|
|
8809
|
+
ctx: params.ctx,
|
|
8810
|
+
interactionCtx,
|
|
8811
|
+
channelConfig,
|
|
8812
|
+
guildInfo,
|
|
8813
|
+
allowNameMatching
|
|
8814
|
+
}),
|
|
8815
|
+
user,
|
|
8816
|
+
replyOpts
|
|
8713
8817
|
};
|
|
8714
8818
|
}
|
|
8715
|
-
async function
|
|
8716
|
-
const
|
|
8717
|
-
if (
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
|
|
8819
|
+
async function resolveComponentCommandAuthorized(params) {
|
|
8820
|
+
const { ctx, interactionCtx, channelConfig, guildInfo } = params;
|
|
8821
|
+
if (interactionCtx.isDirectMessage) return true;
|
|
8822
|
+
const { ownerAllowList, ownerAllowed: ownerOk } = resolveDiscordOwnerAccess({
|
|
8823
|
+
allowFrom: ctx.allowFrom,
|
|
8824
|
+
sender: {
|
|
8825
|
+
id: interactionCtx.user.id,
|
|
8826
|
+
name: interactionCtx.user.username,
|
|
8827
|
+
tag: formatDiscordUserTag(interactionCtx.user)
|
|
8828
|
+
},
|
|
8829
|
+
allowNameMatching: params.allowNameMatching
|
|
8830
|
+
});
|
|
8831
|
+
const { hasAccessRestrictions, memberAllowed } = resolveDiscordMemberAccessState({
|
|
8832
|
+
channelConfig,
|
|
8833
|
+
guildInfo,
|
|
8834
|
+
memberRoleIds: interactionCtx.memberRoleIds,
|
|
8835
|
+
sender: {
|
|
8836
|
+
id: interactionCtx.user.id,
|
|
8837
|
+
name: interactionCtx.user.username,
|
|
8838
|
+
tag: formatDiscordUserTag(interactionCtx.user)
|
|
8839
|
+
},
|
|
8840
|
+
allowNameMatching: params.allowNameMatching
|
|
8841
|
+
});
|
|
8842
|
+
const useAccessGroups = ctx.cfg.commands?.useAccessGroups !== false;
|
|
8843
|
+
return resolveCommandAuthorizedFromAuthorizers({
|
|
8844
|
+
useAccessGroups,
|
|
8845
|
+
authorizers: useAccessGroups ? [{
|
|
8846
|
+
configured: ownerAllowList != null,
|
|
8847
|
+
allowed: ownerOk
|
|
8848
|
+
}, {
|
|
8849
|
+
configured: hasAccessRestrictions,
|
|
8850
|
+
allowed: memberAllowed
|
|
8851
|
+
}] : [{
|
|
8852
|
+
configured: hasAccessRestrictions,
|
|
8853
|
+
allowed: memberAllowed
|
|
8854
|
+
}],
|
|
8855
|
+
modeWhenAccessGroupsOff: "configured"
|
|
8721
8856
|
});
|
|
8722
|
-
return false;
|
|
8723
|
-
}
|
|
8724
|
-
function createDiscordVoiceCommand(params) {
|
|
8725
|
-
const resolveSessionChannelId = (manager, guildId) => manager.status().find((entry) => entry.guildId === guildId)?.channelId;
|
|
8726
|
-
class JoinCommand extends Command {
|
|
8727
|
-
constructor(..._args) {
|
|
8728
|
-
super(..._args);
|
|
8729
|
-
this.name = "join";
|
|
8730
|
-
this.description = "Join a voice channel";
|
|
8731
|
-
this.defer = true;
|
|
8732
|
-
this.ephemeral = params.ephemeralDefault;
|
|
8733
|
-
this.options = [{
|
|
8734
|
-
name: "channel",
|
|
8735
|
-
description: "Voice channel to join",
|
|
8736
|
-
type: ApplicationCommandOptionType.Channel,
|
|
8737
|
-
required: true,
|
|
8738
|
-
channel_types: VOICE_CHANNEL_TYPES
|
|
8739
|
-
}];
|
|
8740
|
-
}
|
|
8741
|
-
async run(interaction) {
|
|
8742
|
-
const channel = await interaction.options.getChannel("channel", true);
|
|
8743
|
-
if (!channel || !("id" in channel)) {
|
|
8744
|
-
await interaction.reply({
|
|
8745
|
-
content: "Voice channel not found.",
|
|
8746
|
-
ephemeral: true
|
|
8747
|
-
});
|
|
8748
|
-
return;
|
|
8749
|
-
}
|
|
8750
|
-
const access = await authorizeVoiceCommand(interaction, params, { channelOverride: {
|
|
8751
|
-
id: channel.id,
|
|
8752
|
-
name: resolveDiscordChannelNameSafe(channel)
|
|
8753
|
-
} });
|
|
8754
|
-
if (!access.ok) {
|
|
8755
|
-
await interaction.reply({
|
|
8756
|
-
content: access.message ?? "Not authorized.",
|
|
8757
|
-
ephemeral: true
|
|
8758
|
-
});
|
|
8759
|
-
return;
|
|
8760
|
-
}
|
|
8761
|
-
if (!isVoiceChannelType(channel.type)) {
|
|
8762
|
-
await interaction.reply({
|
|
8763
|
-
content: "That is not a voice channel.",
|
|
8764
|
-
ephemeral: true
|
|
8765
|
-
});
|
|
8766
|
-
return;
|
|
8767
|
-
}
|
|
8768
|
-
const guildId = access.guildId ?? ("guildId" in channel ? channel.guildId : void 0);
|
|
8769
|
-
if (!guildId) {
|
|
8770
|
-
await interaction.reply({
|
|
8771
|
-
content: "Unable to resolve guild for this voice channel.",
|
|
8772
|
-
ephemeral: true
|
|
8773
|
-
});
|
|
8774
|
-
return;
|
|
8775
|
-
}
|
|
8776
|
-
const manager = params.getManager();
|
|
8777
|
-
if (!manager) {
|
|
8778
|
-
await interaction.reply({
|
|
8779
|
-
content: "Voice manager is not available yet.",
|
|
8780
|
-
ephemeral: true
|
|
8781
|
-
});
|
|
8782
|
-
return;
|
|
8783
|
-
}
|
|
8784
|
-
const result = await manager.join({
|
|
8785
|
-
guildId,
|
|
8786
|
-
channelId: channel.id
|
|
8787
|
-
});
|
|
8788
|
-
await interaction.reply({
|
|
8789
|
-
content: result.message,
|
|
8790
|
-
ephemeral: true
|
|
8791
|
-
});
|
|
8792
|
-
}
|
|
8793
|
-
}
|
|
8794
|
-
class LeaveCommand extends Command {
|
|
8795
|
-
constructor(..._args2) {
|
|
8796
|
-
super(..._args2);
|
|
8797
|
-
this.name = "leave";
|
|
8798
|
-
this.description = "Leave the current voice channel";
|
|
8799
|
-
this.defer = true;
|
|
8800
|
-
this.ephemeral = params.ephemeralDefault;
|
|
8801
|
-
}
|
|
8802
|
-
async run(interaction) {
|
|
8803
|
-
const runtimeContext = await resolveVoiceCommandRuntimeContext(interaction, params);
|
|
8804
|
-
if (!runtimeContext) return;
|
|
8805
|
-
const sessionChannelId = resolveSessionChannelId(runtimeContext.manager, runtimeContext.guildId);
|
|
8806
|
-
if (!await ensureVoiceCommandAccess({
|
|
8807
|
-
interaction,
|
|
8808
|
-
context: params,
|
|
8809
|
-
channelOverride: sessionChannelId ? { id: sessionChannelId } : void 0
|
|
8810
|
-
})) return;
|
|
8811
|
-
const result = await runtimeContext.manager.leave({ guildId: runtimeContext.guildId });
|
|
8812
|
-
await interaction.reply({
|
|
8813
|
-
content: result.message,
|
|
8814
|
-
ephemeral: true
|
|
8815
|
-
});
|
|
8816
|
-
}
|
|
8817
|
-
}
|
|
8818
|
-
class StatusCommand extends Command {
|
|
8819
|
-
constructor(..._args3) {
|
|
8820
|
-
super(..._args3);
|
|
8821
|
-
this.name = "status";
|
|
8822
|
-
this.description = "Show active voice sessions";
|
|
8823
|
-
this.defer = true;
|
|
8824
|
-
this.ephemeral = params.ephemeralDefault;
|
|
8825
|
-
}
|
|
8826
|
-
async run(interaction) {
|
|
8827
|
-
const runtimeContext = await resolveVoiceCommandRuntimeContext(interaction, params);
|
|
8828
|
-
if (!runtimeContext) return;
|
|
8829
|
-
const sessions = runtimeContext.manager.status().filter((entry) => entry.guildId === runtimeContext.guildId);
|
|
8830
|
-
const sessionChannelId = sessions[0]?.channelId;
|
|
8831
|
-
if (!await ensureVoiceCommandAccess({
|
|
8832
|
-
interaction,
|
|
8833
|
-
context: params,
|
|
8834
|
-
channelOverride: sessionChannelId ? { id: sessionChannelId } : void 0
|
|
8835
|
-
})) return;
|
|
8836
|
-
if (sessions.length === 0) {
|
|
8837
|
-
await interaction.reply({
|
|
8838
|
-
content: "No active voice sessions.",
|
|
8839
|
-
ephemeral: true
|
|
8840
|
-
});
|
|
8841
|
-
return;
|
|
8842
|
-
}
|
|
8843
|
-
const lines = sessions.map((entry) => `• ${formatMention({ channelId: entry.channelId })} (guild ${entry.guildId})`);
|
|
8844
|
-
await interaction.reply({
|
|
8845
|
-
content: lines.join("\n"),
|
|
8846
|
-
ephemeral: true
|
|
8847
|
-
});
|
|
8848
|
-
}
|
|
8849
|
-
}
|
|
8850
|
-
return new class extends CommandWithSubcommands {
|
|
8851
|
-
constructor(..._args4) {
|
|
8852
|
-
super(..._args4);
|
|
8853
|
-
this.name = "vc";
|
|
8854
|
-
this.description = "Voice channel controls";
|
|
8855
|
-
this.subcommands = [
|
|
8856
|
-
new JoinCommand(),
|
|
8857
|
-
new LeaveCommand(),
|
|
8858
|
-
new StatusCommand()
|
|
8859
|
-
];
|
|
8860
|
-
}
|
|
8861
|
-
}();
|
|
8862
|
-
}
|
|
8863
|
-
function isVoiceChannelType(type) {
|
|
8864
|
-
return type === ChannelType.GuildVoice || type === ChannelType.GuildStageVoice;
|
|
8865
8857
|
}
|
|
8866
8858
|
//#endregion
|
|
8867
8859
|
//#region extensions/discord/src/monitor/agent-components-data.ts
|
|
@@ -9174,7 +9166,7 @@ async function deliverDiscordReply(params) {
|
|
|
9174
9166
|
//#endregion
|
|
9175
9167
|
//#region extensions/discord/src/monitor/agent-components.dispatch.ts
|
|
9176
9168
|
const loadConversationRuntime$1 = createLazyRuntimeModule(() => import("./agent-components.runtime-CEPrf2SY.js"));
|
|
9177
|
-
const loadTypingRuntime = createLazyRuntimeModule(() => import("./typing-
|
|
9169
|
+
const loadTypingRuntime = createLazyRuntimeModule(() => import("./typing-wxtm1NlF.js").then((n) => n.n));
|
|
9178
9170
|
function buildDiscordComponentConversationLabel(params) {
|
|
9179
9171
|
if (params.interactionCtx.isDirectMessage) return buildDirectLabel(params.interactionCtx.user);
|
|
9180
9172
|
if (params.interactionCtx.isGroupDm) return `Group DM #${params.channelCtx.channelName ?? params.interactionCtx.channelId} channel id:${params.interactionCtx.channelId}`;
|
|
@@ -9283,7 +9275,7 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
9283
9275
|
previousTimestamp,
|
|
9284
9276
|
envelope: envelopeOptions
|
|
9285
9277
|
});
|
|
9286
|
-
const { createReplyReferencePlanner,
|
|
9278
|
+
const { createReplyReferencePlanner, finalizeInboundContext, resolveChunkMode, resolveTextChunkLimit } = await (async () => {
|
|
9287
9279
|
return { ...await loadConversationRuntime$1() };
|
|
9288
9280
|
})();
|
|
9289
9281
|
const ctxPayload = finalizeInboundContext({
|
|
@@ -9359,12 +9351,11 @@ async function dispatchDiscordComponentEvent(params) {
|
|
|
9359
9351
|
cfg: ctx.cfg,
|
|
9360
9352
|
channel: "discord",
|
|
9361
9353
|
accountId,
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9354
|
+
route: {
|
|
9355
|
+
agentId,
|
|
9356
|
+
sessionKey
|
|
9357
|
+
},
|
|
9365
9358
|
ctxPayload,
|
|
9366
|
-
recordInboundSession,
|
|
9367
|
-
dispatchReplyWithBufferedBlockDispatcher,
|
|
9368
9359
|
record: {
|
|
9369
9360
|
updateLastRoute: interactionCtx.isDirectMessage ? {
|
|
9370
9361
|
sessionKey: inboundLastRouteSessionKey,
|
|
@@ -9587,7 +9578,7 @@ async function dispatchPluginDiscordInteractiveEvent(params) {
|
|
|
9587
9578
|
}
|
|
9588
9579
|
//#endregion
|
|
9589
9580
|
//#region extensions/discord/src/monitor/agent-components.handlers.ts
|
|
9590
|
-
const loadComponentsRuntime = createLazyRuntimeModule(() => import("./outbound-session-route-
|
|
9581
|
+
const loadComponentsRuntime = createLazyRuntimeModule(() => import("./outbound-session-route-M2bEY9tI.js").then((n) => n.n));
|
|
9591
9582
|
async function handleDiscordComponentEvent(params) {
|
|
9592
9583
|
const parsed = parseDiscordComponentData(params.data, resolveInteractionCustomId(params.interaction));
|
|
9593
9584
|
if (!parsed) {
|
|
@@ -10276,6 +10267,74 @@ function createDiscordExecApprovalButtonContext(params) {
|
|
|
10276
10267
|
};
|
|
10277
10268
|
}
|
|
10278
10269
|
//#endregion
|
|
10270
|
+
//#region extensions/discord/src/monitor/questions.ts
|
|
10271
|
+
var QuestionButton = class extends Button {
|
|
10272
|
+
constructor(ctx) {
|
|
10273
|
+
super();
|
|
10274
|
+
this.ctx = ctx;
|
|
10275
|
+
this.label = "question";
|
|
10276
|
+
this.customId = "ocq:id=seed;i=0";
|
|
10277
|
+
this.style = ButtonStyle.Primary;
|
|
10278
|
+
}
|
|
10279
|
+
async run(interaction, data) {
|
|
10280
|
+
const callback = parseDiscordQuestionData(data);
|
|
10281
|
+
if (!callback) {
|
|
10282
|
+
await interaction.reply({
|
|
10283
|
+
content: "This question is no longer valid.",
|
|
10284
|
+
ephemeral: true
|
|
10285
|
+
});
|
|
10286
|
+
return;
|
|
10287
|
+
}
|
|
10288
|
+
if (!await this.ctx.authorizeQuestion(interaction)) return;
|
|
10289
|
+
try {
|
|
10290
|
+
await interaction.acknowledge();
|
|
10291
|
+
} catch {}
|
|
10292
|
+
let result;
|
|
10293
|
+
try {
|
|
10294
|
+
result = await this.ctx.resolveQuestion({
|
|
10295
|
+
cfg: this.ctx.cfg,
|
|
10296
|
+
questionId: callback.questionId,
|
|
10297
|
+
optionIndex: callback.optionIndex,
|
|
10298
|
+
senderId: interaction.userId,
|
|
10299
|
+
clientDisplayName: `Discord question (${this.ctx.accountId})`
|
|
10300
|
+
});
|
|
10301
|
+
} catch {
|
|
10302
|
+
try {
|
|
10303
|
+
await interaction.followUp({
|
|
10304
|
+
content: "Could not submit this answer.",
|
|
10305
|
+
ephemeral: true
|
|
10306
|
+
});
|
|
10307
|
+
} catch {}
|
|
10308
|
+
return;
|
|
10309
|
+
}
|
|
10310
|
+
try {
|
|
10311
|
+
await interaction.followUp({
|
|
10312
|
+
content: result.status === "answered" ? "Answer submitted." : "This question was already answered.",
|
|
10313
|
+
ephemeral: true
|
|
10314
|
+
});
|
|
10315
|
+
} catch {}
|
|
10316
|
+
}
|
|
10317
|
+
};
|
|
10318
|
+
function createDiscordQuestionButton(params) {
|
|
10319
|
+
const authContext = params.authContext ?? {
|
|
10320
|
+
cfg: params.cfg,
|
|
10321
|
+
accountId: params.accountId
|
|
10322
|
+
};
|
|
10323
|
+
return new QuestionButton({
|
|
10324
|
+
cfg: params.cfg,
|
|
10325
|
+
accountId: params.accountId,
|
|
10326
|
+
resolveQuestion: params.resolveQuestion ?? questionGatewayRuntime.resolveOption,
|
|
10327
|
+
authorizeQuestion: params.authorizeQuestion ?? (async (interaction) => Boolean(await resolveAuthorizedComponentInteraction({
|
|
10328
|
+
ctx: authContext,
|
|
10329
|
+
interaction,
|
|
10330
|
+
label: "discord question",
|
|
10331
|
+
componentLabel: "button",
|
|
10332
|
+
unauthorizedReply: "You are not authorized to answer this question.",
|
|
10333
|
+
defer: false
|
|
10334
|
+
})))
|
|
10335
|
+
});
|
|
10336
|
+
}
|
|
10337
|
+
//#endregion
|
|
10279
10338
|
//#region extensions/discord/src/monitor/provider.interactions.ts
|
|
10280
10339
|
function createDiscordProviderInteractionSurface(params) {
|
|
10281
10340
|
const createNativeCommand = params.createNativeCommand ?? createDiscordNativeCommand;
|
|
@@ -10320,6 +10379,20 @@ function createDiscordProviderInteractionSurface(params) {
|
|
|
10320
10379
|
abortSignal: params.abortSignal
|
|
10321
10380
|
});
|
|
10322
10381
|
const components = [
|
|
10382
|
+
createDiscordQuestionButton({
|
|
10383
|
+
cfg: params.cfg,
|
|
10384
|
+
accountId: params.accountId,
|
|
10385
|
+
authContext: {
|
|
10386
|
+
cfg: params.cfg,
|
|
10387
|
+
accountId: params.accountId,
|
|
10388
|
+
discordConfig: params.discordConfig,
|
|
10389
|
+
runtime: params.runtime,
|
|
10390
|
+
token: params.token,
|
|
10391
|
+
guildEntries: params.guildEntries,
|
|
10392
|
+
allowFrom: params.allowFrom,
|
|
10393
|
+
dmPolicy: params.dmPolicy
|
|
10394
|
+
}
|
|
10395
|
+
}),
|
|
10323
10396
|
createDiscordCommandArgFallbackButton({
|
|
10324
10397
|
cfg: params.cfg,
|
|
10325
10398
|
discordConfig: params.discordConfig,
|
|
@@ -10915,7 +10988,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10915
10988
|
runtime,
|
|
10916
10989
|
botUserId
|
|
10917
10990
|
});
|
|
10918
|
-
const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-
|
|
10991
|
+
const { setDiscordTranscriptsVoiceManager } = await import("./transcripts-source-DjDbt14x.js").then((n) => n.n);
|
|
10919
10992
|
setDiscordTranscriptsVoiceManager({
|
|
10920
10993
|
accountId: account.accountId,
|
|
10921
10994
|
manager: voiceManager
|
|
@@ -10927,6 +11000,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
10927
11000
|
registerDiscordListener(client.listeners, new DiscordVoiceStateUpdateListener(voiceManager));
|
|
10928
11001
|
}
|
|
10929
11002
|
const messageHandler = discordProviderSessionRuntime.createDiscordMessageHandler({
|
|
11003
|
+
client,
|
|
10930
11004
|
cfg,
|
|
10931
11005
|
discordConfig: discordCfg,
|
|
10932
11006
|
accountId: account.accountId,
|
|
@@ -11006,7 +11080,7 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
11006
11080
|
gatewayRuntimeReadyTimeoutMs: account.config.gatewayRuntimeReadyTimeoutMs
|
|
11007
11081
|
});
|
|
11008
11082
|
} finally {
|
|
11009
|
-
cleanupDiscordProviderStartup({
|
|
11083
|
+
await cleanupDiscordProviderStartup({
|
|
11010
11084
|
deactivateMessageHandler,
|
|
11011
11085
|
autoPresenceController,
|
|
11012
11086
|
setStatus: opts.setStatus,
|
|
@@ -11021,4 +11095,4 @@ async function monitorDiscordProvider(opts = {}) {
|
|
|
11021
11095
|
}
|
|
11022
11096
|
}
|
|
11023
11097
|
//#endregion
|
|
11024
|
-
export {
|
|
11098
|
+
export { resolveDiscordDmCommandAccess as A, mapGatewayDispatchData as C, resolveDiscordReplyTarget as D, resolveDiscordAutoThreadReplyPlan as E, resolveDiscordThreadStarter as O, handleDiscordDmCommandDecision as S, threading_exports as T, createDiscordSupplementalContextAccessChecker as _, buildDirectLabel as a, resolveDiscordEffectiveRoute as b, resolveDiscordVoiceAccess as c, resolveDiscordGatewayIntents as d, waitForDiscordGatewayPluginRegistration as f, buildDiscordInboundAccessContext as g, buildDiscordGroupSystemPrompt as h, sanitizeDiscordFrontChannelReplyPayloads as i, resolveDiscordTextCommandAccess as j, sanitizeDiscordThreadName as k, authorizeDiscordVoiceIngress as l, createDiscordNativeCommand as m, deliverDiscordReply as n, buildGuildLabel as o, resolveDiscordVoiceEnabled as p, formatDiscordReplyDeliveryFailure as r, resolveReplyContext as s, monitorDiscordProvider as t, createDiscordGatewayPlugin as u, buildDiscordRoutePeer as v, registerDiscordListener as w, shouldIgnoreStaleDiscordRouteBinding as x, resolveDiscordConversationRoute as y };
|