import { GROK_BOT_CATEGORY_ID, KNOWN_GROK_BOT_CHANNELS, listChannelMappings, readCategoryId, upsertStubBotRecord, writeCategoryId, writeChannelMapping, type ChannelMapping, } from './discord-map.ts' export type SyncDiscordInput = { /** Override the stored Grok Bot category id. */ categoryId?: string } export type SyncDiscordResult = { categoryId: string channels: ChannelMapping[] upserted: number } /** * Persist the Grok Bot Discord category and existing per-bot channel map. * * Channels can exist before a bot is wake-registered. Does not need webhook * URLs. Safe to re-run; existing webhook URLs on roster rows are kept. * * @param input.categoryId - Optional category id override * @returns Stored category id and channel mappings * @example * import syncDiscord from 'kody:@kentcdodds/grok-bot/sync-discord' * const synced = await syncDiscord() * // => { categoryId: '1542616354274676827', channels: [{ channelId, botId, name }], upserted: 10 } */ export default async function syncDiscord( input: SyncDiscordInput = {}, ): Promise { const categoryId = await writeCategoryId( typeof input.categoryId === 'string' && input.categoryId.trim() ? input.categoryId.trim() : GROK_BOT_CATEGORY_ID, ) let upserted = 0 for (const channel of KNOWN_GROK_BOT_CHANNELS) { await writeChannelMapping({ channelId: channel.channelId, botId: channel.botId, name: channel.name, }) await upsertStubBotRecord({ id: channel.botId, name: channel.name, channelId: channel.channelId, }) upserted += 1 } const channels = await listChannelMappings() return { categoryId: categoryId || (await readCategoryId()), channels, upserted, } }