feat: multi-agent routing + multi-account providers
This commit is contained in:
122
src/web/accounts.ts
Normal file
122
src/web/accounts.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import { resolveOAuthDir } from "../config/paths.js";
|
||||
import type { GroupPolicy, WhatsAppAccountConfig } from "../config/types.js";
|
||||
import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
|
||||
export type ResolvedWhatsAppAccount = {
|
||||
accountId: string;
|
||||
enabled: boolean;
|
||||
authDir: string;
|
||||
isLegacyAuthDir: boolean;
|
||||
allowFrom?: string[];
|
||||
groupAllowFrom?: string[];
|
||||
groupPolicy?: GroupPolicy;
|
||||
textChunkLimit?: number;
|
||||
groups?: WhatsAppAccountConfig["groups"];
|
||||
};
|
||||
|
||||
function listConfiguredAccountIds(cfg: ClawdbotConfig): string[] {
|
||||
const accounts = cfg.whatsapp?.accounts;
|
||||
if (!accounts || typeof accounts !== "object") return [];
|
||||
return Object.keys(accounts).filter(Boolean);
|
||||
}
|
||||
|
||||
export function listWhatsAppAccountIds(cfg: ClawdbotConfig): string[] {
|
||||
const ids = listConfiguredAccountIds(cfg);
|
||||
if (ids.length === 0) return [DEFAULT_ACCOUNT_ID];
|
||||
return ids.sort((a, b) => a.localeCompare(b));
|
||||
}
|
||||
|
||||
export function resolveDefaultWhatsAppAccountId(cfg: ClawdbotConfig): string {
|
||||
const ids = listWhatsAppAccountIds(cfg);
|
||||
if (ids.includes(DEFAULT_ACCOUNT_ID)) return DEFAULT_ACCOUNT_ID;
|
||||
return ids[0] ?? DEFAULT_ACCOUNT_ID;
|
||||
}
|
||||
|
||||
function resolveAccountConfig(
|
||||
cfg: ClawdbotConfig,
|
||||
accountId: string,
|
||||
): WhatsAppAccountConfig | undefined {
|
||||
const accounts = cfg.whatsapp?.accounts;
|
||||
if (!accounts || typeof accounts !== "object") return undefined;
|
||||
const entry = accounts[accountId] as WhatsAppAccountConfig | undefined;
|
||||
return entry;
|
||||
}
|
||||
|
||||
function resolveDefaultAuthDir(accountId: string): string {
|
||||
return path.join(resolveOAuthDir(), "whatsapp", accountId);
|
||||
}
|
||||
|
||||
function resolveLegacyAuthDir(): string {
|
||||
// Legacy Baileys creds lived in the same directory as OAuth tokens.
|
||||
return resolveOAuthDir();
|
||||
}
|
||||
|
||||
function legacyAuthExists(authDir: string): boolean {
|
||||
try {
|
||||
return fs.existsSync(path.join(authDir, "creds.json"));
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveWhatsAppAuthDir(params: {
|
||||
cfg: ClawdbotConfig;
|
||||
accountId: string;
|
||||
}): { authDir: string; isLegacy: boolean } {
|
||||
const accountId = params.accountId.trim() || DEFAULT_ACCOUNT_ID;
|
||||
const account = resolveAccountConfig(params.cfg, accountId);
|
||||
const configured = account?.authDir?.trim();
|
||||
if (configured) {
|
||||
return { authDir: resolveUserPath(configured), isLegacy: false };
|
||||
}
|
||||
|
||||
const defaultDir = resolveDefaultAuthDir(accountId);
|
||||
if (accountId === DEFAULT_ACCOUNT_ID) {
|
||||
const legacyDir = resolveLegacyAuthDir();
|
||||
if (legacyAuthExists(legacyDir) && !legacyAuthExists(defaultDir)) {
|
||||
return { authDir: legacyDir, isLegacy: true };
|
||||
}
|
||||
}
|
||||
|
||||
return { authDir: defaultDir, isLegacy: false };
|
||||
}
|
||||
|
||||
export function resolveWhatsAppAccount(params: {
|
||||
cfg: ClawdbotConfig;
|
||||
accountId?: string | null;
|
||||
}): ResolvedWhatsAppAccount {
|
||||
const accountId =
|
||||
params.accountId?.trim() || resolveDefaultWhatsAppAccountId(params.cfg);
|
||||
const accountCfg = resolveAccountConfig(params.cfg, accountId);
|
||||
const enabled = accountCfg?.enabled !== false;
|
||||
const { authDir, isLegacy } = resolveWhatsAppAuthDir({
|
||||
cfg: params.cfg,
|
||||
accountId,
|
||||
});
|
||||
return {
|
||||
accountId,
|
||||
enabled,
|
||||
authDir,
|
||||
isLegacyAuthDir: isLegacy,
|
||||
allowFrom: accountCfg?.allowFrom ?? params.cfg.whatsapp?.allowFrom,
|
||||
groupAllowFrom:
|
||||
accountCfg?.groupAllowFrom ?? params.cfg.whatsapp?.groupAllowFrom,
|
||||
groupPolicy: accountCfg?.groupPolicy ?? params.cfg.whatsapp?.groupPolicy,
|
||||
textChunkLimit:
|
||||
accountCfg?.textChunkLimit ?? params.cfg.whatsapp?.textChunkLimit,
|
||||
groups: accountCfg?.groups ?? params.cfg.whatsapp?.groups,
|
||||
};
|
||||
}
|
||||
|
||||
export function listEnabledWhatsAppAccounts(
|
||||
cfg: ClawdbotConfig,
|
||||
): ResolvedWhatsAppAccount[] {
|
||||
return listWhatsAppAccountIds(cfg)
|
||||
.map((accountId) => resolveWhatsAppAccount({ cfg, accountId }))
|
||||
.filter((account) => account.enabled);
|
||||
}
|
||||
Reference in New Issue
Block a user