UNPKG

@gguf/claw

Version:

WhatsApp gateway CLI (Baileys web) with Pi RPC agent

138 lines (122 loc) 3.97 kB
/** * Twitch resolver adapter for channel/user name resolution. * * This module implements the ChannelResolverAdapter interface to resolve * Twitch usernames to user IDs via the Twitch Helix API. */ import { ApiClient } from "@twurple/api"; import { StaticAuthProvider } from "@twurple/auth"; import type { ChannelResolveKind, ChannelResolveResult } from "./types.js"; import type { ChannelLogSink, TwitchAccountConfig } from "./types.js"; import { normalizeToken } from "./utils/twitch.js"; /** * Normalize a Twitch username - strip @ prefix and convert to lowercase */ function normalizeUsername(input: string): string { const trimmed = input.trim(); if (trimmed.startsWith("@")) { return trimmed.slice(1).toLowerCase(); } return trimmed.toLowerCase(); } /** * Create a logger that includes the Twitch prefix */ function createLogger(logger?: ChannelLogSink): ChannelLogSink { return { info: (msg: string) => logger?.info(msg), warn: (msg: string) => logger?.warn(msg), error: (msg: string) => logger?.error(msg), debug: (msg: string) => logger?.debug?.(msg) ?? (() => {}), }; } /** * Resolve Twitch usernames to user IDs via the Helix API * * @param inputs - Array of usernames or user IDs to resolve * @param account - Twitch account configuration with auth credentials * @param kind - Type of target to resolve ("user" or "group") * @param logger - Optional logger * @returns Promise resolving to array of ChannelResolveResult */ export async function resolveTwitchTargets( inputs: string[], account: TwitchAccountConfig, kind: ChannelResolveKind, logger?: ChannelLogSink, ): Promise<ChannelResolveResult[]> { const log = createLogger(logger); if (!account.clientId || !account.token) { log.error("Missing Twitch client ID or token"); return inputs.map((input) => ({ input, resolved: false, note: "missing Twitch credentials", })); } const normalizedToken = normalizeToken(account.token); const authProvider = new StaticAuthProvider(account.clientId, normalizedToken); const apiClient = new ApiClient({ authProvider }); const results: ChannelResolveResult[] = []; for (const input of inputs) { const normalized = normalizeUsername(input); if (!normalized) { results.push({ input, resolved: false, note: "empty input", }); continue; } const looksLikeUserId = /^\d+$/.test(normalized); try { if (looksLikeUserId) { const user = await apiClient.users.getUserById(normalized); if (user) { results.push({ input, resolved: true, id: user.id, name: user.name, }); log.debug?.(`Resolved user ID ${normalized} -> ${user.name}`); } else { results.push({ input, resolved: false, note: "user ID not found", }); log.warn(`User ID ${normalized} not found`); } } else { const user = await apiClient.users.getUserByName(normalized); if (user) { results.push({ input, resolved: true, id: user.id, name: user.name, note: user.displayName !== user.name ? `display: ${user.displayName}` : undefined, }); log.debug?.(`Resolved username ${normalized} -> ${user.id} (${user.name})`); } else { results.push({ input, resolved: false, note: "username not found", }); log.warn(`Username ${normalized} not found`); } } } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); results.push({ input, resolved: false, note: `API error: ${errorMessage}`, }); log.error(`Failed to resolve ${input}: ${errorMessage}`); } } return results; }