import {
createAllowFromSection,
createStandardChannelSetupStatus,
DEFAULT_ACCOUNT_ID,
hasConfiguredSecretInput,
patchChannelConfigForAccount,
setSetupChannelEnabled,
splitSetupEntries,
} from "openclaw/plugin-sdk/setup" ;
import type { ChannelSetupWizard } from "openclaw/plugin-sdk/setup" ;
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime" ;
import { inspectTelegramAccount } from "./account-inspect.js" ;
import { listTelegramAccountIds, resolveTelegramAccount } from "./accounts.js" ;
import {
parseTelegramAllowFromId,
TELEGRAM_TOKEN_HELP_LINES,
TELEGRAM_USER_ID_HELP_LINES,
telegramSetupAdapter,
} from "./setup-core.js" ;
import {
buildTelegramDmAccessWarningLines,
ensureTelegramDefaultGroupMentionGate,
shouldShowTelegramDmAccessWarning,
telegramSetupDmPolicy,
} from "./setup-surface.helpers.js" ;
const channel = "telegram" as const ;
export const telegramSetupWizard: ChannelSetupWizard = {
channel,
status: createStandardChannelSetupStatus({
channelLabel: "Telegram" ,
configuredLabel: "configured" ,
unconfiguredLabel: "needs token" ,
configuredHint: "recommended · configured" ,
unconfiguredHint: "recommended · newcomer-friendly" ,
configuredScore: 1 ,
unconfiguredScore: 10 ,
resolveConfigured: ({ cfg, accountId }) =>
(accountId ? [accountId] : listTelegramAccountIds(cfg)).some((resolvedAccountId) => {
const account = inspectTelegramAccount({ cfg, accountId: resolvedAccountId });
return account.configured;
}),
}),
prepare: async ({ cfg, accountId, credentialValues }) => ({
cfg: ensureTelegramDefaultGroupMentionGate(cfg, accountId),
credentialValues,
}),
credentials: [
{
inputKey: "token" ,
providerHint: channel,
credentialLabel: "Telegram bot token" ,
preferredEnvVar: "TELEGRAM_BOT_TOKEN" ,
helpTitle: "Telegram bot token" ,
helpLines: TELEGRAM_TOKEN_HELP_LINES,
envPrompt: "TELEGRAM_BOT_TOKEN detected. Use env var?" ,
keepPrompt: "Telegram token already configured. Keep it?" ,
inputPrompt: "Enter Telegram bot token" ,
allowEnv: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID,
inspect: ({ cfg, accountId }) => {
const resolved = resolveTelegramAccount({ cfg, accountId });
const hasConfiguredBotToken = hasConfiguredSecretInput(resolved.config.botToken);
const hasConfiguredValue =
hasConfiguredBotToken || Boolean (resolved.config.tokenFile?.trim());
return {
accountConfigured: Boolean (resolved.token) || hasConfiguredValue,
hasConfiguredValue,
resolvedValue: normalizeOptionalString(resolved.token),
envValue:
accountId === DEFAULT_ACCOUNT_ID
? normalizeOptionalString(process.env.TELEGRAM_BOT_TOKEN)
: undefined,
};
},
},
],
allowFrom: createAllowFromSection({
helpTitle: "Telegram user id" ,
helpLines: TELEGRAM_USER_ID_HELP_LINES,
message: "Telegram allowFrom (numeric sender id)" ,
placeholder: "123456789" ,
invalidWithoutCredentialNote:
"Telegram allowFrom requires numeric sender ids. DM your bot first, then copy from.id from logs or getUpdates." ,
parseInputs: splitSetupEntries,
parseId: parseTelegramAllowFromId,
resolveEntries: async ({ entries }) =>
entries.map((entry) => {
const id = parseTelegramAllowFromId(entry);
return { input: entry, resolved: Boolean (id), id };
}),
apply: async ({ cfg, accountId, allowFrom }) =>
patchChannelConfigForAccount({
cfg,
channel,
accountId,
patch: { dmPolicy: "allowlist" , allowFrom },
}),
}),
finalize: async ({ cfg, accountId, prompter }) => {
if (!shouldShowTelegramDmAccessWarning(cfg, accountId)) {
return ;
}
await prompter.note(
buildTelegramDmAccessWarningLines(accountId).join("\n" ),
"Telegram DM access warning" ,
);
},
dmPolicy: telegramSetupDmPolicy,
disable: (cfg) => setSetupChannelEnabled(cfg, channel, false ),
};
export { parseTelegramAllowFromId, telegramSetupAdapter };
Messung V0.5 in Prozent C=97 H=96 G=96
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-13)
¤
*© Formatika GbR, Deutschland