Files
openclaw/src/auto-reply/reply/group-id.test.ts
Gabriel M. f7ced438f7 fix: restore Telegram forum-topic routing (#56060) (thanks @one27001)
* feat(telegram): add child thread-binding placement via createForumTopic

Enable ACP subagent spawn on Telegram by adding "child" placement
support to the thread-bindings adapter. When a child binding is
requested, the adapter creates a new forum topic via the Telegram
Bot API and binds the subagent session to it using the canonical
chatId:topic:topicId conversation ID format.

When the ACP spawn context provides only a topic ID (not a full
group chat ID), the adapter resolves the group from the configured
Telegram groups in openclaw.json.

This mirrors the Discord adapter's child placement behavior
(thread creation + session binding) and unblocks the orchestrator
pattern on Telegram forum-enabled groups.

Closes #5737
Ref #23414

* fix(telegram): return null with warning instead of silent group fallback for bare topic IDs in child bind

* telegram: fix ACP child thread spawn with group chat ID from agentGroupId

* telegram: scope agentGroupId substitution to telegram channel only

* Telegram: fix forum topic replies routing to root chat instead of topic thread

* fix: clean up dead guard in child bind + add explicit threadId override test

- Simplify bare-topic-ID guards in thread-bindings.ts: split into
  separate !chatId and !chatId.startsWith("-") checks, removing
  unreachable second condition
- Add regression test confirming explicit turnSourceThreadId overrides
  session lastThreadId on same channel

* fix: guard threadId fallback against shared-session race

Codex review P1: when turnSourceTo differs from the session's stored
to, the session threadId may belong to a different chat/topic. Only
fall back to context.threadId when the destination also matches.

* fix(telegram): enable ACP spawn from forum topics without thread binding

extractExplicitGroupId returned topic-qualified IDs (-100...:topic:1264)
instead of bare group chat IDs, breaking agentGroupId resolution.
agentGroupId was also never wired in the inline actions path.

For Telegram forum topics, skip thread binding entirely — the delivery
plan already routes correctly via requester origin (to + threadId).
Creating new forum topics per child session is unnecessary; output goes
back to the same topic the user asked from.

* fix(acp): bind Telegram forum sessions to current topic

* fix: restore Telegram forum-topic routing (#56060) (thanks @one27001)

---------

Co-authored-by: openclaw <mgabrie.dev@gmail.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-03-31 10:18:09 +05:30

49 lines
1.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { extractExplicitGroupId } from "./group-id.js";
describe("extractExplicitGroupId", () => {
it("returns undefined for empty/null input", () => {
expect(extractExplicitGroupId(undefined)).toBeUndefined();
expect(extractExplicitGroupId(null)).toBeUndefined();
expect(extractExplicitGroupId("")).toBeUndefined();
expect(extractExplicitGroupId(" ")).toBeUndefined();
});
it("extracts group ID from telegram group format", () => {
expect(extractExplicitGroupId("telegram:group:-1003776849159")).toBe("-1003776849159");
});
it("extracts group ID from telegram forum topic format, stripping topic suffix", () => {
expect(extractExplicitGroupId("telegram:group:-1003776849159:topic:1264")).toBe(
"-1003776849159",
);
});
it("extracts group ID from channel format", () => {
expect(extractExplicitGroupId("telegram:channel:-1001234567890")).toBe("-1001234567890");
});
it("extracts group ID from channel format with topic", () => {
expect(extractExplicitGroupId("telegram:channel:-1001234567890:topic:42")).toBe(
"-1001234567890",
);
});
it("extracts group ID from bare group: prefix", () => {
expect(extractExplicitGroupId("group:-1003776849159")).toBe("-1003776849159");
});
it("extracts group ID from bare group: prefix with topic", () => {
expect(extractExplicitGroupId("group:-1003776849159:topic:999")).toBe("-1003776849159");
});
it("extracts WhatsApp group ID", () => {
expect(extractExplicitGroupId("whatsapp:120363123456789@g.us")).toBe("120363123456789@g.us");
});
it("returns undefined for unrecognized formats", () => {
expect(extractExplicitGroupId("user:12345")).toBeUndefined();
expect(extractExplicitGroupId("just-a-string")).toBeUndefined();
});
});