diff --git a/extensions/discord/src/accounts.test.ts b/extensions/discord/src/accounts.test.ts index 1f6d70b1ea0..f34cca229ff 100644 --- a/extensions/discord/src/accounts.test.ts +++ b/extensions/discord/src/accounts.test.ts @@ -1,7 +1,30 @@ import { describe, expect, it } from "vitest"; -import { resolveDiscordAccount, resolveDiscordMaxLinesPerMessage } from "./accounts.js"; +import { + createDiscordActionGate, + resolveDiscordAccount, + resolveDiscordMaxLinesPerMessage, +} from "./accounts.js"; describe("resolveDiscordAccount allowFrom precedence", () => { + it("uses configured defaultAccount when accountId is omitted", () => { + const resolved = resolveDiscordAccount({ + cfg: { + channels: { + discord: { + defaultAccount: "work", + accounts: { + work: { token: "token-work", name: "Work" }, + }, + }, + }, + }, + }); + + expect(resolved.accountId).toBe("work"); + expect(resolved.name).toBe("Work"); + expect(resolved.token).toBe("token-work"); + }); + it("prefers accounts.default.allowFrom over top-level for default account", () => { const resolved = resolveDiscordAccount({ cfg: { @@ -57,6 +80,29 @@ describe("resolveDiscordAccount allowFrom precedence", () => { }); }); +describe("createDiscordActionGate", () => { + it("uses configured defaultAccount when accountId is omitted", () => { + const gate = createDiscordActionGate({ + cfg: { + channels: { + discord: { + actions: { reactions: false }, + defaultAccount: "work", + accounts: { + work: { + token: "token-work", + actions: { reactions: true }, + }, + }, + }, + }, + }, + }); + + expect(gate("reactions")).toBe(true); + }); +}); + describe("resolveDiscordMaxLinesPerMessage", () => { it("falls back to merged root discord maxLinesPerMessage when runtime config omits it", () => { const resolved = resolveDiscordMaxLinesPerMessage({ diff --git a/extensions/discord/src/accounts.ts b/extensions/discord/src/accounts.ts index 95aae07310b..85cab84eaf6 100644 --- a/extensions/discord/src/accounts.ts +++ b/extensions/discord/src/accounts.ts @@ -45,7 +45,9 @@ export function createDiscordActionGate(params: { cfg: OpenClawConfig; accountId?: string | null; }): (key: keyof DiscordActionConfig, defaultValue?: boolean) => boolean { - const accountId = normalizeAccountId(params.accountId); + const accountId = normalizeAccountId( + params.accountId ?? resolveDefaultDiscordAccountId(params.cfg), + ); return createAccountActionGate({ baseActions: params.cfg.channels?.discord?.actions, accountActions: resolveDiscordAccountConfig(params.cfg, accountId)?.actions, @@ -56,7 +58,9 @@ export function resolveDiscordAccount(params: { cfg: OpenClawConfig; accountId?: string | null; }): ResolvedDiscordAccount { - const accountId = normalizeAccountId(params.accountId); + const accountId = normalizeAccountId( + params.accountId ?? resolveDefaultDiscordAccountId(params.cfg), + ); const baseEnabled = params.cfg.channels?.discord?.enabled !== false; const merged = mergeDiscordAccountConfig(params.cfg, accountId); const accountEnabled = merged.enabled !== false;