refactor(channels): dedupe message routing and telegram helpers

This commit is contained in:
Peter Steinberger
2026-02-22 07:37:54 +00:00
parent b109fa53ea
commit 75c1bfbae8
21 changed files with 566 additions and 410 deletions

View File

@@ -36,6 +36,24 @@ vi.mock("../../../discord/monitor/thread-bindings.js", async (importOriginal) =>
const { discordOutbound } = await import("./discord.js");
function mockBoundThreadManager() {
hoisted.getThreadBindingManagerMock.mockReturnValue({
getByThreadId: () => ({
accountId: "default",
channelId: "parent-1",
threadId: "thread-1",
targetKind: "subagent",
targetSessionKey: "agent:main:subagent:child",
agentId: "main",
label: "codex-thread",
webhookId: "wh-1",
webhookToken: "tok-1",
boundBy: "system",
boundAt: Date.now(),
}),
});
}
describe("normalizeDiscordOutboundTarget", () => {
it("normalizes bare numeric IDs to channel: prefix", () => {
expect(normalizeDiscordOutboundTarget("1470130713209602050")).toEqual({
@@ -110,21 +128,7 @@ describe("discordOutbound", () => {
});
it("uses webhook persona delivery for bound thread text replies", async () => {
hoisted.getThreadBindingManagerMock.mockReturnValue({
getByThreadId: () => ({
accountId: "default",
channelId: "parent-1",
threadId: "thread-1",
targetKind: "subagent",
targetSessionKey: "agent:main:subagent:child",
agentId: "main",
label: "codex-thread",
webhookId: "wh-1",
webhookToken: "tok-1",
boundBy: "system",
boundAt: Date.now(),
}),
});
mockBoundThreadManager();
const result = await discordOutbound.sendText?.({
cfg: {},
@@ -160,20 +164,7 @@ describe("discordOutbound", () => {
});
it("falls back to bot send for silent delivery on bound threads", async () => {
hoisted.getThreadBindingManagerMock.mockReturnValue({
getByThreadId: () => ({
accountId: "default",
channelId: "parent-1",
threadId: "thread-1",
targetKind: "subagent",
targetSessionKey: "agent:main:subagent:child",
agentId: "main",
webhookId: "wh-1",
webhookToken: "tok-1",
boundBy: "system",
boundAt: Date.now(),
}),
});
mockBoundThreadManager();
const result = await discordOutbound.sendText?.({
cfg: {},
@@ -201,20 +192,7 @@ describe("discordOutbound", () => {
});
it("falls back to bot send when webhook send fails", async () => {
hoisted.getThreadBindingManagerMock.mockReturnValue({
getByThreadId: () => ({
accountId: "default",
channelId: "parent-1",
threadId: "thread-1",
targetKind: "subagent",
targetSessionKey: "agent:main:subagent:child",
agentId: "main",
webhookId: "wh-1",
webhookToken: "tok-1",
boundBy: "system",
boundAt: Date.now(),
}),
});
mockBoundThreadManager();
hoisted.sendWebhookMessageDiscordMock.mockRejectedValueOnce(new Error("rate limited"));
const result = await discordOutbound.sendText?.({

View File

@@ -57,7 +57,7 @@ export type ChannelConfigAdapter<ResolvedAccount> = {
resolveAllowFrom?: (params: {
cfg: OpenClawConfig;
accountId?: string | null;
}) => string[] | undefined;
}) => Array<string | number> | undefined;
formatAllowFrom?: (params: {
cfg: OpenClawConfig;
accountId?: string | null;