From 725958c66f2fb0e558813b09b0162080b17032d6 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 10 Mar 2026 20:28:25 +0000 Subject: [PATCH] refactor: share onboarding secret prompt flows --- extensions/nextcloud-talk/src/onboarding.ts | 65 ++++++----- extensions/zalo/src/onboarding.ts | 113 +++++++++----------- src/channels/plugins/onboarding/discord.ts | 64 +++++------ src/channels/plugins/onboarding/helpers.ts | 76 +++++++++++++ src/channels/plugins/onboarding/slack.ts | 69 +++++------- src/channels/plugins/onboarding/telegram.ts | 64 +++++------ src/plugin-sdk/mattermost.ts | 1 + src/plugin-sdk/nextcloud-talk.ts | 1 + src/plugin-sdk/zalo.ts | 1 + 9 files changed, 239 insertions(+), 215 deletions(-) diff --git a/extensions/nextcloud-talk/src/onboarding.ts b/extensions/nextcloud-talk/src/onboarding.ts index b9772fb47e5..b3967057fe1 100644 --- a/extensions/nextcloud-talk/src/onboarding.ts +++ b/extensions/nextcloud-talk/src/onboarding.ts @@ -1,16 +1,14 @@ import { - buildSingleChannelSecretPromptState, formatDocsLink, hasConfiguredSecretInput, mapAllowFromEntries, mergeAllowFromEntries, patchScopedAccountConfig, - promptSingleChannelSecretInput, + runSingleChannelSecretStep, resolveAccountIdForConfigure, DEFAULT_ACCOUNT_ID, normalizeAccountId, setTopLevelChannelDmPolicyWithAllowFrom, - type SecretInput, type ChannelOnboardingAdapter, type ChannelOnboardingDmPolicy, type OpenClawConfig, @@ -190,12 +188,6 @@ export const nextcloudTalkOnboardingAdapter: ChannelOnboardingAdapter = { hasConfiguredSecretInput(resolvedAccount.config.botSecret) || resolvedAccount.config.botSecretFile, ); - const secretPromptState = buildSingleChannelSecretPromptState({ - accountConfigured, - hasConfigToken: hasConfigSecret, - allowEnv, - envValue: process.env.NEXTCLOUD_TALK_BOT_SECRET, - }); let baseUrl = resolvedAccount.baseUrl; if (!baseUrl) { @@ -216,32 +208,35 @@ export const nextcloudTalkOnboardingAdapter: ChannelOnboardingAdapter = { ).trim(); } - let secret: SecretInput | null = null; - if (!accountConfigured) { - await noteNextcloudTalkSecretHelp(prompter); - } - - const secretResult = await promptSingleChannelSecretInput({ + const secretStep = await runSingleChannelSecretStep({ cfg: next, prompter, providerHint: "nextcloud-talk", credentialLabel: "bot secret", - accountConfigured: secretPromptState.accountConfigured, - canUseEnv: secretPromptState.canUseEnv, - hasConfigToken: secretPromptState.hasConfigToken, + accountConfigured, + hasConfigToken: hasConfigSecret, + allowEnv, + envValue: process.env.NEXTCLOUD_TALK_BOT_SECRET, envPrompt: "NEXTCLOUD_TALK_BOT_SECRET detected. Use env var?", keepPrompt: "Nextcloud Talk bot secret already configured. Keep it?", inputPrompt: "Enter Nextcloud Talk bot secret", preferredEnvVar: "NEXTCLOUD_TALK_BOT_SECRET", + onMissingConfigured: async () => await noteNextcloudTalkSecretHelp(prompter), + applyUseEnv: async (cfg) => + setNextcloudTalkAccountConfig(cfg as CoreConfig, accountId, { + baseUrl, + }), + applySet: async (cfg, value) => + setNextcloudTalkAccountConfig(cfg as CoreConfig, accountId, { + baseUrl, + botSecret: value, + }), }); - if (secretResult.action === "set") { - secret = secretResult.value; - } + next = secretStep.cfg; - if (secretResult.action === "use-env" || secret || baseUrl !== resolvedAccount.baseUrl) { + if (secretStep.action === "keep" && baseUrl !== resolvedAccount.baseUrl) { next = setNextcloudTalkAccountConfig(next, accountId, { baseUrl, - ...(secret ? { botSecret: secret } : {}), }); } @@ -262,26 +257,28 @@ export const nextcloudTalkOnboardingAdapter: ChannelOnboardingAdapter = { validate: (value) => (String(value ?? "").trim() ? undefined : "Required"), }), ).trim(); - const apiPasswordResult = await promptSingleChannelSecretInput({ + const apiPasswordStep = await runSingleChannelSecretStep({ cfg: next, prompter, providerHint: "nextcloud-talk-api", credentialLabel: "API password", - ...buildSingleChannelSecretPromptState({ - accountConfigured: Boolean(existingApiUser && existingApiPasswordConfigured), - hasConfigToken: existingApiPasswordConfigured, - allowEnv: false, - }), + accountConfigured: Boolean(existingApiUser && existingApiPasswordConfigured), + hasConfigToken: existingApiPasswordConfigured, + allowEnv: false, envPrompt: "", keepPrompt: "Nextcloud Talk API password already configured. Keep it?", inputPrompt: "Enter Nextcloud Talk API password", preferredEnvVar: "NEXTCLOUD_TALK_API_PASSWORD", + applySet: async (cfg, value) => + setNextcloudTalkAccountConfig(cfg as CoreConfig, accountId, { + apiUser, + apiPassword: value, + }), }); - const apiPassword = apiPasswordResult.action === "set" ? apiPasswordResult.value : undefined; - next = setNextcloudTalkAccountConfig(next, accountId, { - apiUser, - ...(apiPassword ? { apiPassword } : {}), - }); + next = + apiPasswordStep.action === "keep" + ? setNextcloudTalkAccountConfig(next, accountId, { apiUser }) + : apiPasswordStep.cfg; } if (forceAllowFrom) { diff --git a/extensions/zalo/src/onboarding.ts b/extensions/zalo/src/onboarding.ts index e23765f4f7d..4c6f7cbe4de 100644 --- a/extensions/zalo/src/onboarding.ts +++ b/extensions/zalo/src/onboarding.ts @@ -12,6 +12,7 @@ import { mergeAllowFromEntries, normalizeAccountId, promptSingleChannelSecretInput, + runSingleChannelSecretStep, resolveAccountIdForConfigure, setTopLevelChannelDmPolicyWithAllowFrom, } from "openclaw/plugin-sdk/zalo"; @@ -255,80 +256,66 @@ export const zaloOnboardingAdapter: ChannelOnboardingAdapter = { const hasConfigToken = Boolean( hasConfiguredSecretInput(resolvedAccount.config.botToken) || resolvedAccount.config.tokenFile, ); - const tokenPromptState = buildSingleChannelSecretPromptState({ - accountConfigured, - hasConfigToken, - allowEnv, - envValue: process.env.ZALO_BOT_TOKEN, - }); - - let token: SecretInput | null = null; - if (!accountConfigured) { - await noteZaloTokenHelp(prompter); - } - const tokenResult = await promptSingleChannelSecretInput({ + const tokenStep = await runSingleChannelSecretStep({ cfg: next, prompter, providerHint: "zalo", credentialLabel: "bot token", - accountConfigured: tokenPromptState.accountConfigured, - canUseEnv: tokenPromptState.canUseEnv, - hasConfigToken: tokenPromptState.hasConfigToken, + accountConfigured, + hasConfigToken, + allowEnv, + envValue: process.env.ZALO_BOT_TOKEN, envPrompt: "ZALO_BOT_TOKEN detected. Use env var?", keepPrompt: "Zalo token already configured. Keep it?", inputPrompt: "Enter Zalo bot token", preferredEnvVar: "ZALO_BOT_TOKEN", - }); - if (tokenResult.action === "set") { - token = tokenResult.value; - } - if (tokenResult.action === "use-env" && zaloAccountId === DEFAULT_ACCOUNT_ID) { - next = { - ...next, - channels: { - ...next.channels, - zalo: { - ...next.channels?.zalo, - enabled: true, - }, - }, - } as OpenClawConfig; - } - - if (token) { - if (zaloAccountId === DEFAULT_ACCOUNT_ID) { - next = { - ...next, - channels: { - ...next.channels, - zalo: { - ...next.channels?.zalo, - enabled: true, - botToken: token, - }, - }, - } as OpenClawConfig; - } else { - next = { - ...next, - channels: { - ...next.channels, - zalo: { - ...next.channels?.zalo, - enabled: true, - accounts: { - ...next.channels?.zalo?.accounts, - [zaloAccountId]: { - ...next.channels?.zalo?.accounts?.[zaloAccountId], + onMissingConfigured: async () => await noteZaloTokenHelp(prompter), + applyUseEnv: async (cfg) => + zaloAccountId === DEFAULT_ACCOUNT_ID + ? ({ + ...cfg, + channels: { + ...cfg.channels, + zalo: { + ...cfg.channels?.zalo, enabled: true, - botToken: token, }, }, - }, - }, - } as OpenClawConfig; - } - } + } as OpenClawConfig) + : cfg, + applySet: async (cfg, value) => + zaloAccountId === DEFAULT_ACCOUNT_ID + ? ({ + ...cfg, + channels: { + ...cfg.channels, + zalo: { + ...cfg.channels?.zalo, + enabled: true, + botToken: value, + }, + }, + } as OpenClawConfig) + : ({ + ...cfg, + channels: { + ...cfg.channels, + zalo: { + ...cfg.channels?.zalo, + enabled: true, + accounts: { + ...cfg.channels?.zalo?.accounts, + [zaloAccountId]: { + ...cfg.channels?.zalo?.accounts?.[zaloAccountId], + enabled: true, + botToken: value, + }, + }, + }, + }, + } as OpenClawConfig), + }); + next = tokenStep.cfg; const wantsWebhook = await prompter.confirm({ message: "Use webhook mode for Zalo?", diff --git a/src/channels/plugins/onboarding/discord.ts b/src/channels/plugins/onboarding/discord.ts index 52f0d2b1373..d6a8c8df370 100644 --- a/src/channels/plugins/onboarding/discord.ts +++ b/src/channels/plugins/onboarding/discord.ts @@ -20,15 +20,14 @@ import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onb import { configureChannelAccessWithAllowlist } from "./channel-access-configure.js"; import { applySingleTokenPromptResult, - buildSingleChannelSecretPromptState, parseMentionOrPrefixedId, noteChannelLookupFailure, noteChannelLookupSummary, patchChannelConfigForAccount, promptLegacyChannelAllowFrom, - promptSingleChannelSecretInput, resolveAccountIdForConfigure, resolveOnboardingAccountId, + runSingleChannelSecretStep, setAccountGroupPolicyForChannel, setLegacyChannelDmPolicyWithAllowFrom, setOnboardingChannelEnabled, @@ -179,52 +178,39 @@ export const discordOnboardingAdapter: ChannelOnboardingAdapter = { accountId: discordAccountId, }); const allowEnv = discordAccountId === DEFAULT_ACCOUNT_ID; - const tokenPromptState = buildSingleChannelSecretPromptState({ - accountConfigured: Boolean(resolvedAccount.token), - hasConfigToken: hasConfiguredSecretInput(resolvedAccount.config.token), - allowEnv, - envValue: process.env.DISCORD_BOT_TOKEN, - }); - - if (!tokenPromptState.accountConfigured) { - await noteDiscordTokenHelp(prompter); - } - - const tokenResult = await promptSingleChannelSecretInput({ + const tokenStep = await runSingleChannelSecretStep({ cfg: next, prompter, providerHint: "discord", credentialLabel: "Discord bot token", secretInputMode: options?.secretInputMode, - accountConfigured: tokenPromptState.accountConfigured, - canUseEnv: tokenPromptState.canUseEnv, - hasConfigToken: tokenPromptState.hasConfigToken, + accountConfigured: Boolean(resolvedAccount.token), + hasConfigToken: hasConfiguredSecretInput(resolvedAccount.config.token), + allowEnv, + envValue: process.env.DISCORD_BOT_TOKEN, envPrompt: "DISCORD_BOT_TOKEN detected. Use env var?", keepPrompt: "Discord token already configured. Keep it?", inputPrompt: "Enter Discord bot token", preferredEnvVar: allowEnv ? "DISCORD_BOT_TOKEN" : undefined, + onMissingConfigured: async () => await noteDiscordTokenHelp(prompter), + applyUseEnv: async (cfg) => + applySingleTokenPromptResult({ + cfg, + channel: "discord", + accountId: discordAccountId, + tokenPatchKey: "token", + tokenResult: { useEnv: true, token: null }, + }), + applySet: async (cfg, value) => + applySingleTokenPromptResult({ + cfg, + channel: "discord", + accountId: discordAccountId, + tokenPatchKey: "token", + tokenResult: { useEnv: false, token: value }, + }), }); - - let resolvedTokenForAllowlist: string | undefined; - if (tokenResult.action === "use-env") { - next = applySingleTokenPromptResult({ - cfg: next, - channel: "discord", - accountId: discordAccountId, - tokenPatchKey: "token", - tokenResult: { useEnv: true, token: null }, - }); - resolvedTokenForAllowlist = process.env.DISCORD_BOT_TOKEN?.trim() || undefined; - } else if (tokenResult.action === "set") { - next = applySingleTokenPromptResult({ - cfg: next, - channel: "discord", - accountId: discordAccountId, - tokenPatchKey: "token", - tokenResult: { useEnv: false, token: tokenResult.value }, - }); - resolvedTokenForAllowlist = tokenResult.resolvedValue; - } + next = tokenStep.cfg; const currentEntries = Object.entries(resolvedAccount.config.guilds ?? {}).flatMap( ([guildKey, value]) => { @@ -261,7 +247,7 @@ export const discordOnboardingAdapter: ChannelOnboardingAdapter = { input, resolved: false, })); - const activeToken = accountWithTokens.token || resolvedTokenForAllowlist || ""; + const activeToken = accountWithTokens.token || tokenStep.resolvedValue || ""; if (activeToken && entries.length > 0) { try { resolved = await resolveDiscordChannelAllowlist({ diff --git a/src/channels/plugins/onboarding/helpers.ts b/src/channels/plugins/onboarding/helpers.ts index 8880162064c..6eab25fd239 100644 --- a/src/channels/plugins/onboarding/helpers.ts +++ b/src/channels/plugins/onboarding/helpers.ts @@ -482,6 +482,82 @@ export type SingleChannelSecretInputPromptResult = | { action: "use-env" } | { action: "set"; value: SecretInput; resolvedValue: string }; +export async function runSingleChannelSecretStep(params: { + cfg: OpenClawConfig; + prompter: Pick; + providerHint: string; + credentialLabel: string; + secretInputMode?: "plaintext" | "ref"; + accountConfigured: boolean; + hasConfigToken: boolean; + allowEnv: boolean; + envValue?: string; + envPrompt: string; + keepPrompt: string; + inputPrompt: string; + preferredEnvVar?: string; + onMissingConfigured?: () => Promise; + applyUseEnv?: (cfg: OpenClawConfig) => OpenClawConfig | Promise; + applySet?: ( + cfg: OpenClawConfig, + value: SecretInput, + resolvedValue: string, + ) => OpenClawConfig | Promise; +}): Promise<{ + cfg: OpenClawConfig; + action: SingleChannelSecretInputPromptResult["action"]; + resolvedValue?: string; +}> { + const promptState = buildSingleChannelSecretPromptState({ + accountConfigured: params.accountConfigured, + hasConfigToken: params.hasConfigToken, + allowEnv: params.allowEnv, + envValue: params.envValue, + }); + + if (!promptState.accountConfigured && params.onMissingConfigured) { + await params.onMissingConfigured(); + } + + const result = await promptSingleChannelSecretInput({ + cfg: params.cfg, + prompter: params.prompter, + providerHint: params.providerHint, + credentialLabel: params.credentialLabel, + secretInputMode: params.secretInputMode, + accountConfigured: promptState.accountConfigured, + canUseEnv: promptState.canUseEnv, + hasConfigToken: promptState.hasConfigToken, + envPrompt: params.envPrompt, + keepPrompt: params.keepPrompt, + inputPrompt: params.inputPrompt, + preferredEnvVar: params.preferredEnvVar, + }); + + if (result.action === "use-env") { + return { + cfg: params.applyUseEnv ? await params.applyUseEnv(params.cfg) : params.cfg, + action: result.action, + resolvedValue: params.envValue?.trim() || undefined, + }; + } + + if (result.action === "set") { + return { + cfg: params.applySet + ? await params.applySet(params.cfg, result.value, result.resolvedValue) + : params.cfg, + action: result.action, + resolvedValue: result.resolvedValue, + }; + } + + return { + cfg: params.cfg, + action: result.action, + }; +} + export async function promptSingleChannelSecretInput(params: { cfg: OpenClawConfig; prompter: Pick; diff --git a/src/channels/plugins/onboarding/slack.ts b/src/channels/plugins/onboarding/slack.ts index cc683477c09..0cceb859e4d 100644 --- a/src/channels/plugins/onboarding/slack.ts +++ b/src/channels/plugins/onboarding/slack.ts @@ -14,15 +14,14 @@ import type { WizardPrompter } from "../../../wizard/prompts.js"; import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js"; import { configureChannelAccessWithAllowlist } from "./channel-access-configure.js"; import { - buildSingleChannelSecretPromptState, parseMentionOrPrefixedId, noteChannelLookupFailure, noteChannelLookupSummary, patchChannelConfigForAccount, promptLegacyChannelAllowFrom, - promptSingleChannelSecretInput, resolveAccountIdForConfigure, resolveOnboardingAccountId, + runSingleChannelSecretStep, setAccountGroupPolicyForChannel, setLegacyChannelDmPolicyWithAllowFrom, setOnboardingChannelEnabled, @@ -235,18 +234,6 @@ export const slackOnboardingAdapter: ChannelOnboardingAdapter = { const accountConfigured = Boolean(resolvedAccount.botToken && resolvedAccount.appToken) || hasConfigTokens; const allowEnv = slackAccountId === DEFAULT_ACCOUNT_ID; - const botPromptState = buildSingleChannelSecretPromptState({ - accountConfigured: Boolean(resolvedAccount.botToken) || hasConfiguredBotToken, - hasConfigToken: hasConfiguredBotToken, - allowEnv, - envValue: process.env.SLACK_BOT_TOKEN, - }); - const appPromptState = buildSingleChannelSecretPromptState({ - accountConfigured: Boolean(resolvedAccount.appToken) || hasConfiguredAppToken, - hasConfigToken: hasConfiguredAppToken, - allowEnv, - envValue: process.env.SLACK_APP_TOKEN, - }); let resolvedBotTokenForAllowlist = resolvedAccount.botToken; const slackBotName = String( await prompter.text({ @@ -257,54 +244,56 @@ export const slackOnboardingAdapter: ChannelOnboardingAdapter = { if (!accountConfigured) { await noteSlackTokenHelp(prompter, slackBotName); } - const botTokenResult = await promptSingleChannelSecretInput({ + const botTokenStep = await runSingleChannelSecretStep({ cfg: next, prompter, providerHint: "slack-bot", credentialLabel: "Slack bot token", secretInputMode: options?.secretInputMode, - accountConfigured: botPromptState.accountConfigured, - canUseEnv: botPromptState.canUseEnv, - hasConfigToken: botPromptState.hasConfigToken, + accountConfigured: Boolean(resolvedAccount.botToken) || hasConfiguredBotToken, + hasConfigToken: hasConfiguredBotToken, + allowEnv, + envValue: process.env.SLACK_BOT_TOKEN, envPrompt: "SLACK_BOT_TOKEN detected. Use env var?", keepPrompt: "Slack bot token already configured. Keep it?", inputPrompt: "Enter Slack bot token (xoxb-...)", preferredEnvVar: allowEnv ? "SLACK_BOT_TOKEN" : undefined, + applySet: async (cfg, value) => + patchChannelConfigForAccount({ + cfg, + channel: "slack", + accountId: slackAccountId, + patch: { botToken: value }, + }), }); - if (botTokenResult.action === "use-env") { - resolvedBotTokenForAllowlist = process.env.SLACK_BOT_TOKEN?.trim() || undefined; - } else if (botTokenResult.action === "set") { - next = patchChannelConfigForAccount({ - cfg: next, - channel: "slack", - accountId: slackAccountId, - patch: { botToken: botTokenResult.value }, - }); - resolvedBotTokenForAllowlist = botTokenResult.resolvedValue; + next = botTokenStep.cfg; + if (botTokenStep.resolvedValue) { + resolvedBotTokenForAllowlist = botTokenStep.resolvedValue; } - const appTokenResult = await promptSingleChannelSecretInput({ + const appTokenStep = await runSingleChannelSecretStep({ cfg: next, prompter, providerHint: "slack-app", credentialLabel: "Slack app token", secretInputMode: options?.secretInputMode, - accountConfigured: appPromptState.accountConfigured, - canUseEnv: appPromptState.canUseEnv, - hasConfigToken: appPromptState.hasConfigToken, + accountConfigured: Boolean(resolvedAccount.appToken) || hasConfiguredAppToken, + hasConfigToken: hasConfiguredAppToken, + allowEnv, + envValue: process.env.SLACK_APP_TOKEN, envPrompt: "SLACK_APP_TOKEN detected. Use env var?", keepPrompt: "Slack app token already configured. Keep it?", inputPrompt: "Enter Slack app token (xapp-...)", preferredEnvVar: allowEnv ? "SLACK_APP_TOKEN" : undefined, + applySet: async (cfg, value) => + patchChannelConfigForAccount({ + cfg, + channel: "slack", + accountId: slackAccountId, + patch: { appToken: value }, + }), }); - if (appTokenResult.action === "set") { - next = patchChannelConfigForAccount({ - cfg: next, - channel: "slack", - accountId: slackAccountId, - patch: { appToken: appTokenResult.value }, - }); - } + next = appTokenStep.cfg; next = await configureChannelAccessWithAllowlist({ cfg: next, diff --git a/src/channels/plugins/onboarding/telegram.ts b/src/channels/plugins/onboarding/telegram.ts index 22a173d47fe..2c37c24bcee 100644 --- a/src/channels/plugins/onboarding/telegram.ts +++ b/src/channels/plugins/onboarding/telegram.ts @@ -14,12 +14,11 @@ import { fetchTelegramChatId } from "../../telegram/api.js"; import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js"; import { applySingleTokenPromptResult, - buildSingleChannelSecretPromptState, patchChannelConfigForAccount, - promptSingleChannelSecretInput, promptResolvedAllowFrom, resolveAccountIdForConfigure, resolveOnboardingAccountId, + runSingleChannelSecretStep, setChannelDmPolicyWithAllowFrom, setOnboardingChannelEnabled, splitOnboardingEntries, @@ -194,59 +193,46 @@ export const telegramOnboardingAdapter: ChannelOnboardingAdapter = { const hasConfigToken = hasConfiguredBotToken || Boolean(resolvedAccount.config.tokenFile?.trim()); const allowEnv = telegramAccountId === DEFAULT_ACCOUNT_ID; - const tokenPromptState = buildSingleChannelSecretPromptState({ - accountConfigured: Boolean(resolvedAccount.token) || hasConfigToken, - hasConfigToken, - allowEnv, - envValue: process.env.TELEGRAM_BOT_TOKEN, - }); - - if (!tokenPromptState.accountConfigured) { - await noteTelegramTokenHelp(prompter); - } - - const tokenResult = await promptSingleChannelSecretInput({ + const tokenStep = await runSingleChannelSecretStep({ cfg: next, prompter, providerHint: "telegram", credentialLabel: "Telegram bot token", secretInputMode: options?.secretInputMode, - accountConfigured: tokenPromptState.accountConfigured, - canUseEnv: tokenPromptState.canUseEnv, - hasConfigToken: tokenPromptState.hasConfigToken, + accountConfigured: Boolean(resolvedAccount.token) || hasConfigToken, + hasConfigToken, + allowEnv, + envValue: process.env.TELEGRAM_BOT_TOKEN, envPrompt: "TELEGRAM_BOT_TOKEN detected. Use env var?", keepPrompt: "Telegram token already configured. Keep it?", inputPrompt: "Enter Telegram bot token", preferredEnvVar: allowEnv ? "TELEGRAM_BOT_TOKEN" : undefined, + onMissingConfigured: async () => await noteTelegramTokenHelp(prompter), + applyUseEnv: async (cfg) => + applySingleTokenPromptResult({ + cfg, + channel: "telegram", + accountId: telegramAccountId, + tokenPatchKey: "botToken", + tokenResult: { useEnv: true, token: null }, + }), + applySet: async (cfg, value) => + applySingleTokenPromptResult({ + cfg, + channel: "telegram", + accountId: telegramAccountId, + tokenPatchKey: "botToken", + tokenResult: { useEnv: false, token: value }, + }), }); - - let resolvedTokenForAllowFrom: string | undefined; - if (tokenResult.action === "use-env") { - next = applySingleTokenPromptResult({ - cfg: next, - channel: "telegram", - accountId: telegramAccountId, - tokenPatchKey: "botToken", - tokenResult: { useEnv: true, token: null }, - }); - resolvedTokenForAllowFrom = process.env.TELEGRAM_BOT_TOKEN?.trim() || undefined; - } else if (tokenResult.action === "set") { - next = applySingleTokenPromptResult({ - cfg: next, - channel: "telegram", - accountId: telegramAccountId, - tokenPatchKey: "botToken", - tokenResult: { useEnv: false, token: tokenResult.value }, - }); - resolvedTokenForAllowFrom = tokenResult.resolvedValue; - } + next = tokenStep.cfg; if (forceAllowFrom) { next = await promptTelegramAllowFrom({ cfg: next, prompter, accountId: telegramAccountId, - tokenOverride: resolvedTokenForAllowFrom, + tokenOverride: tokenStep.resolvedValue, }); } diff --git a/src/plugin-sdk/mattermost.ts b/src/plugin-sdk/mattermost.ts index 7b574dd3eeb..fb77580359b 100644 --- a/src/plugin-sdk/mattermost.ts +++ b/src/plugin-sdk/mattermost.ts @@ -33,6 +33,7 @@ export { buildSingleChannelSecretPromptState, promptAccountId, promptSingleChannelSecretInput, + runSingleChannelSecretStep, resolveAccountIdForConfigure, } from "../channels/plugins/onboarding/helpers.js"; export { diff --git a/src/plugin-sdk/nextcloud-talk.ts b/src/plugin-sdk/nextcloud-talk.ts index b0d4a84c32d..6e5c6a28b5b 100644 --- a/src/plugin-sdk/nextcloud-talk.ts +++ b/src/plugin-sdk/nextcloud-talk.ts @@ -27,6 +27,7 @@ export { mergeAllowFromEntries, promptAccountId, promptSingleChannelSecretInput, + runSingleChannelSecretStep, resolveAccountIdForConfigure, setTopLevelChannelDmPolicyWithAllowFrom, } from "../channels/plugins/onboarding/helpers.js"; diff --git a/src/plugin-sdk/zalo.ts b/src/plugin-sdk/zalo.ts index 2196493009e..b5c69486f60 100644 --- a/src/plugin-sdk/zalo.ts +++ b/src/plugin-sdk/zalo.ts @@ -21,6 +21,7 @@ export { mergeAllowFromEntries, promptAccountId, promptSingleChannelSecretInput, + runSingleChannelSecretStep, resolveAccountIdForConfigure, setTopLevelChannelDmPolicyWithAllowFrom, } from "../channels/plugins/onboarding/helpers.js";