From 55f6d2d1adfd2a20037009d62d9509ba1a8854d1 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Mon, 16 Mar 2026 17:24:37 +0530 Subject: [PATCH] fix(channels): parse bundled targets without plugin registry --- src/channels/plugins/target-parsing.test.ts | 59 +++++++++++++++++++++ src/channels/plugins/target-parsing.ts | 23 +++++++- 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/channels/plugins/target-parsing.test.ts diff --git a/src/channels/plugins/target-parsing.test.ts b/src/channels/plugins/target-parsing.test.ts new file mode 100644 index 00000000000..a1c5d278fde --- /dev/null +++ b/src/channels/plugins/target-parsing.test.ts @@ -0,0 +1,59 @@ +import { beforeEach, describe, expect, it } from "vitest"; +import { setActivePluginRegistry } from "../../plugins/runtime.js"; +import { createTestRegistry } from "../../test-utils/channel-plugins.js"; +import { parseExplicitTargetForChannel } from "./target-parsing.js"; + +describe("parseExplicitTargetForChannel", () => { + beforeEach(() => { + setActivePluginRegistry(createTestRegistry([])); + }); + + it("parses bundled Telegram targets without an active Telegram registry entry", () => { + expect(parseExplicitTargetForChannel("telegram", "telegram:group:-100123:topic:77")).toEqual({ + to: "-100123", + threadId: 77, + chatType: "group", + }); + expect(parseExplicitTargetForChannel("telegram", "-100123")).toEqual({ + to: "-100123", + chatType: "group", + }); + }); + + it("parses registered non-bundled channel targets via the active plugin contract", () => { + setActivePluginRegistry( + createTestRegistry([ + { + pluginId: "msteams", + source: "test", + plugin: { + id: "msteams", + meta: { + id: "msteams", + label: "Microsoft Teams", + selectionLabel: "Microsoft Teams", + docsPath: "/channels/msteams", + blurb: "test stub", + }, + capabilities: { chatTypes: ["direct"] }, + config: { + listAccountIds: () => [], + resolveAccount: () => ({}), + }, + messaging: { + parseExplicitTarget: ({ raw }: { raw: string }) => ({ + to: raw.trim().toUpperCase(), + chatType: "direct" as const, + }), + }, + }, + }, + ]), + ); + + expect(parseExplicitTargetForChannel("msteams", "team-room")).toEqual({ + to: "TEAM-ROOM", + chatType: "direct", + }); + }); +}); diff --git a/src/channels/plugins/target-parsing.ts b/src/channels/plugins/target-parsing.ts index 5d7fd6e28da..beea68adca3 100644 --- a/src/channels/plugins/target-parsing.ts +++ b/src/channels/plugins/target-parsing.ts @@ -1,4 +1,7 @@ +import { parseDiscordTarget } from "../../../extensions/discord/src/targets.js"; +import { parseTelegramTarget } from "../../../extensions/telegram/src/targets.js"; import type { ChatType } from "../chat-type.js"; +import { normalizeChatChannelId } from "../registry.js"; import { getChannelPlugin, normalizeChannelId } from "./registry.js"; export type ParsedChannelExplicitTarget = { @@ -11,10 +14,28 @@ function parseWithPlugin( rawChannel: string, rawTarget: string, ): ParsedChannelExplicitTarget | null { - const channel = normalizeChannelId(rawChannel); + const channel = normalizeChatChannelId(rawChannel) ?? normalizeChannelId(rawChannel); if (!channel) { return null; } + if (channel === "telegram") { + const target = parseTelegramTarget(rawTarget); + return { + to: target.chatId, + ...(target.messageThreadId != null ? { threadId: target.messageThreadId } : {}), + ...(target.chatType === "unknown" ? {} : { chatType: target.chatType }), + }; + } + if (channel === "discord") { + const target = parseDiscordTarget(rawTarget, { defaultKind: "channel" }); + if (!target) { + return null; + } + return { + to: target.id, + chatType: target.kind === "user" ? "direct" : "channel", + }; + } return getChannelPlugin(channel)?.messaging?.parseExplicitTarget?.({ raw: rawTarget }) ?? null; }