From 4100bea888e8d211707776201ea5b51f36e01aa7 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 23 Apr 2026 08:54:03 +0100 Subject: [PATCH] test(telegram): hide split message context files --- ...t-message-context.audio-transcript.test.ts | 159 ----------------- ...t-message-context.implicit-mention.test.ts | 147 ---------------- ...t-message-context.named-account-dm.test.ts | 160 ------------------ .../bot-message-context.sender-prefix.test.ts | 60 ------- ...t-message-context.session-recreate.test.ts | 99 ----------- .../bot-message-context.silent-ingest.test.ts | 146 ---------------- 6 files changed, 771 deletions(-) delete mode 100644 extensions/telegram/src/bot-message-context.audio-transcript.test.ts delete mode 100644 extensions/telegram/src/bot-message-context.implicit-mention.test.ts delete mode 100644 extensions/telegram/src/bot-message-context.named-account-dm.test.ts delete mode 100644 extensions/telegram/src/bot-message-context.sender-prefix.test.ts delete mode 100644 extensions/telegram/src/bot-message-context.session-recreate.test.ts delete mode 100644 extensions/telegram/src/bot-message-context.silent-ingest.test.ts diff --git a/extensions/telegram/src/bot-message-context.audio-transcript.test.ts b/extensions/telegram/src/bot-message-context.audio-transcript.test.ts deleted file mode 100644 index ef0d3503823..00000000000 --- a/extensions/telegram/src/bot-message-context.audio-transcript.test.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; - -const transcribeFirstAudioMock = vi.fn(); -const DEFAULT_MODEL = "anthropic/claude-opus-4-5"; -const DEFAULT_WORKSPACE = "/tmp/openclaw"; -const DEFAULT_MENTION_PATTERN = "\\bbot\\b"; - -vi.mock("./media-understanding.runtime.js", () => ({ - transcribeFirstAudio: (...args: unknown[]) => transcribeFirstAudioMock(...args), -})); - -const { buildTelegramMessageContextForTest } = - await import("./bot-message-context.test-harness.js"); - -async function buildGroupVoiceContext(params: { - messageId: number; - chatId: number; - title: string; - date: number; - fromId: number; - firstName: string; - fileId: string; - mediaPath: string; - groupDisableAudioPreflight?: boolean; - topicDisableAudioPreflight?: boolean; -}) { - const groupConfig = { - requireMention: true, - ...(params.groupDisableAudioPreflight === undefined - ? {} - : { disableAudioPreflight: params.groupDisableAudioPreflight }), - }; - const topicConfig = - params.topicDisableAudioPreflight === undefined - ? undefined - : { disableAudioPreflight: params.topicDisableAudioPreflight }; - - return buildTelegramMessageContextForTest({ - message: { - message_id: params.messageId, - chat: { id: params.chatId, type: "supergroup", title: params.title }, - date: params.date, - text: undefined, - from: { id: params.fromId, first_name: params.firstName }, - voice: { file_id: params.fileId }, - }, - allMedia: [{ path: params.mediaPath, contentType: "audio/ogg" }], - options: { forceWasMentioned: true }, - cfg: { - agents: { defaults: { model: DEFAULT_MODEL, workspace: DEFAULT_WORKSPACE } }, - channels: { telegram: {} }, - messages: { groupChat: { mentionPatterns: [DEFAULT_MENTION_PATTERN] } }, - }, - resolveGroupActivation: () => true, - resolveGroupRequireMention: () => true, - resolveTelegramGroupConfig: () => ({ - groupConfig, - topicConfig, - }), - }); -} - -function expectTranscriptRendered( - ctx: Awaited>, - transcript: string, -) { - expect(ctx).not.toBeNull(); - expect(ctx?.ctxPayload?.BodyForAgent).toBe(transcript); - expect(ctx?.ctxPayload?.Body).toContain(transcript); - expect(ctx?.ctxPayload?.Body).not.toContain(""); -} - -function expectAudioPlaceholderRendered(ctx: Awaited>) { - expect(ctx).not.toBeNull(); - expect(ctx?.ctxPayload?.Body).toContain(""); -} - -describe("buildTelegramMessageContext audio transcript body", () => { - beforeEach(() => { - transcribeFirstAudioMock.mockReset(); - }); - - it("uses preflight transcript as BodyForAgent for mention-gated group voice messages", async () => { - transcribeFirstAudioMock.mockResolvedValueOnce("hey bot please help"); - - const ctx = await buildGroupVoiceContext({ - messageId: 1, - chatId: -1001234567890, - title: "Test Group", - date: 1700000000, - fromId: 42, - firstName: "Alice", - fileId: "voice-1", - mediaPath: "/tmp/voice.ogg", - }); - - expect(transcribeFirstAudioMock).toHaveBeenCalledTimes(1); - expectTranscriptRendered(ctx, "hey bot please help"); - }); - - it("skips preflight transcription when disableAudioPreflight is true", async () => { - transcribeFirstAudioMock.mockClear(); - - const ctx = await buildGroupVoiceContext({ - messageId: 2, - chatId: -1001234567891, - title: "Test Group 2", - date: 1700000100, - fromId: 43, - firstName: "Bob", - fileId: "voice-2", - mediaPath: "/tmp/voice2.ogg", - groupDisableAudioPreflight: true, - }); - - expect(transcribeFirstAudioMock).not.toHaveBeenCalled(); - expectAudioPlaceholderRendered(ctx); - }); - - it("uses topic disableAudioPreflight=false to override group disableAudioPreflight=true", async () => { - transcribeFirstAudioMock.mockResolvedValueOnce("topic override transcript"); - - const ctx = await buildGroupVoiceContext({ - messageId: 3, - chatId: -1001234567892, - title: "Test Group 3", - date: 1700000200, - fromId: 44, - firstName: "Cara", - fileId: "voice-3", - mediaPath: "/tmp/voice3.ogg", - groupDisableAudioPreflight: true, - topicDisableAudioPreflight: false, - }); - - expect(transcribeFirstAudioMock).toHaveBeenCalledTimes(1); - expectTranscriptRendered(ctx, "topic override transcript"); - }); - - it("uses topic disableAudioPreflight=true to override group disableAudioPreflight=false", async () => { - transcribeFirstAudioMock.mockClear(); - - const ctx = await buildGroupVoiceContext({ - messageId: 4, - chatId: -1001234567893, - title: "Test Group 4", - date: 1700000300, - fromId: 45, - firstName: "Dan", - fileId: "voice-4", - mediaPath: "/tmp/voice4.ogg", - groupDisableAudioPreflight: false, - topicDisableAudioPreflight: true, - }); - - expect(transcribeFirstAudioMock).not.toHaveBeenCalled(); - expectAudioPlaceholderRendered(ctx); - }); -}); diff --git a/extensions/telegram/src/bot-message-context.implicit-mention.test.ts b/extensions/telegram/src/bot-message-context.implicit-mention.test.ts deleted file mode 100644 index 4ed40719be5..00000000000 --- a/extensions/telegram/src/bot-message-context.implicit-mention.test.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { buildTelegramMessageContextForTest } from "./bot-message-context.test-harness.js"; -import { TELEGRAM_FORUM_SERVICE_FIELDS } from "./forum-service-message.js"; - -describe("buildTelegramMessageContext implicitMention forum service messages", () => { - /** - * Build a group message context where the user sends a message inside a - * forum topic that has `reply_to_message` pointing to a message from the - * bot. Callers control whether the reply target looks like a forum service - * message (carries `forum_topic_created` etc.) or a real bot reply. - */ - async function buildGroupReplyCtx(params: { - replyToMessageText?: string; - replyToMessageCaption?: string; - replyFromIsBot?: boolean; - replyFromId?: number; - /** Extra fields on reply_to_message (e.g. forum_topic_created). */ - replyToMessageExtra?: Record; - }) { - const BOT_ID = 7; // matches test harness primaryCtx.me.id - return await buildTelegramMessageContextForTest({ - message: { - message_id: 100, - chat: { id: -1001234567890, type: "supergroup", title: "Forum Group" }, - date: 1700000000, - text: "hello everyone", - from: { id: 42, first_name: "Alice" }, - reply_to_message: { - message_id: 1, - text: params.replyToMessageText ?? undefined, - ...(params.replyToMessageCaption != null - ? { caption: params.replyToMessageCaption } - : {}), - from: { - id: params.replyFromId ?? BOT_ID, - first_name: "OpenClaw", - is_bot: params.replyFromIsBot ?? true, - }, - ...params.replyToMessageExtra, - }, - }, - resolveGroupActivation: () => true, - resolveGroupRequireMention: () => true, - resolveTelegramGroupConfig: () => ({ - groupConfig: { requireMention: true }, - topicConfig: undefined, - }), - }); - } - - it("does NOT trigger implicitMention for forum_topic_created service message", async () => { - // Bot auto-generated "Topic created" message carries forum_topic_created. - const ctx = await buildGroupReplyCtx({ - replyToMessageText: undefined, - replyFromIsBot: true, - replyToMessageExtra: { - forum_topic_created: { name: "New Topic", icon_color: 0x6fb9f0 }, - }, - }); - - // With requireMention and no explicit @mention, the message should be - // skipped (null) because implicitMention should NOT fire. - expect(ctx).toBeNull(); - }); - - it.each(TELEGRAM_FORUM_SERVICE_FIELDS)( - "does NOT trigger implicitMention for %s service message", - async (field) => { - const ctx = await buildGroupReplyCtx({ - replyToMessageText: undefined, - replyFromIsBot: true, - replyToMessageExtra: { [field]: {} }, - }); - - expect(ctx).toBeNull(); - }, - ); - - it("does NOT trigger implicitMention for forum_topic_closed service message", async () => { - const ctx = await buildGroupReplyCtx({ - replyToMessageText: undefined, - replyFromIsBot: true, - replyToMessageExtra: { forum_topic_closed: {} }, - }); - - expect(ctx).toBeNull(); - }); - - it("does NOT trigger implicitMention for general_forum_topic_hidden service message", async () => { - const ctx = await buildGroupReplyCtx({ - replyToMessageText: undefined, - replyFromIsBot: true, - replyToMessageExtra: { general_forum_topic_hidden: {} }, - }); - - expect(ctx).toBeNull(); - }); - - it("DOES trigger implicitMention for real bot replies (non-empty text)", async () => { - const ctx = await buildGroupReplyCtx({ - replyToMessageText: "Here is my answer", - replyFromIsBot: true, - }); - - // Real bot reply → implicitMention fires → message is NOT skipped. - expect(ctx).not.toBeNull(); - expect(ctx?.ctxPayload?.WasMentioned).toBe(true); - }); - - it("DOES trigger implicitMention for bot media messages with caption", async () => { - // Media messages from the bot have caption but no text — they should - // still count as real bot replies, not service messages. - const ctx = await buildGroupReplyCtx({ - replyToMessageText: undefined, - replyToMessageCaption: "Check out this image", - replyFromIsBot: true, - }); - - expect(ctx).not.toBeNull(); - expect(ctx?.ctxPayload?.WasMentioned).toBe(true); - }); - - it("DOES trigger implicitMention for bot sticker/voice (no text, no caption, no service field)", async () => { - // Stickers, voice notes, and captionless photos have neither text nor - // caption, but they are NOT service messages — they are legitimate bot - // replies that should trigger implicitMention. - const ctx = await buildGroupReplyCtx({ - replyToMessageText: undefined, - replyFromIsBot: true, - // No forum_topic_* fields → not a service message - }); - - expect(ctx).not.toBeNull(); - expect(ctx?.ctxPayload?.WasMentioned).toBe(true); - }); - - it("does NOT trigger implicitMention when reply is from a different user", async () => { - const ctx = await buildGroupReplyCtx({ - replyToMessageText: "some message", - replyFromIsBot: false, - replyFromId: 999, - }); - - // Different user's message → not an implicit mention → skipped. - expect(ctx).toBeNull(); - }); -}); diff --git a/extensions/telegram/src/bot-message-context.named-account-dm.test.ts b/extensions/telegram/src/bot-message-context.named-account-dm.test.ts deleted file mode 100644 index c36b60f2ea6..00000000000 --- a/extensions/telegram/src/bot-message-context.named-account-dm.test.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; -import { - getRecordedUpdateLastRoute, - loadTelegramMessageContextRouteHarness, - recordInboundSessionMock, -} from "./bot-message-context.route-test-support.js"; - -let buildTelegramMessageContextForTest: typeof import("./bot-message-context.test-harness.js").buildTelegramMessageContextForTest; -let clearRuntimeConfigSnapshot: typeof import("openclaw/plugin-sdk/config-runtime").clearRuntimeConfigSnapshot; -let setRuntimeConfigSnapshot: typeof import("openclaw/plugin-sdk/config-runtime").setRuntimeConfigSnapshot; - -describe("buildTelegramMessageContext named-account DM fallback", () => { - const baseCfg = { - agents: { defaults: { model: "anthropic/claude-opus-4-5", workspace: "/tmp/openclaw" } }, - channels: { telegram: {} }, - messages: { groupChat: { mentionPatterns: [] } }, - }; - - afterEach(() => { - clearRuntimeConfigSnapshot(); - }); - - beforeAll(async () => { - ({ clearRuntimeConfigSnapshot, setRuntimeConfigSnapshot, buildTelegramMessageContextForTest } = - await loadTelegramMessageContextRouteHarness()); - }); - - beforeEach(() => { - recordInboundSessionMock.mockClear(); - }); - - function getLastUpdateLastRoute(): { sessionKey?: string } | undefined { - return getRecordedUpdateLastRoute() as { sessionKey?: string } | undefined; - } - - function buildNamedAccountDmMessage(messageId = 1) { - return { - message_id: messageId, - chat: { id: 814912386, type: "private" as const }, - date: 1700000000 + messageId - 1, - text: "hello", - from: { id: 814912386, first_name: "Alice" }, - }; - } - - async function buildNamedAccountDmContext(accountId = "atlas", messageId = 1) { - setRuntimeConfigSnapshot(baseCfg); - return await buildTelegramMessageContextForTest({ - cfg: baseCfg, - accountId, - message: buildNamedAccountDmMessage(messageId), - }); - } - - it("allows DM through for a named account with no explicit binding", async () => { - setRuntimeConfigSnapshot(baseCfg); - - const ctx = await buildTelegramMessageContextForTest({ - cfg: baseCfg, - accountId: "atlas", - message: { - message_id: 1, - chat: { id: 814912386, type: "private" }, - date: 1700000000, - text: "hello", - from: { id: 814912386, first_name: "Alice" }, - }, - }); - - expect(ctx).not.toBeNull(); - expect(ctx?.route.matchedBy).toBe("default"); - expect(ctx?.route.accountId).toBe("atlas"); - }); - - it("uses a per-account session key for named-account DMs", async () => { - const ctx = await buildNamedAccountDmContext(); - - expect(ctx?.ctxPayload?.SessionKey).toBe("agent:main:telegram:atlas:direct:814912386"); - }); - - it("keeps named-account fallback lastRoute on the isolated DM session", async () => { - const ctx = await buildNamedAccountDmContext(); - - expect(ctx?.ctxPayload?.SessionKey).toBe("agent:main:telegram:atlas:direct:814912386"); - expect(getLastUpdateLastRoute()?.sessionKey).toBe("agent:main:telegram:atlas:direct:814912386"); - }); - - it("isolates sessions between named accounts that share the default agent", async () => { - const atlas = await buildNamedAccountDmContext("atlas", 1); - const skynet = await buildNamedAccountDmContext("skynet", 2); - - expect(atlas?.ctxPayload?.SessionKey).toBe("agent:main:telegram:atlas:direct:814912386"); - expect(skynet?.ctxPayload?.SessionKey).toBe("agent:main:telegram:skynet:direct:814912386"); - expect(atlas?.ctxPayload?.SessionKey).not.toBe(skynet?.ctxPayload?.SessionKey); - }); - - it("keeps identity-linked peer canonicalization in the named-account fallback path", async () => { - const cfg = { - ...baseCfg, - session: { - identityLinks: { - "alice-shared": ["telegram:814912386"], - }, - }, - }; - setRuntimeConfigSnapshot(cfg); - - const ctx = await buildTelegramMessageContextForTest({ - cfg, - accountId: "atlas", - message: { - message_id: 1, - chat: { id: 999999999, type: "private" }, - date: 1700000000, - text: "hello", - from: { id: 814912386, first_name: "Alice" }, - }, - }); - - expect(ctx?.ctxPayload?.SessionKey).toBe("agent:main:telegram:atlas:direct:alice-shared"); - }); - - it("still drops named-account group messages without an explicit binding", async () => { - setRuntimeConfigSnapshot(baseCfg); - - const ctx = await buildTelegramMessageContextForTest({ - cfg: baseCfg, - accountId: "atlas", - options: { forceWasMentioned: true }, - resolveGroupActivation: () => true, - message: { - message_id: 1, - chat: { id: -1001234567890, type: "supergroup", title: "Test Group" }, - date: 1700000000, - text: "@bot hello", - from: { id: 814912386, first_name: "Alice" }, - }, - }); - - expect(ctx).toBeNull(); - }); - - it("uses the main session key for default-account DMs", async () => { - setRuntimeConfigSnapshot(baseCfg); - - const ctx = await buildTelegramMessageContextForTest({ - cfg: baseCfg, - message: { - message_id: 1, - chat: { id: 42, type: "private" }, - date: 1700000000, - text: "hello", - from: { id: 42, first_name: "Alice" }, - }, - }); - - expect(ctx?.ctxPayload?.SessionKey).toBe("agent:main:main"); - expect(getLastUpdateLastRoute()?.sessionKey).toBe("agent:main:main"); - }); -}); diff --git a/extensions/telegram/src/bot-message-context.sender-prefix.test.ts b/extensions/telegram/src/bot-message-context.sender-prefix.test.ts deleted file mode 100644 index 104eb64d5d9..00000000000 --- a/extensions/telegram/src/bot-message-context.sender-prefix.test.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { buildTelegramMessageContextForTest } from "./bot-message-context.test-harness.js"; -import { - isTelegramForumServiceMessage, - TELEGRAM_FORUM_SERVICE_FIELDS, -} from "./forum-service-message.js"; - -describe("isTelegramForumServiceMessage", () => { - it("returns true for any Telegram forum service field", () => { - for (const field of TELEGRAM_FORUM_SERVICE_FIELDS) { - expect(isTelegramForumServiceMessage({ [field]: {} })).toBe(true); - } - }); - - it("returns false for normal messages and non-objects", () => { - expect(isTelegramForumServiceMessage({ text: "hello" })).toBe(false); - expect(isTelegramForumServiceMessage(null)).toBe(false); - expect(isTelegramForumServiceMessage("topic created")).toBe(false); - }); -}); - -describe("buildTelegramMessageContext sender prefix", () => { - async function buildCtx(params: { messageId: number; options?: Record }) { - return await buildTelegramMessageContextForTest({ - message: { - message_id: params.messageId, - chat: { id: -99, type: "supergroup", title: "Dev Chat" }, - date: 1700000000, - text: "hello", - from: { id: 42, first_name: "Alice" }, - }, - options: params.options, - }); - } - - it("prefixes group bodies with sender label", async () => { - const ctx = await buildCtx({ messageId: 1 }); - - expect(ctx).not.toBeNull(); - const body = ctx?.ctxPayload?.Body ?? ""; - expect(body).toContain("Alice (42): hello"); - }); - - it("sets MessageSid from message_id", async () => { - const ctx = await buildCtx({ messageId: 12345 }); - - expect(ctx).not.toBeNull(); - expect(ctx?.ctxPayload?.MessageSid).toBe("12345"); - }); - - it("respects messageIdOverride option", async () => { - const ctx = await buildCtx({ - messageId: 12345, - options: { messageIdOverride: "67890" }, - }); - - expect(ctx).not.toBeNull(); - expect(ctx?.ctxPayload?.MessageSid).toBe("67890"); - }); -}); diff --git a/extensions/telegram/src/bot-message-context.session-recreate.test.ts b/extensions/telegram/src/bot-message-context.session-recreate.test.ts deleted file mode 100644 index 85880dfbab5..00000000000 --- a/extensions/telegram/src/bot-message-context.session-recreate.test.ts +++ /dev/null @@ -1,99 +0,0 @@ -import fs from "node:fs/promises"; -import path from "node:path"; -import { - clearRuntimeConfigSnapshot, - setRuntimeConfigSnapshot, -} from "openclaw/plugin-sdk/config-runtime"; -import { - clearSessionStoreCacheForTest, - loadSessionStore, - updateSessionStore, -} from "openclaw/plugin-sdk/config-runtime"; -import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest"; -import { createSuiteTempRootTracker } from "../../../src/test-helpers/temp-dir.js"; -import { buildTelegramMessageContextForTest } from "./bot-message-context.test-harness.js"; - -const TELEGRAM_DIRECT_KEY = "agent:main:telegram:direct:7463849194"; - -describe("Telegram direct session recreation after delete", () => { - const suiteRootTracker = createSuiteTempRootTracker({ - prefix: "openclaw-telegram-context-recreate-", - }); - - beforeAll(async () => { - await suiteRootTracker.setup(); - }); - - afterEach(() => { - clearRuntimeConfigSnapshot(); - clearSessionStoreCacheForTest(); - }); - - afterAll(async () => { - await suiteRootTracker.cleanup(); - }); - - it("records a deleted direct session again when the next DM is processed", async () => { - const tempDir = await suiteRootTracker.make("direct"); - const storePath = path.join(tempDir, "sessions.json"); - const cfg = { - agents: { - defaults: { - model: "openai/gpt-5.4", - workspace: "/tmp/openclaw", - }, - }, - channels: { telegram: {} }, - messages: { groupChat: { mentionPatterns: [] } }, - session: { - dmScope: "per-channel-peer" as const, - store: storePath, - }, - }; - setRuntimeConfigSnapshot(cfg as never); - await fs.writeFile( - storePath, - JSON.stringify( - { - [TELEGRAM_DIRECT_KEY]: { - sessionId: "old-session", - updatedAt: 1_700_000_000_000, - chatType: "direct", - channel: "telegram", - }, - }, - null, - 2, - ), - "utf-8", - ); - await updateSessionStore(storePath, (store) => { - delete store[TELEGRAM_DIRECT_KEY]; - }); - - const context = await buildTelegramMessageContextForTest({ - cfg, - message: { - message_id: 2, - chat: { id: 7463849194, type: "private" }, - date: 1_700_000_001, - text: "hello again", - from: { id: 7463849194, first_name: "Alice" }, - }, - sessionRuntime: null, - }); - - const store = loadSessionStore(storePath, { skipCache: true }); - expect(context?.ctxPayload?.SessionKey).toBe(TELEGRAM_DIRECT_KEY); - expect(store[TELEGRAM_DIRECT_KEY]).toEqual( - expect.objectContaining({ - lastChannel: "telegram", - lastTo: "telegram:7463849194", - origin: expect.objectContaining({ - provider: "telegram", - chatType: "direct", - }), - }), - ); - }); -}); diff --git a/extensions/telegram/src/bot-message-context.silent-ingest.test.ts b/extensions/telegram/src/bot-message-context.silent-ingest.test.ts deleted file mode 100644 index f82ceb6d384..00000000000 --- a/extensions/telegram/src/bot-message-context.silent-ingest.test.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { describe, expect, it, vi } from "vitest"; -import { buildTelegramMessageContextForTest } from "./bot-message-context.test-harness.js"; - -const internalHookMocks = vi.hoisted(() => ({ - createInternalHookEvent: vi.fn( - (type: string, action: string, sessionKey: string, context: Record) => ({ - type, - action, - sessionKey, - context, - timestamp: new Date(), - messages: [], - }), - ), - triggerInternalHook: vi.fn(async () => undefined), -})); - -vi.mock("openclaw/plugin-sdk/hook-runtime", () => { - return { - createInternalHookEvent: internalHookMocks.createInternalHookEvent, - fireAndForgetHook: (task: Promise) => void task, - toInternalMessageReceivedContext: (context: Record) => ({ - ...context, - metadata: { to: context.to }, - }), - triggerInternalHook: internalHookMocks.triggerInternalHook, - }; -}); - -function makeGroupMessage(text: string) { - return { - message_id: 42, - chat: { id: -1001234567890, type: "supergroup" as const, title: "Test Group" }, - date: 1_700_000_000, - text, - from: { id: 99, first_name: "Alice", username: "alice" }, - }; -} - -describe("telegram mention-skip silent ingest", () => { - it("emits internal message:received when ingest is enabled", async () => { - internalHookMocks.createInternalHookEvent.mockClear(); - internalHookMocks.triggerInternalHook.mockClear(); - - const result = await buildTelegramMessageContextForTest({ - message: makeGroupMessage("hello without mention"), - cfg: { - agents: { - defaults: { - model: "anthropic/sonnet-4.6", - workspace: "/tmp/openclaw", - }, - }, - channels: { - telegram: { - groups: { - "*": { - requireMention: true, - ingest: true, - }, - }, - }, - }, - messages: { - groupChat: { - mentionPatterns: ["@bot"], - }, - }, - } as never, - resolveGroupRequireMention: () => true, - resolveTelegramGroupConfig: () => ({ - groupConfig: { - requireMention: true, - ingest: true, - }, - topicConfig: undefined, - }), - }); - - expect(result).toBeNull(); - expect(internalHookMocks.createInternalHookEvent).toHaveBeenCalledWith( - "message", - "received", - expect.stringContaining("telegram"), - expect.objectContaining({ - channelId: "telegram", - content: "hello without mention", - }), - ); - expect(internalHookMocks.triggerInternalHook).toHaveBeenCalledTimes(1); - }); - - it("uses wildcard ingest when a specific group override omits ingest", async () => { - internalHookMocks.createInternalHookEvent.mockClear(); - internalHookMocks.triggerInternalHook.mockClear(); - - const result = await buildTelegramMessageContextForTest({ - message: makeGroupMessage("hello without mention"), - cfg: { - agents: { - defaults: { - model: "anthropic/sonnet-4.6", - workspace: "/tmp/openclaw", - }, - }, - channels: { - telegram: { - groups: { - "*": { - requireMention: true, - ingest: true, - }, - "-1001234567890": { - requireMention: true, - }, - }, - }, - }, - messages: { - groupChat: { - mentionPatterns: ["@bot"], - }, - }, - } as never, - resolveGroupRequireMention: () => true, - resolveTelegramGroupConfig: () => ({ - groupConfig: { - requireMention: true, - }, - topicConfig: undefined, - }), - }); - - expect(result).toBeNull(); - expect(internalHookMocks.createInternalHookEvent).toHaveBeenCalledWith( - "message", - "received", - expect.stringContaining("telegram"), - expect.objectContaining({ - channelId: "telegram", - content: "hello without mention", - }), - ); - expect(internalHookMocks.triggerInternalHook).toHaveBeenCalledTimes(1); - }); -});