import { Button, Row, Separator, TextDisplay, serializePayload, type MessagePayloadObject, type TopLevelComponents, } from "@buape/carbon"; import { ButtonStyle, Routes } 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 { DiscordExecApprovalConfig, OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; import type { ExecApprovalActionDescriptor, ExecApprovalDecision, } from "openclaw/plugin-sdk/infra-runtime"; import { logDebug, logError, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime"; import { shouldHandleDiscordApprovalRequest } from "./approval-shared.js"; import { isDiscordExecApprovalClientEnabled } from "./exec-approvals.js"; import { createDiscordClient, stripUndefinedFields } from "./send.shared.js"; import { DiscordUiContainer } from "./ui.js"; type PendingApproval = { discordMessageId: string; discordChannelId: string; }; type DiscordPendingDelivery = { body: ReturnType; }; type PreparedDeliveryTarget = { discordChannelId: string; recipientUserId?: string; }; export 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