diff --git a/README.md b/README.md index 2b4067bd3..218e967ee 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ Minimal `~/.clawdis/clawdis.json`: ### Telegram - Set `TELEGRAM_BOT_TOKEN` or `telegram.botToken` (env wins). -- Optional: set `telegram.requireMention`, `telegram.allowFrom`, or `telegram.webhookUrl` as needed. +- Optional: set `telegram.groups` (with `telegram.groups."*".requireMention`), `telegram.allowFrom`, or `telegram.webhookUrl` as needed. ```json5 { diff --git a/src/auto-reply/reply.ts b/src/auto-reply/reply.ts index 91d4a0ac6..10cd9eda7 100644 --- a/src/auto-reply/reply.ts +++ b/src/auto-reply/reply.ts @@ -995,8 +995,8 @@ export async function getReplyFromConfig( const webAuthAgeMs = getWebAuthAgeMs(); const heartbeatSeconds = resolveHeartbeatSeconds(cfg, undefined); const groupActivation = isGroup - ? normalizeGroupActivation(sessionEntry?.groupActivation) ?? - defaultGroupActivation() + ? (normalizeGroupActivation(sessionEntry?.groupActivation) ?? + defaultGroupActivation()) : undefined; const statusText = buildStatusMessage({ agent: { diff --git a/src/config/config.ts b/src/config/config.ts index 1a04a2348..f5508d497 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -1235,7 +1235,7 @@ const LEGACY_CONFIG_RULES: LegacyConfigRule[] = [ { path: ["telegram", "requireMention"], message: - "telegram.requireMention was removed; use telegram.groups.\"*\".requireMention instead (run `clawdis doctor` to migrate).", + 'telegram.requireMention was removed; use telegram.groups."*".requireMention instead (run `clawdis doctor` to migrate).', }, ]; @@ -1280,8 +1280,10 @@ const LEGACY_CONFIG_MIGRATIONS: LegacyConfigMigration[] = [ const groupChat = (routing as Record).groupChat && typeof (routing as Record).groupChat === "object" - ? ((routing as Record) - .groupChat as Record) + ? ((routing as Record).groupChat as Record< + string, + unknown + >) : null; if (!groupChat) return; const requireMention = groupChat.requireMention; @@ -1331,18 +1333,22 @@ const LEGACY_CONFIG_MIGRATIONS: LegacyConfigMigration[] = [ }, { id: "telegram.requireMention->telegram.groups.*.requireMention", - describe: "Move telegram.requireMention to telegram.groups.*.requireMention", + describe: + "Move telegram.requireMention to telegram.groups.*.requireMention", apply: (raw, changes) => { const telegram = raw.telegram; if (!telegram || typeof telegram !== "object") return; - const requireMention = (telegram as Record).requireMention; + const requireMention = (telegram as Record) + .requireMention; if (requireMention === undefined) return; const groups = (telegram as Record).groups && typeof (telegram as Record).groups === "object" - ? ((telegram as Record) - .groups as Record) + ? ((telegram as Record).groups as Record< + string, + unknown + >) : {}; const defaultKey = "*"; const entry = diff --git a/src/telegram/bot.test.ts b/src/telegram/bot.test.ts index 19df8842d..a6cade3e4 100644 --- a/src/telegram/bot.test.ts +++ b/src/telegram/bot.test.ts @@ -2,7 +2,9 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import * as replyModule from "../auto-reply/reply.js"; import { createTelegramBot } from "./bot.js"; -const loadConfig = vi.fn(() => ({})); +const { loadConfig } = vi.hoisted(() => ({ + loadConfig: vi.fn(() => ({})), +})); vi.mock("../config/config.js", () => ({ loadConfig, })); diff --git a/ui/src/ui/controllers/config.ts b/ui/src/ui/controllers/config.ts index 3c2b78acb..4b4023650 100644 --- a/ui/src/ui/controllers/config.ts +++ b/ui/src/ui/controllers/config.ts @@ -58,6 +58,14 @@ export function applyConfigSnapshot(state: ConfigState, snapshot: ConfigSnapshot .filter((v) => v.length > 0) .join(", ") : ""; + const telegramGroups = + telegram.groups && typeof telegram.groups === "object" + ? (telegram.groups as Record) + : {}; + const telegramDefaultGroup = + telegramGroups["*"] && typeof telegramGroups["*"] === "object" + ? (telegramGroups["*"] as Record) + : {}; const allowFrom = Array.isArray(telegram.allowFrom) ? toList(telegram.allowFrom) : typeof telegram.allowFrom === "string" @@ -67,7 +75,9 @@ export function applyConfigSnapshot(state: ConfigState, snapshot: ConfigSnapshot state.telegramForm = { token: typeof telegram.botToken === "string" ? telegram.botToken : "", requireMention: - typeof telegram.requireMention === "boolean" ? telegram.requireMention : true, + typeof telegramDefaultGroup.requireMention === "boolean" + ? telegramDefaultGroup.requireMention + : true, allowFrom, proxy: typeof telegram.proxy === "string" ? telegram.proxy : "", webhookUrl: typeof telegram.webhookUrl === "string" ? telegram.webhookUrl : "", diff --git a/ui/src/ui/controllers/connections.ts b/ui/src/ui/controllers/connections.ts index a1ab69d81..3791dbdac 100644 --- a/ui/src/ui/controllers/connections.ts +++ b/ui/src/ui/controllers/connections.ts @@ -147,7 +147,24 @@ export async function saveTelegramConfig(state: ConnectionsState) { if (token) telegram.botToken = token; else delete telegram.botToken; } - telegram.requireMention = state.telegramForm.requireMention; + const groups = + telegram.groups && typeof telegram.groups === "object" + ? ({ ...(telegram.groups as Record) } as Record< + string, + unknown + >) + : {}; + const defaultGroup = + groups["*"] && typeof groups["*"] === "object" + ? ({ ...(groups["*"] as Record) } as Record< + string, + unknown + >) + : {}; + defaultGroup.requireMention = state.telegramForm.requireMention; + groups["*"] = defaultGroup; + telegram.groups = groups; + delete telegram.requireMention; const allowFrom = parseList(state.telegramForm.allowFrom); if (allowFrom.length > 0) telegram.allowFrom = allowFrom; else delete telegram.allowFrom; diff --git a/ui/src/ui/views/connections.ts b/ui/src/ui/views/connections.ts index 64d176e72..ea3485406 100644 --- a/ui/src/ui/views/connections.ts +++ b/ui/src/ui/views/connections.ts @@ -298,7 +298,7 @@ function renderProvider( />