From d8fae6c4d76040b707c3fe377eabe097a363c1e2 Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Wed, 11 Mar 2026 17:46:06 +0100 Subject: [PATCH] telegram: tighten topic alias validation and pass cfg --- extensions/telegram/src/channel-actions.ts | 29 ++++++++++-- extensions/telegram/src/send.ts | 1 + src/agents/tools/telegram-actions.test.ts | 2 +- src/agents/tools/telegram-actions.ts | 2 + src/channels/plugins/actions/actions.test.ts | 48 +++++++++++++++++++- 5 files changed, 76 insertions(+), 6 deletions(-) diff --git a/extensions/telegram/src/channel-actions.ts b/extensions/telegram/src/channel-actions.ts index 460a34f4dbe..003b7113a78 100644 --- a/extensions/telegram/src/channel-actions.ts +++ b/extensions/telegram/src/channel-actions.ts @@ -80,10 +80,31 @@ function readTelegramMessageIdParam( } function readTelegramTopicIdParam(params: Record): number | undefined { - return ( - readNumberParam(params, "topicId", { integer: true, strict: true }) ?? - readNumberParam(params, "threadId", { integer: true, strict: true }) - ); + const hasTopicIdParam = Object.hasOwn(params, "topicId") || Object.hasOwn(params, "topic_id"); + const topicId = readNumberParam(params, "topicId", { + integer: true, + strict: true, + strictInteger: true, + }); + if (hasTopicIdParam && typeof topicId !== "number") { + throw new Error("topicId must be a valid integer when provided."); + } + if (typeof topicId === "number") { + return topicId; + } + + const hasThreadIdParam = + Object.hasOwn(params, "threadId") || Object.hasOwn(params, "thread_id"); + const threadId = readNumberParam(params, "threadId", { + integer: true, + strict: true, + strictInteger: true, + }); + if (hasThreadIdParam && typeof threadId !== "number") { + throw new Error("threadId must be a valid integer when provided."); + } + + return threadId; } export const telegramMessageActions: ChannelMessageActionAdapter = { diff --git a/extensions/telegram/src/send.ts b/extensions/telegram/src/send.ts index 1914f29905c..e6c09c106b6 100644 --- a/extensions/telegram/src/send.ts +++ b/extensions/telegram/src/send.ts @@ -1443,6 +1443,7 @@ export async function sendPollTelegram( // --------------------------------------------------------------------------- type TelegramDeleteForumTopicOpts = { + cfg?: ReturnType; token?: string; accountId?: string; verbose?: boolean; diff --git a/src/agents/tools/telegram-actions.test.ts b/src/agents/tools/telegram-actions.test.ts index c8c961ffcc8..409b9a50f5f 100644 --- a/src/agents/tools/telegram-actions.test.ts +++ b/src/agents/tools/telegram-actions.test.ts @@ -629,7 +629,7 @@ describe("handleTelegramAction", () => { expect(deleteForumTopicTelegram).toHaveBeenCalledWith( "-100123", 271, - expect.objectContaining({ token: "tok" }), + expect.objectContaining({ cfg, token: "tok" }), ); }); diff --git a/src/agents/tools/telegram-actions.ts b/src/agents/tools/telegram-actions.ts index 3294ce1d917..b0a9abf4c95 100644 --- a/src/agents/tools/telegram-actions.ts +++ b/src/agents/tools/telegram-actions.ts @@ -359,6 +359,7 @@ export async function handleTelegramAction( required: true, integer: true, strict: true, + strictInteger: true, }); const token = resolveTelegramToken(cfg, { accountId }).token; if (!token) { @@ -367,6 +368,7 @@ export async function handleTelegramAction( ); } await deleteForumTopicTelegram(chatId ?? "", topicId ?? 0, { + cfg, token, accountId: accountId ?? undefined, }); diff --git a/src/channels/plugins/actions/actions.test.ts b/src/channels/plugins/actions/actions.test.ts index e8fa82b3fdd..b0a0c0123d9 100644 --- a/src/channels/plugins/actions/actions.test.ts +++ b/src/channels/plugins/actions/actions.test.ts @@ -953,7 +953,53 @@ describe("telegramMessageActions", () => { }, cfg, }), - ).rejects.toThrow(/threadId\/topicId is required for action=topic-delete/i); + ).rejects.toThrow(/topicId must be a valid integer when provided/i); + + expect(handleTelegramAction).not.toHaveBeenCalled(); + }); + + it("rejects malformed topicId even when threadId alias is valid", async () => { + const cfg = telegramCfg(); + const handleAction = telegramMessageActions.handleAction; + if (!handleAction) { + throw new Error("telegram handleAction unavailable"); + } + + await expect( + handleAction({ + channel: "telegram", + action: "topic-delete", + params: { + to: "-1001234567890", + topicId: "oops", + threadId: 271, + }, + cfg, + }), + ).rejects.toThrow(/topicId must be a valid integer when provided/i); + + expect(handleTelegramAction).not.toHaveBeenCalled(); + }); + + it("rejects malformed delete topicId even when threadId alias is valid", async () => { + const cfg = telegramCfg(); + const handleAction = telegramMessageActions.handleAction; + if (!handleAction) { + throw new Error("telegram handleAction unavailable"); + } + + await expect( + handleAction({ + channel: "telegram", + action: "delete", + params: { + to: "-1001234567890", + topicId: "oops", + threadId: 271, + }, + cfg, + }), + ).rejects.toThrow(/topicId must be a valid integer when provided/i); expect(handleTelegramAction).not.toHaveBeenCalled(); });