import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id" ;
import {
hasConfiguredSecretInput,
normalizeSecretInputString,
} from "openclaw/plugin-sdk/secret-input" ;
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime" ;
import {
mergeDiscordAccountConfig,
resolveDefaultDiscordAccountId,
resolveDiscordAccountConfig,
} from "./accounts.js" ;
import type { DiscordAccountConfig, OpenClawConfig } from "./runtime-api.js" ;
export type DiscordCredentialStatus = "available" | "configured_unavailable" | "missing" ;
export type InspectedDiscordAccount = {
accountId: string;
enabled: boolean ;
name?: string;
token: string;
tokenSource: "env" | "config" | "none" ;
tokenStatus: DiscordCredentialStatus;
configured: boolean ;
config: DiscordAccountConfig;
};
function inspectDiscordTokenValue(value: unknown): {
token: string;
tokenSource: "config" ;
tokenStatus: Exclude<DiscordCredentialStatus, "missing" >;
} | null {
const normalized = normalizeSecretInputString(value);
if (normalized) {
return {
token: normalized.replace(/^Bot\s+/i, "" ),
tokenSource: "config" ,
tokenStatus: "available" ,
};
}
if (hasConfiguredSecretInput(value)) {
return {
token: "" ,
tokenSource: "config" ,
tokenStatus: "configured_unavailable" ,
};
}
return null ;
}
export function inspectDiscordAccount(params: {
cfg: OpenClawConfig;
accountId?: string | null ;
envToken?: string | null ;
}): InspectedDiscordAccount {
const accountId = normalizeAccountId(
params.accountId ?? resolveDefaultDiscordAccountId(params.cfg),
);
const merged = mergeDiscordAccountConfig(params.cfg, accountId);
const enabled = params.cfg.channels?.discord?.enabled !== false && merged.enabled !== false ;
const accountConfig = resolveDiscordAccountConfig(params.cfg, accountId);
const hasAccountToken = Boolean (
accountConfig &&
Object.prototype.hasOwnProperty.call(accountConfig as Record<string, unknown>, "token" ),
);
const accountToken = inspectDiscordTokenValue(accountConfig?.token);
if (accountToken) {
return {
accountId,
enabled,
name: normalizeOptionalString(merged.name),
token: accountToken.token,
tokenSource: accountToken.tokenSource,
tokenStatus: accountToken.tokenStatus,
configured: true ,
config: merged,
};
}
if (hasAccountToken) {
return {
accountId,
enabled,
name: normalizeOptionalString(merged.name),
token: "" ,
tokenSource: "none" ,
tokenStatus: "missing" ,
configured: false ,
config: merged,
};
}
const channelToken = inspectDiscordTokenValue(params.cfg.channels?.discord?.token);
if (channelToken) {
return {
accountId,
enabled,
name: normalizeOptionalString(merged.name),
token: channelToken.token,
tokenSource: channelToken.tokenSource,
tokenStatus: channelToken.tokenStatus,
configured: true ,
config: merged,
};
}
const allowEnv = accountId === DEFAULT_ACCOUNT_ID;
const envToken = allowEnv
? normalizeSecretInputString(params.envToken ?? process.env.DISCORD_BOT_TOKEN)
: undefined;
if (envToken) {
return {
accountId,
enabled,
name: normalizeOptionalString(merged.name),
token: envToken.replace(/^Bot\s+/i, "" ),
tokenSource: "env" ,
tokenStatus: "available" ,
configured: true ,
config: merged,
};
}
return {
accountId,
enabled,
name: normalizeOptionalString(merged.name),
token: "" ,
tokenSource: "none" ,
tokenStatus: "missing" ,
configured: false ,
config: merged,
};
}
Messung V0.5 in Prozent C=100 H=100 G=100
¤ Dauer der Verarbeitung: 0.8 Sekunden
(vorverarbeitet am 2026-06-09)
¤
*© Formatika GbR, Deutschland