mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-16 12:41:42 +00:00
156 lines
4.9 KiB
TypeScript
156 lines
4.9 KiB
TypeScript
// Telegram plugin module implements account selection behavior.
|
|
import {
|
|
listCombinedAccountIds,
|
|
resolveListedDefaultAccountId,
|
|
} from "openclaw/plugin-sdk/account-core";
|
|
import {
|
|
DEFAULT_ACCOUNT_ID,
|
|
normalizeAccountId,
|
|
normalizeOptionalAccountId,
|
|
} from "openclaw/plugin-sdk/account-id";
|
|
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
|
|
|
const DEFAULT_AGENT_ID = "main";
|
|
|
|
function normalizeAgentId(value: string | undefined | null): string {
|
|
const normalized = (value ?? "")
|
|
.trim()
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9_-]+/g, "-")
|
|
.replace(/^-+/g, "")
|
|
.replace(/-+$/g, "");
|
|
return normalized || DEFAULT_AGENT_ID;
|
|
}
|
|
|
|
function normalizeChannelId(value: unknown): string {
|
|
return typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
}
|
|
|
|
function resolveDefaultAgentId(cfg: OpenClawConfig): string {
|
|
const agents = Array.isArray(cfg.agents?.list) ? cfg.agents.list : [];
|
|
const chosen = (agents.find((agent) => agent?.default) ?? agents[0])?.id;
|
|
return normalizeAgentId(chosen);
|
|
}
|
|
|
|
function listConfiguredAccountIds(cfg: OpenClawConfig): string[] {
|
|
const ids = new Set<string>();
|
|
for (const key of Object.keys(cfg.channels?.telegram?.accounts ?? {})) {
|
|
if (key) {
|
|
ids.add(normalizeAccountId(key));
|
|
}
|
|
}
|
|
return [...ids];
|
|
}
|
|
|
|
function resolveBindingAccount(params: {
|
|
binding: unknown;
|
|
channelId: string;
|
|
}): { agentId: string; accountId: string } | null {
|
|
if (!params.binding || typeof params.binding !== "object") {
|
|
return null;
|
|
}
|
|
const binding = params.binding as {
|
|
agentId?: unknown;
|
|
match?: { channel?: unknown; accountId?: unknown };
|
|
};
|
|
if (normalizeChannelId(binding.match?.channel) !== params.channelId) {
|
|
return null;
|
|
}
|
|
const accountId = typeof binding.match?.accountId === "string" ? binding.match.accountId : "";
|
|
if (!accountId.trim() || accountId.trim() === "*") {
|
|
return null;
|
|
}
|
|
return {
|
|
agentId: normalizeAgentId(typeof binding.agentId === "string" ? binding.agentId : undefined),
|
|
accountId: normalizeAccountId(accountId),
|
|
};
|
|
}
|
|
|
|
function listBoundAccountIds(cfg: OpenClawConfig, channelId: string): string[] {
|
|
const ids = new Set<string>();
|
|
for (const binding of cfg.bindings ?? []) {
|
|
const resolved = resolveBindingAccount({ binding, channelId });
|
|
if (resolved) {
|
|
ids.add(resolved.accountId);
|
|
}
|
|
}
|
|
return [...ids].toSorted((left, right) => left.localeCompare(right));
|
|
}
|
|
|
|
function resolveDefaultAgentBoundAccountId(cfg: OpenClawConfig, channelId: string): string | null {
|
|
const defaultAgentId = resolveDefaultAgentId(cfg);
|
|
for (const binding of cfg.bindings ?? []) {
|
|
const resolved = resolveBindingAccount({ binding, channelId });
|
|
if (resolved?.agentId === defaultAgentId) {
|
|
return resolved.accountId;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function hasConfiguredDefaultAccountValue(value: unknown): boolean {
|
|
if (typeof value === "string") {
|
|
return value.trim().length > 0;
|
|
}
|
|
return value !== undefined && value !== null;
|
|
}
|
|
|
|
function hasImplicitDefaultTelegramAccount(cfg: OpenClawConfig): boolean {
|
|
const telegram = cfg.channels?.telegram;
|
|
if (!telegram) {
|
|
return false;
|
|
}
|
|
return (
|
|
hasConfiguredDefaultAccountValue(telegram.botToken) ||
|
|
hasConfiguredDefaultAccountValue(telegram.tokenFile) ||
|
|
hasConfiguredDefaultAccountValue(process.env.TELEGRAM_BOT_TOKEN)
|
|
);
|
|
}
|
|
|
|
export function listTelegramAccountIds(cfg: OpenClawConfig): string[] {
|
|
return listCombinedAccountIds({
|
|
configuredAccountIds: listConfiguredAccountIds(cfg),
|
|
additionalAccountIds: listBoundAccountIds(cfg, "telegram"),
|
|
implicitAccountId: hasImplicitDefaultTelegramAccount(cfg) ? DEFAULT_ACCOUNT_ID : undefined,
|
|
fallbackAccountIdWhenEmpty: DEFAULT_ACCOUNT_ID,
|
|
});
|
|
}
|
|
|
|
export function resolveDefaultTelegramAccountSelection(cfg: OpenClawConfig): {
|
|
accountId: string;
|
|
accountIds: string[];
|
|
shouldWarnMissingDefault: boolean;
|
|
} {
|
|
const boundDefault = resolveDefaultAgentBoundAccountId(cfg, "telegram");
|
|
if (boundDefault) {
|
|
return {
|
|
accountId: boundDefault,
|
|
accountIds: listTelegramAccountIds(cfg),
|
|
shouldWarnMissingDefault: false,
|
|
};
|
|
}
|
|
const accountIds = listTelegramAccountIds(cfg);
|
|
const configuredDefaultAccountId =
|
|
normalizeOptionalAccountId(cfg.channels?.telegram?.defaultAccount) ?? undefined;
|
|
const hasExplicitDefaultAccount = configuredDefaultAccountId
|
|
? accountIds.includes(configuredDefaultAccountId)
|
|
: false;
|
|
const resolved = resolveListedDefaultAccountId({
|
|
accountIds,
|
|
configuredDefaultAccountId,
|
|
});
|
|
return {
|
|
accountId: resolved,
|
|
accountIds,
|
|
shouldWarnMissingDefault:
|
|
resolved === accountIds[0] &&
|
|
!hasExplicitDefaultAccount &&
|
|
!accountIds.includes(DEFAULT_ACCOUNT_ID) &&
|
|
accountIds.length > 1,
|
|
};
|
|
}
|
|
|
|
export function resolveDefaultTelegramAccountId(cfg: OpenClawConfig): string {
|
|
return resolveDefaultTelegramAccountSelection(cfg).accountId;
|
|
}
|