import { listDirectoryGroupEntriesFromMapKeysAndAllowFrom, listDirectoryUserEntriesFromAllowFromAndMapKeys, } from "openclaw/plugin-sdk/compat"; import type { ClawdbotConfig } from "openclaw/plugin-sdk/feishu"; import { resolveFeishuAccount } from "./accounts.js"; import { createFeishuClient } from "./client.js"; import { normalizeFeishuTarget } from "./targets.js"; export type FeishuDirectoryPeer = { kind: "user"; id: string; name?: string; }; export type FeishuDirectoryGroup = { kind: "group"; id: string; name?: string; }; function toFeishuDirectoryPeers(ids: string[]): FeishuDirectoryPeer[] { return ids.map((id) => ({ kind: "user", id })); } function toFeishuDirectoryGroups(ids: string[]): FeishuDirectoryGroup[] { return ids.map((id) => ({ kind: "group", id })); } export async function listFeishuDirectoryPeers(params: { cfg: ClawdbotConfig; query?: string; limit?: number; accountId?: string; }): Promise { const account = resolveFeishuAccount({ cfg: params.cfg, accountId: params.accountId }); const entries = listDirectoryUserEntriesFromAllowFromAndMapKeys({ allowFrom: account.config.allowFrom, map: account.config.dms, query: params.query, limit: params.limit, normalizeAllowFromId: (entry) => normalizeFeishuTarget(entry) ?? entry, normalizeMapKeyId: (entry) => normalizeFeishuTarget(entry) ?? entry, }); return toFeishuDirectoryPeers(entries.map((entry) => entry.id)); } export async function listFeishuDirectoryGroups(params: { cfg: ClawdbotConfig; query?: string; limit?: number; accountId?: string; }): Promise { const account = resolveFeishuAccount({ cfg: params.cfg, accountId: params.accountId }); const entries = listDirectoryGroupEntriesFromMapKeysAndAllowFrom({ groups: account.config.groups, allowFrom: account.config.groupAllowFrom, query: params.query, limit: params.limit, }); return toFeishuDirectoryGroups(entries.map((entry) => entry.id)); } export async function listFeishuDirectoryPeersLive(params: { cfg: ClawdbotConfig; query?: string; limit?: number; accountId?: string; }): Promise { const account = resolveFeishuAccount({ cfg: params.cfg, accountId: params.accountId }); if (!account.configured) { return listFeishuDirectoryPeers(params); } try { const client = createFeishuClient(account); const peers: FeishuDirectoryPeer[] = []; const limit = params.limit ?? 50; const response = await client.contact.user.list({ params: { page_size: Math.min(limit, 50), }, }); if (response.code === 0 && response.data?.items) { for (const user of response.data.items) { if (user.open_id) { const q = params.query?.trim().toLowerCase() || ""; const name = user.name || ""; if (!q || user.open_id.toLowerCase().includes(q) || name.toLowerCase().includes(q)) { peers.push({ kind: "user", id: user.open_id, name: name || undefined, }); } } if (peers.length >= limit) { break; } } } return peers; } catch { return listFeishuDirectoryPeers(params); } } export async function listFeishuDirectoryGroupsLive(params: { cfg: ClawdbotConfig; query?: string; limit?: number; accountId?: string; }): Promise { const account = resolveFeishuAccount({ cfg: params.cfg, accountId: params.accountId }); if (!account.configured) { return listFeishuDirectoryGroups(params); } try { const client = createFeishuClient(account); const groups: FeishuDirectoryGroup[] = []; const limit = params.limit ?? 50; const response = await client.im.chat.list({ params: { page_size: Math.min(limit, 100), }, }); if (response.code === 0 && response.data?.items) { for (const chat of response.data.items) { if (chat.chat_id) { const q = params.query?.trim().toLowerCase() || ""; const name = chat.name || ""; if (!q || chat.chat_id.toLowerCase().includes(q) || name.toLowerCase().includes(q)) { groups.push({ kind: "group", id: chat.chat_id, name: name || undefined, }); } } if (groups.length >= limit) { break; } } } return groups; } catch { return listFeishuDirectoryGroups(params); } }