UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

264 lines (263 loc) 8.14 kB
import { n as fetchDiscord, t as DiscordApiError } from "./api-IrbNzRWx.js"; import { a as normalizeDiscordSlug } from "./allow-list-CBhA2l4a.js"; import { i as listGuilds, n as filterDiscordGuilds, r as resolveDiscordAllowlistToken, t as buildDiscordUnresolvedResults } from "./resolve-allowlist-common-B5ZvlFtU.js"; //#region extensions/discord/src/resolve-channels.ts function parseDiscordChannelInput(raw) { const trimmed = raw.trim(); if (!trimmed) return {}; const mention = trimmed.match(/^<#(\d+)>$/); if (mention) return { channelId: mention[1] }; const channelPrefix = trimmed.match(/^(?:channel:|discord:)?(\d+)$/i); if (channelPrefix) return { channelId: channelPrefix[1] }; const guildPrefix = trimmed.match(/^(?:guild:|server:)?(\d+)$/i); if (guildPrefix && !trimmed.includes("/") && !trimmed.includes("#")) return { guildId: guildPrefix[1], guildOnly: true }; const split = trimmed.includes("/") ? trimmed.split("/") : trimmed.split("#"); if (split.length >= 2) { const guild = split[0]?.trim(); const channel = split.slice(1).join("#").trim(); if (!channel) return guild ? { guild: guild.trim(), guildOnly: true } : {}; if (guild && /^\d+$/.test(guild)) { if (/^\d+$/.test(channel)) return { guildId: guild, channelId: channel }; return { guildId: guild, channel }; } return { guild, channel }; } return { guild: trimmed, guildOnly: true }; } async function listGuildChannels(token, fetcher, guildId) { return (await fetchDiscord(`/guilds/${guildId}/channels`, token, fetcher)).map((channel) => { const archived = channel.thread_metadata?.archived; return { id: typeof channel.id === "string" ? channel.id : "", name: typeof channel.name === "string" ? channel.name : "", guildId, type: channel.type, archived }; }).filter((channel) => Boolean(channel.id) && Boolean(channel.name)); } async function fetchChannel(token, fetcher, channelId) { let raw; try { raw = await fetchDiscord(`/channels/${channelId}`, token, fetcher); } catch (err) { if (err instanceof DiscordApiError && err.status === 403) return { status: "forbidden" }; if (err instanceof DiscordApiError && err.status === 404) return { status: "not-found" }; throw err; } if (!raw || typeof raw.guild_id !== "string" || typeof raw.id !== "string") return { status: "invalid" }; return { status: "found", channel: { id: raw.id, name: typeof raw.name === "string" ? raw.name : "", guildId: raw.guild_id, type: raw.type } }; } function preferActiveMatch(candidates) { if (candidates.length === 0) return; const scored = candidates.map((channel) => { const isThread = channel.type === 11 || channel.type === 12; return { channel, score: (Boolean(channel.archived) ? 0 : 2) + (isThread ? 0 : 1) }; }); scored.sort((a, b) => b.score - a.score); return scored[0]?.channel ?? candidates[0]; } async function resolveDiscordChannelAllowlist(params) { const token = resolveDiscordAllowlistToken(params.token); if (!token) return buildDiscordUnresolvedResults(params.entries, (input) => ({ input, resolved: false })); const fetcher = params.fetcher ?? fetch; const guilds = await listGuilds(token, fetcher); const channelsByGuild = /* @__PURE__ */ new Map(); const getChannels = (guildId) => { const existing = channelsByGuild.get(guildId); if (existing) return existing; const promise = listGuildChannels(token, fetcher, guildId); channelsByGuild.set(guildId, promise); return promise; }; const results = []; for (const input of params.entries) { const parsed = parseDiscordChannelInput(input); if (parsed.guildOnly) { const guild = filterDiscordGuilds(guilds, { guildId: parsed.guildId, guildName: parsed.guild })[0]; if (guild) results.push({ input, resolved: true, guildId: guild.id, guildName: guild.name }); else results.push({ input, resolved: false, guildId: parsed.guildId, guildName: parsed.guild }); continue; } if (parsed.channelId) { const channelId = parsed.channelId; const result = await fetchChannel(token, fetcher, channelId); if (result.status === "found") { const channel = result.channel; if (parsed.guildId && parsed.guildId !== channel.guildId) { const expectedGuild = guilds.find((entry) => entry.id === parsed.guildId); const actualGuild = guilds.find((entry) => entry.id === channel.guildId); results.push({ input, resolved: false, guildId: parsed.guildId, guildName: expectedGuild?.name, channelId, channelName: channel.name, note: actualGuild?.name ? `channel belongs to guild ${actualGuild.name}` : "channel belongs to a different guild" }); continue; } const guild = guilds.find((entry) => entry.id === channel.guildId); results.push({ input, resolved: true, guildId: channel.guildId, guildName: guild?.name, channelId: channel.id, channelName: channel.name, archived: channel.archived }); continue; } if (result.status === "not-found" && parsed.guildId) { const guild = guilds.find((entry) => entry.id === parsed.guildId); if (guild) { const match = preferActiveMatch((await getChannels(guild.id)).filter((channel) => normalizeDiscordSlug(channel.name) === normalizeDiscordSlug(channelId))); if (match) { results.push({ input, resolved: true, guildId: guild.id, guildName: guild.name, channelId: match.id, channelName: match.name, archived: match.archived }); continue; } } } results.push({ input, resolved: false, guildId: parsed.guildId, channelId }); continue; } if (parsed.guildId || parsed.guild) { const guild = filterDiscordGuilds(guilds, { guildId: parsed.guildId, guildName: parsed.guild })[0]; const channelQuery = parsed.channel?.trim(); if (!guild || !channelQuery) { results.push({ input, resolved: false, guildId: parsed.guildId, guildName: parsed.guild, channelName: channelQuery ?? parsed.channel }); continue; } const channels = await getChannels(guild.id); const normalizedChannelQuery = normalizeDiscordSlug(channelQuery); const isNumericId = /^\d+$/.test(channelQuery); let matches = channels.filter((channel) => isNumericId ? channel.id === channelQuery : normalizeDiscordSlug(channel.name) === normalizedChannelQuery); if (isNumericId && matches.length === 0) matches = channels.filter((channel) => normalizeDiscordSlug(channel.name) === normalizedChannelQuery); const match = preferActiveMatch(matches); if (match) results.push({ input, resolved: true, guildId: guild.id, guildName: guild.name, channelId: match.id, channelName: match.name, archived: match.archived }); else results.push({ input, resolved: false, guildId: guild.id, guildName: guild.name, channelName: parsed.channel, note: `channel not found in guild ${guild.name}` }); continue; } const channelName = input.trim().replace(/^#/, ""); if (!channelName) { results.push({ input, resolved: false, channelName }); continue; } const candidates = []; for (const guild of guilds) { const channels = await getChannels(guild.id); for (const channel of channels) if (normalizeDiscordSlug(channel.name) === normalizeDiscordSlug(channelName)) candidates.push(channel); } const match = preferActiveMatch(candidates); if (match) { const guild = guilds.find((entry) => entry.id === match.guildId); results.push({ input, resolved: true, guildId: match.guildId, guildName: guild?.name, channelId: match.id, channelName: match.name, archived: match.archived, note: candidates.length > 1 && guild?.name ? `matched multiple; chose ${guild.name}` : void 0 }); continue; } results.push({ input, resolved: false, channelName }); } return results; } //#endregion export { resolveDiscordChannelAllowlist as t };