mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-26 16:06:16 +00:00
test: speed up setup surface tests
This commit is contained in:
@@ -1,6 +1,21 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { discordSetupWizard } from "./setup-surface.js";
|
||||
import { createDiscordSetupWizardBase } from "./setup-core.js";
|
||||
|
||||
const discordSetupWizard = createDiscordSetupWizardBase({
|
||||
promptAllowFrom: async ({ cfg }) => cfg,
|
||||
resolveAllowFromEntries: async ({ entries }) =>
|
||||
entries.map((entry) => ({
|
||||
input: entry,
|
||||
resolved: false,
|
||||
id: null,
|
||||
})),
|
||||
resolveGroupAllowlist: async ({ entries }) =>
|
||||
entries.map((entry) => ({
|
||||
input: entry,
|
||||
resolved: false,
|
||||
})),
|
||||
});
|
||||
|
||||
describe("discordSetupWizard.dmPolicy", () => {
|
||||
it("reads the named-account DM policy instead of the channel root", () => {
|
||||
|
||||
@@ -13,7 +13,9 @@ import {
|
||||
import { createStartAccountContext } from "../../../test/helpers/plugins/start-account-context.js";
|
||||
import type { OpenClawConfig, PluginRuntime, ResolvedLineAccount } from "../api.js";
|
||||
import { linePlugin } from "./channel.js";
|
||||
import { probeLineBot } from "./probe.js";
|
||||
import { clearLineRuntime, setLineRuntime } from "./runtime.js";
|
||||
import { lineSetupWizard } from "./setup-surface.js";
|
||||
|
||||
const { getBotInfoMock, MessagingApiClientMock } = vi.hoisted(() => {
|
||||
const getBotInfoMock = vi.fn();
|
||||
@@ -175,8 +177,6 @@ describe("line setup wizard", () => {
|
||||
});
|
||||
|
||||
it("reads the named-account DM policy instead of the channel root", async () => {
|
||||
const { lineSetupWizard } = await import("./setup-surface.js");
|
||||
|
||||
expect(
|
||||
lineSetupWizard.dmPolicy?.getCurrent(
|
||||
{
|
||||
@@ -199,8 +199,6 @@ describe("line setup wizard", () => {
|
||||
});
|
||||
|
||||
it("reports account-scoped config keys for named accounts", async () => {
|
||||
const { lineSetupWizard } = await import("./setup-surface.js");
|
||||
|
||||
expect(lineSetupWizard.dmPolicy?.resolveConfigKeys?.({} as OpenClawConfig, "work")).toEqual({
|
||||
policyKey: "channels.line.accounts.work.dmPolicy",
|
||||
allowFromKey: "channels.line.accounts.work.allowFrom",
|
||||
@@ -208,8 +206,6 @@ describe("line setup wizard", () => {
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount for omitted DM policy account context", async () => {
|
||||
const { lineSetupWizard } = await import("./setup-surface.js");
|
||||
|
||||
const cfg = {
|
||||
channels: {
|
||||
line: {
|
||||
@@ -244,8 +240,6 @@ describe("line setup wizard", () => {
|
||||
});
|
||||
|
||||
it('writes open policy state to the named account and preserves inherited allowFrom with "*"', async () => {
|
||||
const { lineSetupWizard } = await import("./setup-surface.js");
|
||||
|
||||
const next = lineSetupWizard.dmPolicy?.setPolicy(
|
||||
{
|
||||
channels: {
|
||||
@@ -277,8 +271,6 @@ describe("line setup wizard", () => {
|
||||
});
|
||||
|
||||
it("uses configured defaultAccount for omitted setup configured state", async () => {
|
||||
const { lineSetupWizard } = await import("./setup-surface.js");
|
||||
|
||||
const configured = await lineSetupWizard.status.resolveConfigured({
|
||||
cfg: {
|
||||
channels: {
|
||||
@@ -321,7 +313,6 @@ describe("probeLineBot", () => {
|
||||
});
|
||||
|
||||
it("returns timeout when bot info stalls", async () => {
|
||||
const { probeLineBot } = await import("./probe.js");
|
||||
vi.useFakeTimers();
|
||||
getBotInfoMock.mockImplementation(() => new Promise(() => {}));
|
||||
|
||||
@@ -334,7 +325,6 @@ describe("probeLineBot", () => {
|
||||
});
|
||||
|
||||
it("returns bot info when available", async () => {
|
||||
const { probeLineBot } = await import("./probe.js");
|
||||
getBotInfoMock.mockResolvedValue({
|
||||
displayName: "OpenClaw",
|
||||
userId: "U123",
|
||||
@@ -351,7 +341,6 @@ describe("probeLineBot", () => {
|
||||
|
||||
describe("linePlugin status.probeAccount", () => {
|
||||
it("falls back to the direct probe helper when runtime is not initialized", async () => {
|
||||
const { probeLineBot } = await import("./probe.js");
|
||||
MessagingApiClientMock.mockReset();
|
||||
MessagingApiClientMock.mockImplementation(function () {
|
||||
return { getBotInfo: getBotInfoMock };
|
||||
|
||||
@@ -5,7 +5,18 @@ import {
|
||||
runSetupWizardFinalize,
|
||||
type WizardPrompter,
|
||||
} from "../../../test/helpers/plugins/setup-wizard.js";
|
||||
import { slackSetupWizard } from "./setup-surface.js";
|
||||
import { createSlackSetupWizardBase } from "./setup-core.js";
|
||||
|
||||
const slackSetupWizard = createSlackSetupWizardBase({
|
||||
promptAllowFrom: async ({ cfg }) => cfg,
|
||||
resolveAllowFromEntries: async ({ entries }) =>
|
||||
entries.map((entry) => ({
|
||||
input: entry,
|
||||
resolved: false,
|
||||
id: null,
|
||||
})),
|
||||
resolveGroupAllowlist: async ({ entries }) => entries,
|
||||
});
|
||||
|
||||
describe("slackSetupWizard.finalize", () => {
|
||||
const baseCfg = {
|
||||
|
||||
107
extensions/telegram/src/setup-surface.helpers.ts
Normal file
107
extensions/telegram/src/setup-surface.helpers.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import {
|
||||
addWildcardAllowFrom,
|
||||
applySetupAccountConfigPatch,
|
||||
type ChannelSetupDmPolicy,
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
type OpenClawConfig,
|
||||
patchChannelConfigForAccount,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
|
||||
import {
|
||||
mergeTelegramAccountConfig,
|
||||
resolveDefaultTelegramAccountId,
|
||||
resolveTelegramAccount,
|
||||
} from "./accounts.js";
|
||||
import { promptTelegramAllowFromForAccount } from "./setup-core.js";
|
||||
|
||||
const channel = "telegram" as const;
|
||||
|
||||
export function ensureTelegramDefaultGroupMentionGate(
|
||||
cfg: OpenClawConfig,
|
||||
accountId: string,
|
||||
): OpenClawConfig {
|
||||
const resolved = resolveTelegramAccount({ cfg, accountId });
|
||||
const wildcardGroup = resolved.config.groups?.["*"];
|
||||
if (wildcardGroup?.requireMention !== undefined) {
|
||||
return cfg;
|
||||
}
|
||||
return patchChannelConfigForAccount({
|
||||
cfg,
|
||||
channel,
|
||||
accountId,
|
||||
patch: {
|
||||
groups: {
|
||||
...resolved.config.groups,
|
||||
"*": {
|
||||
...wildcardGroup,
|
||||
requireMention: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function shouldShowTelegramDmAccessWarning(cfg: OpenClawConfig, accountId: string): boolean {
|
||||
const merged = mergeTelegramAccountConfig(cfg, accountId);
|
||||
const policy = merged.dmPolicy ?? "pairing";
|
||||
const hasAllowFrom =
|
||||
Array.isArray(merged.allowFrom) && merged.allowFrom.some((entry) => String(entry).trim());
|
||||
return policy === "pairing" && !hasAllowFrom;
|
||||
}
|
||||
|
||||
export function buildTelegramDmAccessWarningLines(accountId: string): string[] {
|
||||
const configBase =
|
||||
accountId === DEFAULT_ACCOUNT_ID
|
||||
? "channels.telegram"
|
||||
: `channels.telegram.accounts.${accountId}`;
|
||||
return [
|
||||
"Your bot is using DM policy: pairing.",
|
||||
"Any Telegram user who discovers the bot can send pairing requests.",
|
||||
"For private use, configure an allowlist with your Telegram user id:",
|
||||
" " + formatCliCommand(`openclaw config set ${configBase}.dmPolicy "allowlist"`),
|
||||
" " + formatCliCommand(`openclaw config set ${configBase}.allowFrom '["YOUR_USER_ID"]'`),
|
||||
`Docs: ${formatDocsLink("/channels/pairing", "channels/pairing")}`,
|
||||
];
|
||||
}
|
||||
|
||||
export const telegramSetupDmPolicy: ChannelSetupDmPolicy = {
|
||||
label: "Telegram",
|
||||
channel,
|
||||
policyKey: "channels.telegram.dmPolicy",
|
||||
allowFromKey: "channels.telegram.allowFrom",
|
||||
resolveConfigKeys: (cfg, accountId) =>
|
||||
(accountId ?? resolveDefaultTelegramAccountId(cfg)) !== DEFAULT_ACCOUNT_ID
|
||||
? {
|
||||
policyKey: `channels.telegram.accounts.${accountId ?? resolveDefaultTelegramAccountId(cfg)}.dmPolicy`,
|
||||
allowFromKey: `channels.telegram.accounts.${accountId ?? resolveDefaultTelegramAccountId(cfg)}.allowFrom`,
|
||||
}
|
||||
: {
|
||||
policyKey: "channels.telegram.dmPolicy",
|
||||
allowFromKey: "channels.telegram.allowFrom",
|
||||
},
|
||||
getCurrent: (cfg, accountId) =>
|
||||
mergeTelegramAccountConfig(cfg, accountId ?? resolveDefaultTelegramAccountId(cfg)).dmPolicy ??
|
||||
"pairing",
|
||||
setPolicy: (cfg, policy, accountId) => {
|
||||
const resolvedAccountId = accountId ?? resolveDefaultTelegramAccountId(cfg);
|
||||
const merged = mergeTelegramAccountConfig(cfg, resolvedAccountId);
|
||||
const patch = {
|
||||
dmPolicy: policy,
|
||||
...(policy === "open" ? { allowFrom: addWildcardAllowFrom(merged.allowFrom) } : {}),
|
||||
};
|
||||
return accountId == null && resolvedAccountId !== DEFAULT_ACCOUNT_ID
|
||||
? applySetupAccountConfigPatch({
|
||||
cfg,
|
||||
channelKey: channel,
|
||||
accountId: resolvedAccountId,
|
||||
patch,
|
||||
})
|
||||
: patchChannelConfigForAccount({
|
||||
cfg,
|
||||
channel,
|
||||
accountId: resolvedAccountId,
|
||||
patch,
|
||||
});
|
||||
},
|
||||
promptAllowFrom: promptTelegramAllowFromForAccount,
|
||||
};
|
||||
@@ -1,171 +1,97 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/setup";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
createTestWizardPrompter,
|
||||
runSetupWizardFinalize,
|
||||
runSetupWizardPrepare,
|
||||
} from "../../../test/helpers/plugins/setup-wizard.js";
|
||||
import { resolveTelegramAllowFromEntries } from "./setup-core.js";
|
||||
import { telegramSetupWizard } from "./setup-surface.js";
|
||||
import {
|
||||
buildTelegramDmAccessWarningLines,
|
||||
ensureTelegramDefaultGroupMentionGate,
|
||||
shouldShowTelegramDmAccessWarning,
|
||||
telegramSetupDmPolicy,
|
||||
} from "./setup-surface.helpers.js";
|
||||
|
||||
async function runPrepare(cfg: OpenClawConfig, accountId: string) {
|
||||
return await runSetupWizardPrepare({
|
||||
prepare: telegramSetupWizard.prepare,
|
||||
cfg,
|
||||
accountId,
|
||||
options: {},
|
||||
});
|
||||
}
|
||||
|
||||
async function runFinalize(cfg: OpenClawConfig, accountId: string) {
|
||||
const note = vi.fn(async () => undefined);
|
||||
|
||||
await runSetupWizardFinalize({
|
||||
finalize: telegramSetupWizard.finalize,
|
||||
cfg,
|
||||
accountId,
|
||||
prompter: createTestWizardPrompter({ note }),
|
||||
});
|
||||
|
||||
return note;
|
||||
}
|
||||
|
||||
function expectPreparedResult(
|
||||
prepared: Awaited<ReturnType<typeof runPrepare>>,
|
||||
): { cfg: OpenClawConfig } & Exclude<Awaited<ReturnType<typeof runPrepare>>, void | undefined> {
|
||||
expect(prepared).toBeDefined();
|
||||
if (
|
||||
!prepared ||
|
||||
typeof prepared !== "object" ||
|
||||
!("cfg" in prepared) ||
|
||||
prepared.cfg === undefined
|
||||
) {
|
||||
throw new Error("Expected prepare result with cfg");
|
||||
}
|
||||
return prepared as { cfg: OpenClawConfig } & Exclude<
|
||||
Awaited<ReturnType<typeof runPrepare>>,
|
||||
void | undefined
|
||||
>;
|
||||
}
|
||||
|
||||
describe("telegramSetupWizard.prepare", () => {
|
||||
describe("ensureTelegramDefaultGroupMentionGate", () => {
|
||||
it('adds groups["*"].requireMention=true for fresh setups', async () => {
|
||||
const prepared = expectPreparedResult(
|
||||
await runPrepare(
|
||||
{
|
||||
channels: {
|
||||
telegram: {
|
||||
botToken: "tok",
|
||||
},
|
||||
const cfg = ensureTelegramDefaultGroupMentionGate(
|
||||
{
|
||||
channels: {
|
||||
telegram: {
|
||||
botToken: "tok",
|
||||
},
|
||||
},
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
),
|
||||
},
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
);
|
||||
|
||||
expect(prepared.cfg.channels?.telegram?.groups).toEqual({
|
||||
expect(cfg.channels?.telegram?.groups).toEqual({
|
||||
"*": { requireMention: true },
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves an explicit wildcard group mention setting", async () => {
|
||||
const prepared = expectPreparedResult(
|
||||
await runPrepare(
|
||||
{
|
||||
channels: {
|
||||
telegram: {
|
||||
botToken: "tok",
|
||||
groups: {
|
||||
"*": { requireMention: false },
|
||||
},
|
||||
const cfg = ensureTelegramDefaultGroupMentionGate(
|
||||
{
|
||||
channels: {
|
||||
telegram: {
|
||||
botToken: "tok",
|
||||
groups: {
|
||||
"*": { requireMention: false },
|
||||
},
|
||||
},
|
||||
},
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
),
|
||||
},
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
);
|
||||
|
||||
expect(prepared.cfg.channels?.telegram?.groups).toEqual({
|
||||
expect(cfg.channels?.telegram?.groups).toEqual({
|
||||
"*": { requireMention: false },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("telegramSetupWizard.finalize", () => {
|
||||
it("shows global config commands for the default account", async () => {
|
||||
const note = await runFinalize(
|
||||
{
|
||||
channels: {
|
||||
telegram: {
|
||||
botToken: "tok",
|
||||
},
|
||||
},
|
||||
},
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
);
|
||||
describe("telegram DM access warning helpers", () => {
|
||||
it("shows global config commands for the default account", () => {
|
||||
const lines = buildTelegramDmAccessWarningLines(DEFAULT_ACCOUNT_ID);
|
||||
|
||||
expect(note).toHaveBeenCalledWith(
|
||||
expect.stringContaining('openclaw config set channels.telegram.dmPolicy "allowlist"'),
|
||||
"Telegram DM access warning",
|
||||
expect(lines.join("\n")).toContain(
|
||||
'openclaw config set channels.telegram.dmPolicy "allowlist"',
|
||||
);
|
||||
expect(note).toHaveBeenCalledWith(
|
||||
expect.stringContaining(`openclaw config set channels.telegram.allowFrom '["YOUR_USER_ID"]'`),
|
||||
"Telegram DM access warning",
|
||||
expect(lines.join("\n")).toContain(
|
||||
`openclaw config set channels.telegram.allowFrom '["YOUR_USER_ID"]'`,
|
||||
);
|
||||
});
|
||||
|
||||
it("shows account-scoped config commands for named accounts", async () => {
|
||||
const note = await runFinalize(
|
||||
{
|
||||
channels: {
|
||||
telegram: {
|
||||
accounts: {
|
||||
alerts: {
|
||||
botToken: "tok",
|
||||
},
|
||||
it("shows account-scoped config commands for named accounts", () => {
|
||||
const lines = buildTelegramDmAccessWarningLines("alerts");
|
||||
|
||||
expect(lines.join("\n")).toContain(
|
||||
'openclaw config set channels.telegram.accounts.alerts.dmPolicy "allowlist"',
|
||||
);
|
||||
expect(lines.join("\n")).toContain(
|
||||
`openclaw config set channels.telegram.accounts.alerts.allowFrom '["YOUR_USER_ID"]'`,
|
||||
);
|
||||
});
|
||||
|
||||
it("skips the warning when an allowFrom entry already exists", () => {
|
||||
expect(
|
||||
shouldShowTelegramDmAccessWarning(
|
||||
{
|
||||
channels: {
|
||||
telegram: {
|
||||
botToken: "tok",
|
||||
allowFrom: ["123"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"alerts",
|
||||
);
|
||||
|
||||
expect(note).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'openclaw config set channels.telegram.accounts.alerts.dmPolicy "allowlist"',
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
),
|
||||
"Telegram DM access warning",
|
||||
);
|
||||
expect(note).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
`openclaw config set channels.telegram.accounts.alerts.allowFrom '["YOUR_USER_ID"]'`,
|
||||
),
|
||||
"Telegram DM access warning",
|
||||
);
|
||||
});
|
||||
|
||||
it("skips the warning when an allowFrom entry already exists", async () => {
|
||||
const note = await runFinalize(
|
||||
{
|
||||
channels: {
|
||||
telegram: {
|
||||
botToken: "tok",
|
||||
allowFrom: ["123"],
|
||||
},
|
||||
},
|
||||
},
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
);
|
||||
|
||||
expect(note).not.toHaveBeenCalled();
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("telegramSetupWizard.dmPolicy", () => {
|
||||
describe("telegramSetupDmPolicy", () => {
|
||||
it("reads the named-account DM policy instead of the channel root", () => {
|
||||
expect(
|
||||
telegramSetupWizard.dmPolicy?.getCurrent(
|
||||
telegramSetupDmPolicy.getCurrent?.(
|
||||
{
|
||||
channels: {
|
||||
telegram: {
|
||||
@@ -185,7 +111,7 @@ describe("telegramSetupWizard.dmPolicy", () => {
|
||||
});
|
||||
|
||||
it("reports account-scoped config keys for named accounts", () => {
|
||||
expect(telegramSetupWizard.dmPolicy?.resolveConfigKeys?.({}, "alerts")).toEqual({
|
||||
expect(telegramSetupDmPolicy.resolveConfigKeys?.({}, "alerts")).toEqual({
|
||||
policyKey: "channels.telegram.accounts.alerts.dmPolicy",
|
||||
allowFromKey: "channels.telegram.accounts.alerts.allowFrom",
|
||||
});
|
||||
@@ -208,13 +134,13 @@ describe("telegramSetupWizard.dmPolicy", () => {
|
||||
},
|
||||
};
|
||||
|
||||
expect(telegramSetupWizard.dmPolicy?.getCurrent(cfg)).toBe("allowlist");
|
||||
expect(telegramSetupWizard.dmPolicy?.resolveConfigKeys?.(cfg)).toEqual({
|
||||
expect(telegramSetupDmPolicy.getCurrent?.(cfg)).toBe("allowlist");
|
||||
expect(telegramSetupDmPolicy.resolveConfigKeys?.(cfg)).toEqual({
|
||||
policyKey: "channels.telegram.accounts.alerts.dmPolicy",
|
||||
allowFromKey: "channels.telegram.accounts.alerts.allowFrom",
|
||||
});
|
||||
|
||||
const next = telegramSetupWizard.dmPolicy?.setPolicy(cfg, "open");
|
||||
const next = telegramSetupDmPolicy.setPolicy?.(cfg, "open");
|
||||
expect(next?.channels?.telegram?.dmPolicy).toBe("disabled");
|
||||
expect(next?.channels?.telegram?.accounts?.alerts?.dmPolicy).toBe("open");
|
||||
});
|
||||
@@ -233,7 +159,7 @@ describe("telegramSetupWizard.dmPolicy", () => {
|
||||
},
|
||||
};
|
||||
|
||||
const next = telegramSetupWizard.dmPolicy?.setPolicy(cfg, "open", "alerts");
|
||||
const next = telegramSetupDmPolicy.setPolicy?.(cfg, "open", "alerts");
|
||||
|
||||
expect(next?.channels?.telegram?.dmPolicy).toBeUndefined();
|
||||
expect(next?.channels?.telegram?.accounts?.alerts?.dmPolicy).toBe("open");
|
||||
|
||||
@@ -1,127 +1,30 @@
|
||||
import {
|
||||
addWildcardAllowFrom,
|
||||
applySetupAccountConfigPatch,
|
||||
createAllowFromSection,
|
||||
createStandardChannelSetupStatus,
|
||||
type ChannelSetupDmPolicy,
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
hasConfiguredSecretInput,
|
||||
type OpenClawConfig,
|
||||
patchChannelConfigForAccount,
|
||||
setSetupChannelEnabled,
|
||||
splitSetupEntries,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import type { ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
||||
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { inspectTelegramAccount } from "./account-inspect.js";
|
||||
import {
|
||||
listTelegramAccountIds,
|
||||
mergeTelegramAccountConfig,
|
||||
resolveDefaultTelegramAccountId,
|
||||
resolveTelegramAccount,
|
||||
} from "./accounts.js";
|
||||
import { listTelegramAccountIds, resolveTelegramAccount } from "./accounts.js";
|
||||
import {
|
||||
parseTelegramAllowFromId,
|
||||
promptTelegramAllowFromForAccount,
|
||||
resolveTelegramAllowFromEntries,
|
||||
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;
|
||||
|
||||
function ensureTelegramDefaultGroupMentionGate(
|
||||
cfg: OpenClawConfig,
|
||||
accountId: string,
|
||||
): OpenClawConfig {
|
||||
const resolved = resolveTelegramAccount({ cfg, accountId });
|
||||
const wildcardGroup = resolved.config.groups?.["*"];
|
||||
if (wildcardGroup?.requireMention !== undefined) {
|
||||
return cfg;
|
||||
}
|
||||
return patchChannelConfigForAccount({
|
||||
cfg,
|
||||
channel,
|
||||
accountId,
|
||||
patch: {
|
||||
groups: {
|
||||
...resolved.config.groups,
|
||||
"*": {
|
||||
...wildcardGroup,
|
||||
requireMention: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function shouldShowTelegramDmAccessWarning(cfg: OpenClawConfig, accountId: string): boolean {
|
||||
const merged = mergeTelegramAccountConfig(cfg, accountId);
|
||||
const policy = merged.dmPolicy ?? "pairing";
|
||||
const hasAllowFrom =
|
||||
Array.isArray(merged.allowFrom) && merged.allowFrom.some((e) => String(e).trim());
|
||||
return policy === "pairing" && !hasAllowFrom;
|
||||
}
|
||||
|
||||
function buildTelegramDmAccessWarningLines(accountId: string): string[] {
|
||||
const configBase =
|
||||
accountId === DEFAULT_ACCOUNT_ID
|
||||
? "channels.telegram"
|
||||
: `channels.telegram.accounts.${accountId}`;
|
||||
return [
|
||||
"Your bot is using DM policy: pairing.",
|
||||
"Any Telegram user who discovers the bot can send pairing requests.",
|
||||
"For private use, configure an allowlist with your Telegram user id:",
|
||||
" " + formatCliCommand(`openclaw config set ${configBase}.dmPolicy "allowlist"`),
|
||||
" " + formatCliCommand(`openclaw config set ${configBase}.allowFrom '["YOUR_USER_ID"]'`),
|
||||
`Docs: ${formatDocsLink("/channels/pairing", "channels/pairing")}`,
|
||||
];
|
||||
}
|
||||
|
||||
const dmPolicy: ChannelSetupDmPolicy = {
|
||||
label: "Telegram",
|
||||
channel,
|
||||
policyKey: "channels.telegram.dmPolicy",
|
||||
allowFromKey: "channels.telegram.allowFrom",
|
||||
resolveConfigKeys: (cfg, accountId) =>
|
||||
(accountId ?? resolveDefaultTelegramAccountId(cfg)) !== DEFAULT_ACCOUNT_ID
|
||||
? {
|
||||
policyKey: `channels.telegram.accounts.${accountId ?? resolveDefaultTelegramAccountId(cfg)}.dmPolicy`,
|
||||
allowFromKey: `channels.telegram.accounts.${accountId ?? resolveDefaultTelegramAccountId(cfg)}.allowFrom`,
|
||||
}
|
||||
: {
|
||||
policyKey: "channels.telegram.dmPolicy",
|
||||
allowFromKey: "channels.telegram.allowFrom",
|
||||
},
|
||||
getCurrent: (cfg, accountId) =>
|
||||
mergeTelegramAccountConfig(cfg, accountId ?? resolveDefaultTelegramAccountId(cfg)).dmPolicy ??
|
||||
"pairing",
|
||||
setPolicy: (cfg, policy, accountId) => {
|
||||
const resolvedAccountId = accountId ?? resolveDefaultTelegramAccountId(cfg);
|
||||
const merged = mergeTelegramAccountConfig(cfg, resolvedAccountId);
|
||||
const patch = {
|
||||
dmPolicy: policy,
|
||||
...(policy === "open" ? { allowFrom: addWildcardAllowFrom(merged.allowFrom) } : {}),
|
||||
};
|
||||
return accountId == null && resolvedAccountId !== DEFAULT_ACCOUNT_ID
|
||||
? applySetupAccountConfigPatch({
|
||||
cfg,
|
||||
channelKey: channel,
|
||||
accountId: resolvedAccountId,
|
||||
patch,
|
||||
})
|
||||
: patchChannelConfigForAccount({
|
||||
cfg,
|
||||
channel,
|
||||
accountId: resolvedAccountId,
|
||||
patch,
|
||||
});
|
||||
},
|
||||
promptAllowFrom: promptTelegramAllowFromForAccount,
|
||||
};
|
||||
|
||||
export const telegramSetupWizard: ChannelSetupWizard = {
|
||||
channel,
|
||||
status: createStandardChannelSetupStatus({
|
||||
@@ -204,7 +107,7 @@ export const telegramSetupWizard: ChannelSetupWizard = {
|
||||
"Telegram DM access warning",
|
||||
);
|
||||
},
|
||||
dmPolicy,
|
||||
dmPolicy: telegramSetupDmPolicy,
|
||||
disable: (cfg) => setSetupChannelEnabled(cfg, channel, false),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user