From 95fec668a0c305705ea362e927f3c53ae186dcd7 Mon Sep 17 00:00:00 2001 From: Penchan <5032148+p3nchan@users.noreply.github.com> Date: Mon, 23 Mar 2026 17:24:39 +0800 Subject: [PATCH] fix: preserve Telegram reply context text (#50500) (thanks @p3nchan) * fix: guard Telegram reply context text (#50500) (thanks @p3nchan) * fix: preserve Telegram reply caption fallback (#50500) (thanks @p3nchan) --------- Co-authored-by: Ayaan Zaidi --- CHANGELOG.md | 1 + extensions/telegram/src/bot/helpers.test.ts | 21 ++++++++++++++++++++- extensions/telegram/src/bot/helpers.ts | 9 +++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c868ccc18c0..7184948cdb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,6 +138,7 @@ Docs: https://docs.openclaw.ai - Android/camera: recycle intermediate and final snap bitmaps in `camera.snap` so repeated captures do not leak native image memory. (#41902) Thanks @Kaneki-x. - Control UI/logging: make browser-safe logger imports avoid eager temp-dir resolution so the bundled Control UI no longer crashes to a blank screen when logging reaches `tmp-openclaw-dir`. (#48469) Fixes #48062. Thanks @7inspire. - Control UI/chat sessions: show human-readable labels in the grouped session dropdown again, keep unique scoped fallbacks when metadata is missing, and disambiguate duplicate labels only when needed. (#45130) Thanks @luzhidong. +- Telegram/replies: ignore malformed non-string reply text and caption fields when describing reply context, so unexpected Telegram reply payloads no longer break inbound context assembly. (#50500) Thanks @p3nchan. - Control UI/dashboard: preserve structured gateway shutdown reasons across restart disconnects so config-triggered restarts no longer fall back to `disconnected (1006): no reason`. (#46580) Fixes #46532. Thanks @vincentkoc. - Android/chat: theme the thinking dropdown and TLS trust dialogs explicitly so popup surfaces match the active app theme instead of falling back to mismatched Material defaults. - Node/startup: remove leftover debug `console.log("node host PATH: ...")` that printed the resolved PATH on every `openclaw node run` invocation. (#46515) Fixes #46411. Thanks @ademczuk. diff --git a/extensions/telegram/src/bot/helpers.test.ts b/extensions/telegram/src/bot/helpers.test.ts index 924c0f369d8..be449f0c532 100644 --- a/extensions/telegram/src/bot/helpers.test.ts +++ b/extensions/telegram/src/bot/helpers.test.ts @@ -263,10 +263,29 @@ describe("describeReplyTarget", () => { }, // oxlint-disable-next-line typescript/no-explicit-any } as any); - // Should not produce "[object Object]" — should return null (no valid body) + // Should not throw when reply text is malformed; return null instead. expect(result).toBeNull(); }); + it("falls back to caption when reply text is malformed", () => { + const result = describeReplyTarget({ + message_id: 2, + date: 1000, + chat: { id: 1, type: "private" }, + reply_to_message: { + message_id: 1, + date: 900, + chat: { id: 1, type: "private" }, + text: { some: "object" }, + caption: "Caption body", + from: { id: 42, first_name: "Alice", is_bot: false }, + }, + // oxlint-disable-next-line typescript/no-explicit-any + } as any); + expect(result?.body).toBe("Caption body"); + expect(result?.kind).toBe("reply"); + }); + it("extracts forwarded context from reply_to_message (issue #9619)", () => { // When user forwards a message with a comment, the comment message has // reply_to_message pointing to the forwarded message. We should extract diff --git a/extensions/telegram/src/bot/helpers.ts b/extensions/telegram/src/bot/helpers.ts index ce1282eb794..f53b426e021 100644 --- a/extensions/telegram/src/bot/helpers.ts +++ b/extensions/telegram/src/bot/helpers.ts @@ -406,8 +406,13 @@ export function describeReplyTarget(msg: Message): TelegramReplyTarget | null { const replyLike = reply ?? externalReply; if (!body && replyLike) { - const rawText = replyLike.text ?? replyLike.caption ?? ""; - const replyBody = (typeof rawText === "string" ? rawText : "").trim(); + const replyBody = ( + typeof replyLike.text === "string" + ? replyLike.text + : typeof replyLike.caption === "string" + ? replyLike.caption + : "" + ).trim(); body = replyBody; if (!body) { body = resolveTelegramMediaPlaceholder(replyLike) ?? "";