fix(telegram): guard DM bindings from being parsed as topics · openclaw/openclaw@1355701
TSHOGX
·
2026-05-09
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -351,6 +351,7 @@ Docs: https://docs.openclaw.ai
|
351 | 351 | - Agents/failover: rotate auth profiles before deferred cooldown marking on rate-limit failures, so file-lock contention cannot stall profile failover. Fixes #57281. (#57283) Thanks @jeremyknows. |
352 | 352 | - Gateway/sessions: when `session.dmScope: "main"` is configured, route a bare webchat `/new` against the agent's main session (`sessions.create` with `emitCommandHooks=true`) to an in-place reset instead of creating a parallel `dashboard:` child, matching `/new` behavior on Telegram/Discord. Fixes #77434. (#71170) Thanks @statxc. |
353 | 353 | - Scripts/UI/Windows: launch `.cmd` and `.bat` UI runners through the shared cmd.exe escaping path with shell mode disabled, avoiding Node.js v24 DEP0190 warnings while preserving argument boundaries. (#62910) Thanks @nandanadileep. |
| 354 | +- Telegram: treat a DM binding that carries the chat id in both `conversationId` and `parentConversationId` as a direct conversation instead of a topic, so reverse delivery for Telegram DMs is not misrouted through a topic-shaped target. Thanks @TSHOGX. |
354 | 355 | |
355 | 356 | ## 2026.5.7 |
356 | 357 | |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { describe, expect, it } from "vitest"; |
| 2 | +import { parseTelegramTopicConversation } from "./topic-conversation.js"; |
| 3 | + |
| 4 | +describe("parseTelegramTopicConversation", () => { |
| 5 | +it("parses direct chatId:topic:topicId strings", () => { |
| 6 | +expect( |
| 7 | +parseTelegramTopicConversation({ |
| 8 | +conversationId: "-1001234567890:topic:42", |
| 9 | +}), |
| 10 | +).toEqual({ |
| 11 | +chatId: "-1001234567890", |
| 12 | +topicId: "42", |
| 13 | +canonicalConversationId: "-1001234567890:topic:42", |
| 14 | +}); |
| 15 | +}); |
| 16 | + |
| 17 | +it("parses a bare topic id against a group parentConversationId", () => { |
| 18 | +expect( |
| 19 | +parseTelegramTopicConversation({ |
| 20 | +conversationId: "42", |
| 21 | +parentConversationId: "-1001234567890", |
| 22 | +}), |
| 23 | +).toEqual({ |
| 24 | +chatId: "-1001234567890", |
| 25 | +topicId: "42", |
| 26 | +canonicalConversationId: "-1001234567890:topic:42", |
| 27 | +}); |
| 28 | +}); |
| 29 | + |
| 30 | +it("returns null when a DM binding carries the chat id in both fields", () => { |
| 31 | +expect( |
| 32 | +parseTelegramTopicConversation({ |
| 33 | +conversationId: "1234", |
| 34 | +parentConversationId: "1234", |
| 35 | +}), |
| 36 | +).toBeNull(); |
| 37 | +}); |
| 38 | + |
| 39 | +it("returns null when neither shape matches", () => { |
| 40 | +expect( |
| 41 | +parseTelegramTopicConversation({ |
| 42 | +conversationId: "not-a-topic", |
| 43 | +}), |
| 44 | +).toBeNull(); |
| 45 | +}); |
| 46 | + |
| 47 | +it("returns null for a bare topic id without a parentConversationId", () => { |
| 48 | +expect( |
| 49 | +parseTelegramTopicConversation({ |
| 50 | +conversationId: "42", |
| 51 | +}), |
| 52 | +).toBeNull(); |
| 53 | +}); |
| 54 | +}); |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -43,6 +43,11 @@ export function parseTelegramTopicConversation(params: {
|
43 | 43 | if (!parent || !/^-?\d+$/.test(parent)) { |
44 | 44 | return null; |
45 | 45 | } |
| 46 | +// Telegram DM bindings can carry the chat id in both fields; treat that as |
| 47 | +// a direct conversation shape, not a legacy topic binding. |
| 48 | +if (parent === conversation) { |
| 49 | +return null; |
| 50 | +} |
46 | 51 | const canonicalConversationId = buildTelegramTopicConversationId({ |
47 | 52 | chatId: parent, |
48 | 53 | topicId: conversation, |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。