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<SyncDiscordResult> {
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,
}
}