import { Interaction, ChatInputCommandInteraction, ButtonInteraction } from "discord.js"; import { handleButton } from "@handlers/buttons"; import { handleTgCommand } from "@commands/tg"; import { handleTgConfigCommand } from "@commands/tgConfig"; import { handleBorrowAcceptButton } from "@subcommands/char/accept"; import { handleBorrowDeclineButton } from "@subcommands/char/decline"; import { handleConflictButton } from "@systems/conflict"; import { handleImpersonateButton } from "@subcommands/impersonate"; import { handleAutocomplete } from "@handlers/autocomplete"; export async function handleInteraction(interaction: Interaction): Promise { try { if (interaction.isAutocomplete()) { await handleAutocomplete(interaction); return; } if (interaction.isButton()) { const btn = interaction as ButtonInteraction; // Conflict resolution buttons if (btn.customId.startsWith("conflict_")) { return await handleConflictButton(btn); } if (btn.customId.startsWith("impersonate_")) { return await handleImpersonateButton(btn); } if (btn.customId.startsWith("switch_after_reclaim:")) { const [, userKey, charName] = btn.customId.split(":"); const { setActiveCharacter } = require("@systems/characters"); const { setPersistentPreference, clearSessionBorrowForUser, getEffectiveCharacter } = require("@systems/borrow"); // Check if it's a shared char const fs = require("fs"); const path = require("path"); const chars = JSON.parse(fs.readFileSync(path.join(__dirname, "../../data/characters.json"), "utf8")); let resolved = false; // Try own char first if (chars[userKey]?.characters?.find((c: any) => c.name === charName)) { setActiveCharacter(userKey, charName); clearSessionBorrowForUser(userKey); resolved = true; } else { // Try shared char for (const [ownerKey, data] of Object.entries(chars) as [string, any][]) { const char = data.characters?.find((c: any) => c.name === charName && c.sharedWith?.includes(userKey)); if (char) { setPersistentPreference(userKey, ownerKey, charName); clearSessionBorrowForUser(userKey); resolved = true; break; } } } if (resolved) { await btn.reply({ content: `✅ Switched to **${charName}**.`, ephemeral: true }); } else { await btn.reply({ content: `❌ Could not switch to **${charName}**.`, ephemeral: true }); } return; } // Borrow accept/decline buttons from DM if (btn.customId.startsWith("borrow_accept:")) { const [, ownerKey, requesterKey] = btn.customId.split(":"); return await handleBorrowAcceptButton(btn, ownerKey, requesterKey); } if (btn.customId.startsWith("borrow_decline:")) { const [, ownerKey, requesterKey] = btn.customId.split(":"); return await handleBorrowDeclineButton(btn, ownerKey, requesterKey); } return await handleButton(btn); } if (interaction.isChatInputCommand()) { const cmd = interaction as ChatInputCommandInteraction; if (cmd.commandName === "tg") await handleTgCommand(cmd); if (cmd.commandName === "tg-config") await handleTgConfigCommand(cmd); } } catch (err) { console.error("Interaction error:", err); try { const msg = { content: "❌ An error occurred.", ephemeral: true }; if ((interaction as any).replied || (interaction as any).deferred) { await (interaction as any).followUp(msg); } else { await (interaction as any).reply(msg); } } catch {} } }