mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 11:28:38 +00:00
refactor: share setup account config patch helper
This commit is contained in:
@@ -256,18 +256,6 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
|
|||||||
channelKey: "bluebubbles",
|
channelKey: "bluebubbles",
|
||||||
})
|
})
|
||||||
: namedConfig;
|
: namedConfig;
|
||||||
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
||||||
return applyBlueBubblesConnectionConfig({
|
|
||||||
cfg: next,
|
|
||||||
accountId,
|
|
||||||
patch: {
|
|
||||||
serverUrl: input.httpUrl,
|
|
||||||
password: input.password,
|
|
||||||
webhookPath: input.webhookPath,
|
|
||||||
},
|
|
||||||
onlyDefinedFields: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return applyBlueBubblesConnectionConfig({
|
return applyBlueBubblesConnectionConfig({
|
||||||
cfg: next,
|
cfg: next,
|
||||||
accountId,
|
accountId,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
applyAccountNameToChannelSection,
|
applyAccountNameToChannelSection,
|
||||||
|
applySetupAccountConfigPatch,
|
||||||
buildChannelConfigSchema,
|
buildChannelConfigSchema,
|
||||||
DEFAULT_ACCOUNT_ID,
|
DEFAULT_ACCOUNT_ID,
|
||||||
deleteAccountFromConfigSection,
|
deleteAccountFromConfigSection,
|
||||||
@@ -345,37 +346,12 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
|
|||||||
...(webhookPath ? { webhookPath } : {}),
|
...(webhookPath ? { webhookPath } : {}),
|
||||||
...(webhookUrl ? { webhookUrl } : {}),
|
...(webhookUrl ? { webhookUrl } : {}),
|
||||||
};
|
};
|
||||||
if (accountId === DEFAULT_ACCOUNT_ID) {
|
return applySetupAccountConfigPatch({
|
||||||
return {
|
cfg: next,
|
||||||
...next,
|
channelKey: "googlechat",
|
||||||
channels: {
|
accountId,
|
||||||
...next.channels,
|
patch: configPatch,
|
||||||
googlechat: {
|
});
|
||||||
...next.channels?.["googlechat"],
|
|
||||||
enabled: true,
|
|
||||||
...configPatch,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as OpenClawConfig;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...next,
|
|
||||||
channels: {
|
|
||||||
...next.channels,
|
|
||||||
googlechat: {
|
|
||||||
...next.channels?.["googlechat"],
|
|
||||||
enabled: true,
|
|
||||||
accounts: {
|
|
||||||
...next.channels?.["googlechat"]?.accounts,
|
|
||||||
[accountId]: {
|
|
||||||
...next.channels?.["googlechat"]?.accounts?.[accountId],
|
|
||||||
enabled: true,
|
|
||||||
...configPatch,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as OpenClawConfig;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
outbound: {
|
outbound: {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
applyAccountNameToChannelSection,
|
applyAccountNameToChannelSection,
|
||||||
|
applySetupAccountConfigPatch,
|
||||||
buildChannelConfigSchema,
|
buildChannelConfigSchema,
|
||||||
DEFAULT_ACCOUNT_ID,
|
DEFAULT_ACCOUNT_ID,
|
||||||
deleteAccountFromConfigSection,
|
deleteAccountFromConfigSection,
|
||||||
@@ -449,43 +450,18 @@ export const mattermostPlugin: ChannelPlugin<ResolvedMattermostAccount> = {
|
|||||||
channelKey: "mattermost",
|
channelKey: "mattermost",
|
||||||
})
|
})
|
||||||
: namedConfig;
|
: namedConfig;
|
||||||
if (accountId === DEFAULT_ACCOUNT_ID) {
|
const patch = input.useEnv
|
||||||
return {
|
? {}
|
||||||
...next,
|
: {
|
||||||
channels: {
|
...(token ? { botToken: token } : {}),
|
||||||
...next.channels,
|
...(baseUrl ? { baseUrl } : {}),
|
||||||
mattermost: {
|
};
|
||||||
...next.channels?.mattermost,
|
return applySetupAccountConfigPatch({
|
||||||
enabled: true,
|
cfg: next,
|
||||||
...(input.useEnv
|
channelKey: "mattermost",
|
||||||
? {}
|
accountId,
|
||||||
: {
|
patch,
|
||||||
...(token ? { botToken: token } : {}),
|
});
|
||||||
...(baseUrl ? { baseUrl } : {}),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...next,
|
|
||||||
channels: {
|
|
||||||
...next.channels,
|
|
||||||
mattermost: {
|
|
||||||
...next.channels?.mattermost,
|
|
||||||
enabled: true,
|
|
||||||
accounts: {
|
|
||||||
...next.channels?.mattermost?.accounts,
|
|
||||||
[accountId]: {
|
|
||||||
...next.channels?.mattermost?.accounts?.[accountId],
|
|
||||||
enabled: true,
|
|
||||||
...(token ? { botToken: token } : {}),
|
|
||||||
...(baseUrl ? { baseUrl } : {}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
gateway: {
|
gateway: {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import type {
|
|||||||
} from "openclaw/plugin-sdk/zalo";
|
} from "openclaw/plugin-sdk/zalo";
|
||||||
import {
|
import {
|
||||||
applyAccountNameToChannelSection,
|
applyAccountNameToChannelSection,
|
||||||
|
applySetupAccountConfigPatch,
|
||||||
buildBaseAccountStatusSnapshot,
|
buildBaseAccountStatusSnapshot,
|
||||||
buildChannelConfigSchema,
|
buildChannelConfigSchema,
|
||||||
buildTokenChannelStatusSummary,
|
buildTokenChannelStatusSummary,
|
||||||
@@ -243,47 +244,19 @@ export const zaloPlugin: ChannelPlugin<ResolvedZaloAccount> = {
|
|||||||
channelKey: "zalo",
|
channelKey: "zalo",
|
||||||
})
|
})
|
||||||
: namedConfig;
|
: namedConfig;
|
||||||
if (accountId === DEFAULT_ACCOUNT_ID) {
|
const patch = input.useEnv
|
||||||
return {
|
? {}
|
||||||
...next,
|
: input.tokenFile
|
||||||
channels: {
|
? { tokenFile: input.tokenFile }
|
||||||
...next.channels,
|
: input.token
|
||||||
zalo: {
|
? { botToken: input.token }
|
||||||
...next.channels?.zalo,
|
: {};
|
||||||
enabled: true,
|
return applySetupAccountConfigPatch({
|
||||||
...(input.useEnv
|
cfg: next,
|
||||||
? {}
|
channelKey: "zalo",
|
||||||
: input.tokenFile
|
accountId,
|
||||||
? { tokenFile: input.tokenFile }
|
patch,
|
||||||
: input.token
|
});
|
||||||
? { botToken: input.token }
|
|
||||||
: {}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as OpenClawConfig;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...next,
|
|
||||||
channels: {
|
|
||||||
...next.channels,
|
|
||||||
zalo: {
|
|
||||||
...next.channels?.zalo,
|
|
||||||
enabled: true,
|
|
||||||
accounts: {
|
|
||||||
...next.channels?.zalo?.accounts,
|
|
||||||
[accountId]: {
|
|
||||||
...next.channels?.zalo?.accounts?.[accountId],
|
|
||||||
enabled: true,
|
|
||||||
...(input.tokenFile
|
|
||||||
? { tokenFile: input.tokenFile }
|
|
||||||
: input.token
|
|
||||||
? { botToken: input.token }
|
|
||||||
: {}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as OpenClawConfig;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pairing: {
|
pairing: {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import type {
|
|||||||
} from "openclaw/plugin-sdk/zalouser";
|
} from "openclaw/plugin-sdk/zalouser";
|
||||||
import {
|
import {
|
||||||
applyAccountNameToChannelSection,
|
applyAccountNameToChannelSection,
|
||||||
|
applySetupAccountConfigPatch,
|
||||||
buildChannelSendResult,
|
buildChannelSendResult,
|
||||||
buildBaseAccountStatusSnapshot,
|
buildBaseAccountStatusSnapshot,
|
||||||
buildChannelConfigSchema,
|
buildChannelConfigSchema,
|
||||||
@@ -329,35 +330,12 @@ export const zalouserPlugin: ChannelPlugin<ResolvedZalouserAccount> = {
|
|||||||
channelKey: "zalouser",
|
channelKey: "zalouser",
|
||||||
})
|
})
|
||||||
: namedConfig;
|
: namedConfig;
|
||||||
if (accountId === DEFAULT_ACCOUNT_ID) {
|
return applySetupAccountConfigPatch({
|
||||||
return {
|
cfg: next,
|
||||||
...next,
|
channelKey: "zalouser",
|
||||||
channels: {
|
accountId,
|
||||||
...next.channels,
|
patch: {},
|
||||||
zalouser: {
|
});
|
||||||
...next.channels?.zalouser,
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as OpenClawConfig;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...next,
|
|
||||||
channels: {
|
|
||||||
...next.channels,
|
|
||||||
zalouser: {
|
|
||||||
...next.channels?.zalouser,
|
|
||||||
enabled: true,
|
|
||||||
accounts: {
|
|
||||||
...next.channels?.zalouser?.accounts,
|
|
||||||
[accountId]: {
|
|
||||||
...next.channels?.zalouser?.accounts?.[accountId],
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as OpenClawConfig;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
messaging: {
|
messaging: {
|
||||||
|
|||||||
81
src/channels/plugins/setup-helpers.test.ts
Normal file
81
src/channels/plugins/setup-helpers.test.ts
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import type { OpenClawConfig } from "../../config/config.js";
|
||||||
|
import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js";
|
||||||
|
import { applySetupAccountConfigPatch } from "./setup-helpers.js";
|
||||||
|
|
||||||
|
function asConfig(value: unknown): OpenClawConfig {
|
||||||
|
return value as OpenClawConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("applySetupAccountConfigPatch", () => {
|
||||||
|
it("patches top-level config for default account and enables channel", () => {
|
||||||
|
const next = applySetupAccountConfigPatch({
|
||||||
|
cfg: asConfig({
|
||||||
|
channels: {
|
||||||
|
zalo: {
|
||||||
|
webhookPath: "/old",
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
channelKey: "zalo",
|
||||||
|
accountId: DEFAULT_ACCOUNT_ID,
|
||||||
|
patch: { webhookPath: "/new", botToken: "tok" },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(next.channels?.zalo).toMatchObject({
|
||||||
|
enabled: true,
|
||||||
|
webhookPath: "/new",
|
||||||
|
botToken: "tok",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("patches named account config and enables both channel and account", () => {
|
||||||
|
const next = applySetupAccountConfigPatch({
|
||||||
|
cfg: asConfig({
|
||||||
|
channels: {
|
||||||
|
zalo: {
|
||||||
|
enabled: false,
|
||||||
|
accounts: {
|
||||||
|
work: { botToken: "old", enabled: false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
channelKey: "zalo",
|
||||||
|
accountId: "work",
|
||||||
|
patch: { botToken: "new" },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(next.channels?.zalo).toMatchObject({
|
||||||
|
enabled: true,
|
||||||
|
accounts: {
|
||||||
|
work: { enabled: true, botToken: "new" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("normalizes account id and preserves other accounts", () => {
|
||||||
|
const next = applySetupAccountConfigPatch({
|
||||||
|
cfg: asConfig({
|
||||||
|
channels: {
|
||||||
|
zalo: {
|
||||||
|
accounts: {
|
||||||
|
personal: { botToken: "personal-token" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
channelKey: "zalo",
|
||||||
|
accountId: "Work Team",
|
||||||
|
patch: { botToken: "work-token" },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(next.channels?.zalo).toMatchObject({
|
||||||
|
accounts: {
|
||||||
|
personal: { botToken: "personal-token" },
|
||||||
|
"work-team": { enabled: true, botToken: "work-token" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -120,6 +120,56 @@ export function migrateBaseNameToDefaultAccount(params: {
|
|||||||
} as OpenClawConfig;
|
} as OpenClawConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function applySetupAccountConfigPatch(params: {
|
||||||
|
cfg: OpenClawConfig;
|
||||||
|
channelKey: string;
|
||||||
|
accountId: string;
|
||||||
|
patch: Record<string, unknown>;
|
||||||
|
}): OpenClawConfig {
|
||||||
|
const accountId = normalizeAccountId(params.accountId);
|
||||||
|
const channels = params.cfg.channels as Record<string, unknown> | undefined;
|
||||||
|
const channelConfig = channels?.[params.channelKey];
|
||||||
|
const base =
|
||||||
|
typeof channelConfig === "object" && channelConfig
|
||||||
|
? (channelConfig as Record<string, unknown> & {
|
||||||
|
accounts?: Record<string, Record<string, unknown>>;
|
||||||
|
})
|
||||||
|
: undefined;
|
||||||
|
if (accountId === DEFAULT_ACCOUNT_ID) {
|
||||||
|
return {
|
||||||
|
...params.cfg,
|
||||||
|
channels: {
|
||||||
|
...params.cfg.channels,
|
||||||
|
[params.channelKey]: {
|
||||||
|
...base,
|
||||||
|
enabled: true,
|
||||||
|
...params.patch,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as OpenClawConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const accounts = base?.accounts ?? {};
|
||||||
|
return {
|
||||||
|
...params.cfg,
|
||||||
|
channels: {
|
||||||
|
...params.cfg.channels,
|
||||||
|
[params.channelKey]: {
|
||||||
|
...base,
|
||||||
|
enabled: true,
|
||||||
|
accounts: {
|
||||||
|
...accounts,
|
||||||
|
[accountId]: {
|
||||||
|
...accounts[accountId],
|
||||||
|
enabled: true,
|
||||||
|
...params.patch,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as OpenClawConfig;
|
||||||
|
}
|
||||||
|
|
||||||
type ChannelSectionRecord = Record<string, unknown> & {
|
type ChannelSectionRecord = Record<string, unknown> & {
|
||||||
accounts?: Record<string, Record<string, unknown>>;
|
accounts?: Record<string, Record<string, unknown>>;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export {
|
|||||||
export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js";
|
export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js";
|
||||||
export {
|
export {
|
||||||
applyAccountNameToChannelSection,
|
applyAccountNameToChannelSection,
|
||||||
|
applySetupAccountConfigPatch,
|
||||||
migrateBaseNameToDefaultAccount,
|
migrateBaseNameToDefaultAccount,
|
||||||
} from "../channels/plugins/setup-helpers.js";
|
} from "../channels/plugins/setup-helpers.js";
|
||||||
export { createAccountListHelpers } from "../channels/plugins/account-helpers.js";
|
export { createAccountListHelpers } from "../channels/plugins/account-helpers.js";
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export {
|
|||||||
} from "../channels/plugins/onboarding/helpers.js";
|
} from "../channels/plugins/onboarding/helpers.js";
|
||||||
export {
|
export {
|
||||||
applyAccountNameToChannelSection,
|
applyAccountNameToChannelSection,
|
||||||
|
applySetupAccountConfigPatch,
|
||||||
migrateBaseNameToDefaultAccount,
|
migrateBaseNameToDefaultAccount,
|
||||||
} from "../channels/plugins/setup-helpers.js";
|
} from "../channels/plugins/setup-helpers.js";
|
||||||
export { createAccountListHelpers } from "../channels/plugins/account-helpers.js";
|
export { createAccountListHelpers } from "../channels/plugins/account-helpers.js";
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export {
|
|||||||
export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js";
|
export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js";
|
||||||
export {
|
export {
|
||||||
applyAccountNameToChannelSection,
|
applyAccountNameToChannelSection,
|
||||||
|
applySetupAccountConfigPatch,
|
||||||
migrateBaseNameToDefaultAccount,
|
migrateBaseNameToDefaultAccount,
|
||||||
} from "../channels/plugins/setup-helpers.js";
|
} from "../channels/plugins/setup-helpers.js";
|
||||||
export { createAccountListHelpers } from "../channels/plugins/account-helpers.js";
|
export { createAccountListHelpers } from "../channels/plugins/account-helpers.js";
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export {
|
|||||||
} from "../channels/plugins/onboarding/helpers.js";
|
} from "../channels/plugins/onboarding/helpers.js";
|
||||||
export {
|
export {
|
||||||
applyAccountNameToChannelSection,
|
applyAccountNameToChannelSection,
|
||||||
|
applySetupAccountConfigPatch,
|
||||||
migrateBaseNameToDefaultAccount,
|
migrateBaseNameToDefaultAccount,
|
||||||
} from "../channels/plugins/setup-helpers.js";
|
} from "../channels/plugins/setup-helpers.js";
|
||||||
export { createAccountListHelpers } from "../channels/plugins/account-helpers.js";
|
export { createAccountListHelpers } from "../channels/plugins/account-helpers.js";
|
||||||
|
|||||||
Reference in New Issue
Block a user