// Discord plugin module implements approval handler behavior. import { ButtonStyle } from "discord-api-types/v10"; import type { ChannelApprovalCapabilityHandlerContext, ExecApprovalExpiredView, ExecApprovalPendingView, ExecApprovalResolvedView, PendingApprovalView, PluginApprovalExpiredView, PluginApprovalPendingView, PluginApprovalResolvedView, } from "openclaw/plugin-sdk/approval-handler-runtime"; import { createChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-runtime"; import type { ExecApprovalActionDescriptor } from "openclaw/plugin-sdk/approval-reply-runtime"; import type { DiscordExecApprovalConfig, OpenClawConfig, } from "openclaw/plugin-sdk/config-contracts"; import { logDebug, logError } from "openclaw/plugin-sdk/logging-core"; import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime"; import { buildExecApprovalCustomId } from "./approval-custom-id.js"; import { DISCORD_APPROVAL_ALLOWED_MENTIONS, formatDiscordApprovalDisplayValue, } from "./approval-message-safety.js"; import { shouldHandleDiscordApprovalRequest } from "./approval-shared.js"; import { isDiscordExecApprovalClientEnabled } from "./exec-approvals.js"; import { Button, createChannelMessage, createUserDmChannel, deleteChannelMessage, editChannelMessage, Row, Separator, TextDisplay, serializePayload, type MessagePayloadObject, type TopLevelComponents, } from "./internal/discord.js"; import { createDiscordClient, createDiscordMessageNonce, stripUndefinedFields, } from "./send.shared.js"; import { DiscordUiContainer } from "./ui.js"; export { buildExecApprovalCustomId }; type PendingApproval = { discordMessageId: string; discordChannelId: string; }; type DiscordPendingDelivery = { body: ReturnType; }; type PreparedDeliveryTarget = { discordChannelId: string; recipientUserId?: string; }; type DiscordApprovalHandlerContext = { token: string; config: DiscordExecApprovalConfig; }; function resolveHandlerContext(params: ChannelApprovalCapabilityHandlerContext): { accountId: string; context: DiscordApprovalHandlerContext; } | null { const context = params.context as DiscordApprovalHandlerContext | undefined; const accountId = normalizeOptionalString(params.accountId) ?? ""; if (!context?.token || !accountId) { return null; } return { accountId, context }; } class ExecApprovalContainer extends DiscordUiContainer { constructor(params: { cfg: OpenClawConfig; accountId: string; title: string; description?: string; commandPreview: string; commandSecondaryPreview?: string | null; metadataLines?: string[]; actionRow?: Row