diff --git a/src/discord/monitor/exec-approvals.ts b/src/discord/monitor/exec-approvals.ts index f426ae51903..e8583475e30 100644 --- a/src/discord/monitor/exec-approvals.ts +++ b/src/discord/monitor/exec-approvals.ts @@ -13,9 +13,8 @@ import { ButtonStyle, Routes } from "discord-api-types/v10"; import type { OpenClawConfig } from "../../config/config.js"; import { loadSessionStore, resolveStorePath } from "../../config/sessions.js"; import type { DiscordExecApprovalConfig } from "../../config/types.discord.js"; -import { buildGatewayConnectionDetails } from "../../gateway/call.js"; import { GatewayClient } from "../../gateway/client.js"; -import { resolveGatewayConnectionAuth } from "../../gateway/connection-auth.js"; +import { createOperatorApprovalsGatewayClient } from "../../gateway/operator-approvals-client.js"; import type { EventFrame } from "../../gateway/protocol/index.js"; import { getExecApprovalApproverDmNoticeText } from "../../infra/exec-approval-reply.js"; import type { @@ -27,11 +26,7 @@ import { logDebug, logError } from "../../logger.js"; import { normalizeAccountId, resolveAgentIdFromSessionKey } from "../../routing/session-key.js"; import type { RuntimeEnv } from "../../runtime.js"; import { compileSafeRegex, testRegexWithBoundedInput } from "../../security/safe-regex.js"; -import { - GATEWAY_CLIENT_MODES, - GATEWAY_CLIENT_NAMES, - normalizeMessageChannel, -} from "../../utils/message-channel.js"; +import { normalizeMessageChannel } from "../../utils/message-channel.js"; import { createDiscordClient, stripUndefinedFields } from "../send.shared.js"; import { DiscordUiContainer } from "../ui.js"; @@ -408,31 +403,10 @@ export class DiscordExecApprovalHandler { logDebug("discord exec approvals: starting handler"); - const { url: gatewayUrl, urlSource } = buildGatewayConnectionDetails({ + this.gatewayClient = await createOperatorApprovalsGatewayClient({ config: this.opts.cfg, - url: this.opts.gatewayUrl, - }); - const gatewayUrlOverrideSource = - urlSource === "cli --url" - ? "cli" - : urlSource === "env OPENCLAW_GATEWAY_URL" - ? "env" - : undefined; - const auth = await resolveGatewayConnectionAuth({ - config: this.opts.cfg, - env: process.env, - urlOverride: gatewayUrlOverrideSource ? gatewayUrl : undefined, - urlOverrideSource: gatewayUrlOverrideSource, - }); - - this.gatewayClient = new GatewayClient({ - url: gatewayUrl, - token: auth.token, - password: auth.password, - clientName: GATEWAY_CLIENT_NAMES.GATEWAY_CLIENT, + gatewayUrl: this.opts.gatewayUrl, clientDisplayName: "Discord Exec Approvals", - mode: GATEWAY_CLIENT_MODES.BACKEND, - scopes: ["operator.approvals"], onEvent: (evt) => this.handleGatewayEvent(evt), onHelloOk: () => { logDebug("discord exec approvals: connected to gateway"); diff --git a/src/gateway/operator-approvals-client.ts b/src/gateway/operator-approvals-client.ts new file mode 100644 index 00000000000..82ea7c80413 --- /dev/null +++ b/src/gateway/operator-approvals-client.ts @@ -0,0 +1,46 @@ +import type { OpenClawConfig } from "../config/config.js"; +import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js"; +import { buildGatewayConnectionDetails } from "./call.js"; +import { GatewayClient, type GatewayClientOptions } from "./client.js"; +import { resolveGatewayConnectionAuth } from "./connection-auth.js"; + +export async function createOperatorApprovalsGatewayClient( + params: Pick< + GatewayClientOptions, + "clientDisplayName" | "onClose" | "onConnectError" | "onEvent" | "onHelloOk" + > & { + config: OpenClawConfig; + gatewayUrl?: string; + }, +): Promise { + const { url: gatewayUrl, urlSource } = buildGatewayConnectionDetails({ + config: params.config, + url: params.gatewayUrl, + }); + const gatewayUrlOverrideSource = + urlSource === "cli --url" + ? "cli" + : urlSource === "env OPENCLAW_GATEWAY_URL" + ? "env" + : undefined; + const auth = await resolveGatewayConnectionAuth({ + config: params.config, + env: process.env, + urlOverride: gatewayUrlOverrideSource ? gatewayUrl : undefined, + urlOverrideSource: gatewayUrlOverrideSource, + }); + + return new GatewayClient({ + url: gatewayUrl, + token: auth.token, + password: auth.password, + clientName: GATEWAY_CLIENT_NAMES.GATEWAY_CLIENT, + clientDisplayName: params.clientDisplayName, + mode: GATEWAY_CLIENT_MODES.BACKEND, + scopes: ["operator.approvals"], + onEvent: params.onEvent, + onHelloOk: params.onHelloOk, + onConnectError: params.onConnectError, + onClose: params.onClose, + }); +} diff --git a/src/telegram/exec-approvals-handler.ts b/src/telegram/exec-approvals-handler.ts index cc3d735e6a6..1a2e4ce21ce 100644 --- a/src/telegram/exec-approvals-handler.ts +++ b/src/telegram/exec-approvals-handler.ts @@ -1,8 +1,7 @@ import type { OpenClawConfig } from "../config/config.js"; import { loadSessionStore, resolveStorePath } from "../config/sessions.js"; -import { buildGatewayConnectionDetails } from "../gateway/call.js"; import { GatewayClient } from "../gateway/client.js"; -import { resolveGatewayConnectionAuth } from "../gateway/connection-auth.js"; +import { createOperatorApprovalsGatewayClient } from "../gateway/operator-approvals-client.js"; import type { EventFrame } from "../gateway/protocol/index.js"; import { buildExecApprovalPendingReplyPayload, @@ -14,7 +13,6 @@ import { createSubsystemLogger } from "../logging/subsystem.js"; import { normalizeAccountId, parseAgentSessionKey } from "../routing/session-key.js"; import type { RuntimeEnv } from "../runtime.js"; import { compileSafeRegex, testRegexWithBoundedInput } from "../security/safe-regex.js"; -import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js"; import { buildTelegramExecApprovalButtons } from "./approval-buttons.js"; import { getTelegramExecApprovalApprovers, @@ -248,31 +246,10 @@ export class TelegramExecApprovalHandler { return; } - const { url: gatewayUrl, urlSource } = buildGatewayConnectionDetails({ + this.gatewayClient = await createOperatorApprovalsGatewayClient({ config: this.opts.cfg, - url: this.opts.gatewayUrl, - }); - const gatewayUrlOverrideSource = - urlSource === "cli --url" - ? "cli" - : urlSource === "env OPENCLAW_GATEWAY_URL" - ? "env" - : undefined; - const auth = await resolveGatewayConnectionAuth({ - config: this.opts.cfg, - env: process.env, - urlOverride: gatewayUrlOverrideSource ? gatewayUrl : undefined, - urlOverrideSource: gatewayUrlOverrideSource, - }); - - this.gatewayClient = new GatewayClient({ - url: gatewayUrl, - token: auth.token, - password: auth.password, - clientName: GATEWAY_CLIENT_NAMES.GATEWAY_CLIENT, + gatewayUrl: this.opts.gatewayUrl, clientDisplayName: `Telegram Exec Approvals (${this.opts.accountId})`, - mode: GATEWAY_CLIENT_MODES.BACKEND, - scopes: ["operator.approvals"], onEvent: (evt) => this.handleGatewayEvent(evt), onConnectError: (err) => { log.error(`telegram exec approvals: connect error: ${err.message}`);