telegram-user: add config directory listing

This commit is contained in:
Muhammed Mukhthar CM 2026-01-26 07:07:20 +00:00
parent eeeacadb36
commit a414f8e7f5
3 changed files with 116 additions and 1 deletions

View File

@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { ClawdbotConfig } from "clawdbot/plugin-sdk";
import type { ClawdbotConfig, RuntimeEnv } from "clawdbot/plugin-sdk";
const sendMediaTelegramUser = vi.fn<
typeof import("./send.js").sendMediaTelegramUser
@ -75,4 +75,42 @@ describe("telegram-user channel plugin", () => {
const [, , opts] = sendMediaTelegramUser.mock.calls[0] ?? [];
expect(opts).not.toHaveProperty("maxBytes");
});
it("lists peers and groups from config like the telegram plugin directory", async () => {
const cfg = {
channels: {
"telegram-user": {
allowFrom: ["123", "@alice", "telegram-user:456", "user:@bob", "*"],
groupAllowFrom: ["tg:carol", 789],
groups: {
"-1001": {},
"*": {},
},
},
},
} satisfies Partial<ClawdbotConfig> as unknown as ClawdbotConfig;
const mod = await import("./channel.js");
const runtime = {
log: () => {},
warn: () => {},
error: () => {},
exit: (): never => {
throw new Error("exit called");
},
} satisfies RuntimeEnv;
const peers = await mod.telegramUserPlugin.directory?.listPeers?.({
cfg,
runtime,
});
const groups = await mod.telegramUserPlugin.directory?.listGroups?.({
cfg,
runtime,
});
expect(peers?.map((p) => p.id).sort()).toEqual(
["123", "456", "@alice", "@bob", "@carol", "789"].sort(),
);
expect(groups?.map((g) => g.id)).toEqual(["-1001"]);
});
});

View File

@ -23,6 +23,10 @@ import {
type ResolvedTelegramUserAccount,
} from "./accounts.js";
import { TelegramUserConfigSchema } from "./config-schema.js";
import {
listTelegramUserDirectoryGroupsFromConfig,
listTelegramUserDirectoryPeersFromConfig,
} from "./directory-config.js";
import { loginTelegramUser } from "./login.js";
import { monitorTelegramUserProvider } from "./monitor/index.js";
import {
@ -117,6 +121,11 @@ export const telegramUserPlugin: ChannelPlugin<ResolvedTelegramUserAccount> = {
hint: "<userId or @username>",
},
},
directory: {
self: async () => null,
listPeers: async (params) => listTelegramUserDirectoryPeersFromConfig(params),
listGroups: async (params) => listTelegramUserDirectoryGroupsFromConfig(params),
},
reload: { configPrefixes: ["channels.telegram-user"] },
configSchema: buildChannelConfigSchema(TelegramUserConfigSchema),
config: {

View File

@ -0,0 +1,68 @@
import type { ChannelDirectoryEntry, ClawdbotConfig } from "clawdbot/plugin-sdk";
import { resolveTelegramUserAccount } from "./accounts.js";
import type { CoreConfig } from "./types.js";
export type TelegramUserDirectoryConfigParams = {
cfg: ClawdbotConfig;
accountId?: string | null;
query?: string | null;
limit?: number | null;
};
function normalizePeerEntry(raw: string): string | null {
const trimmed = raw.trim();
if (!trimmed) return null;
const cleaned = trimmed
.replace(/^(telegram-user|telegram|tg):/i, "")
.replace(/^user:/i, "")
.trim();
if (!cleaned) return null;
if (/^-?\d+$/.test(cleaned)) return cleaned;
const withoutAt = cleaned.replace(/^@/, "");
if (!withoutAt) return null;
return `@${withoutAt}`;
}
export async function listTelegramUserDirectoryPeersFromConfig(
params: TelegramUserDirectoryConfigParams,
): Promise<ChannelDirectoryEntry[]> {
const account = resolveTelegramUserAccount({
cfg: params.cfg as CoreConfig,
accountId: params.accountId,
});
const q = params.query?.trim().toLowerCase() || "";
const raw = [
...(account.config.allowFrom ?? []).map((entry) => String(entry)),
...(account.config.groupAllowFrom ?? []).map((entry) => String(entry)),
];
return Array.from(
new Set(
raw
.map((entry) => entry.trim())
.filter((entry) => Boolean(entry) && entry !== "*"),
),
)
.map((entry) => normalizePeerEntry(entry))
.filter((id): id is string => Boolean(id))
.filter((id) => (q ? id.toLowerCase().includes(q) : true))
.slice(0, params.limit && params.limit > 0 ? params.limit : undefined)
.map((id) => ({ kind: "user", id }) as const);
}
export async function listTelegramUserDirectoryGroupsFromConfig(
params: TelegramUserDirectoryConfigParams,
): Promise<ChannelDirectoryEntry[]> {
const account = resolveTelegramUserAccount({
cfg: params.cfg as CoreConfig,
accountId: params.accountId,
});
const q = params.query?.trim().toLowerCase() || "";
return Object.keys(account.config.groups ?? {})
.map((id) => id.trim())
.filter((id) => Boolean(id) && id !== "*")
.filter((id) => (q ? id.toLowerCase().includes(q) : true))
.slice(0, params.limit && params.limit > 0 ? params.limit : undefined)
.map((id) => ({ kind: "group", id }) as const);
}