Files
qqbot/src/config.ts
2026-01-30 15:12:28 +08:00

159 lines
4.4 KiB
TypeScript

import type { ResolvedQQBotAccount, QQBotAccountConfig } from "./types.js";
const DEFAULT_ACCOUNT_ID = "default";
interface MoltbotConfig {
channels?: {
qqbot?: QQBotChannelConfig;
[key: string]: unknown;
};
[key: string]: unknown;
}
interface QQBotChannelConfig extends QQBotAccountConfig {
accounts?: Record<string, QQBotAccountConfig>;
}
/**
* 列出所有 QQBot 账户 ID
*/
export function listQQBotAccountIds(cfg: MoltbotConfig): string[] {
const ids = new Set<string>();
const qqbot = cfg.channels?.qqbot;
if (qqbot?.appId) {
ids.add(DEFAULT_ACCOUNT_ID);
}
if (qqbot?.accounts) {
for (const accountId of Object.keys(qqbot.accounts)) {
if (qqbot.accounts[accountId]?.appId) {
ids.add(accountId);
}
}
}
return Array.from(ids);
}
/**
* 解析 QQBot 账户配置
*/
export function resolveQQBotAccount(
cfg: MoltbotConfig,
accountId?: string | null
): ResolvedQQBotAccount {
const resolvedAccountId = accountId ?? DEFAULT_ACCOUNT_ID;
const qqbot = cfg.channels?.qqbot;
// 基础配置
let accountConfig: QQBotAccountConfig = {};
let appId = "";
let clientSecret = "";
let secretSource: "config" | "file" | "env" | "none" = "none";
if (resolvedAccountId === DEFAULT_ACCOUNT_ID) {
// 默认账户从顶层读取
accountConfig = {
enabled: qqbot?.enabled,
name: qqbot?.name,
appId: qqbot?.appId,
clientSecret: qqbot?.clientSecret,
clientSecretFile: qqbot?.clientSecretFile,
dmPolicy: qqbot?.dmPolicy,
allowFrom: qqbot?.allowFrom,
systemPrompt: qqbot?.systemPrompt,
imageServerBaseUrl: qqbot?.imageServerBaseUrl,
};
appId = qqbot?.appId ?? "";
} else {
// 命名账户从 accounts 读取
const account = qqbot?.accounts?.[resolvedAccountId];
accountConfig = account ?? {};
appId = account?.appId ?? "";
}
// 解析 clientSecret
if (accountConfig.clientSecret) {
clientSecret = accountConfig.clientSecret;
secretSource = "config";
} else if (accountConfig.clientSecretFile) {
// 从文件读取(运行时处理)
secretSource = "file";
} else if (process.env.QQBOT_CLIENT_SECRET && resolvedAccountId === DEFAULT_ACCOUNT_ID) {
clientSecret = process.env.QQBOT_CLIENT_SECRET;
secretSource = "env";
}
// AppId 也可以从环境变量读取
if (!appId && process.env.QQBOT_APP_ID && resolvedAccountId === DEFAULT_ACCOUNT_ID) {
appId = process.env.QQBOT_APP_ID;
}
return {
accountId: resolvedAccountId,
name: accountConfig.name,
enabled: accountConfig.enabled !== false,
appId,
clientSecret,
secretSource,
systemPrompt: accountConfig.systemPrompt,
imageServerBaseUrl: accountConfig.imageServerBaseUrl || process.env.QQBOT_IMAGE_SERVER_BASE_URL,
config: accountConfig,
};
}
/**
* 应用账户配置
*/
export function applyQQBotAccountConfig(
cfg: MoltbotConfig,
accountId: string,
input: { appId?: string; clientSecret?: string; clientSecretFile?: string; name?: string; imageServerBaseUrl?: string }
): MoltbotConfig {
const next = { ...cfg };
if (accountId === DEFAULT_ACCOUNT_ID) {
next.channels = {
...next.channels,
qqbot: {
...next.channels?.qqbot,
enabled: true,
...(input.appId ? { appId: input.appId } : {}),
...(input.clientSecret
? { clientSecret: input.clientSecret }
: input.clientSecretFile
? { clientSecretFile: input.clientSecretFile }
: {}),
...(input.name ? { name: input.name } : {}),
...(input.imageServerBaseUrl ? { imageServerBaseUrl: input.imageServerBaseUrl } : {}),
},
};
} else {
next.channels = {
...next.channels,
qqbot: {
...next.channels?.qqbot,
enabled: true,
accounts: {
...(next.channels?.qqbot as QQBotChannelConfig)?.accounts,
[accountId]: {
...(next.channels?.qqbot as QQBotChannelConfig)?.accounts?.[accountId],
enabled: true,
...(input.appId ? { appId: input.appId } : {}),
...(input.clientSecret
? { clientSecret: input.clientSecret }
: input.clientSecretFile
? { clientSecretFile: input.clientSecretFile }
: {}),
...(input.name ? { name: input.name } : {}),
...(input.imageServerBaseUrl ? { imageServerBaseUrl: input.imageServerBaseUrl } : {}),
},
},
},
};
}
return next;
}