feat(inventory): add inventory interaction handler utilities
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
71
bot/modules/inventory/inventory.interaction.ts
Normal file
71
bot/modules/inventory/inventory.interaction.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import type { StringSelectMenuInteraction, ButtonInteraction, MessageFlags } from "discord.js";
|
||||
import { inventoryService } from "@shared/modules/inventory/inventory.service";
|
||||
import { getLootboxResultMessage } from "./inventory.view";
|
||||
import type { ItemUsageData } from "@shared/lib/types";
|
||||
import { getGuildConfig } from "@shared/lib/config";
|
||||
|
||||
export interface InventoryState {
|
||||
ownerId: string;
|
||||
viewerId: string;
|
||||
page: number;
|
||||
selectedItemId: number | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the viewer user ID from an inventory custom ID.
|
||||
* Custom IDs follow the format: inv_{action}_{viewerId}
|
||||
*/
|
||||
export function parseInventoryCustomId(customId: string): { action: string; viewerId: string } | null {
|
||||
const match = customId.match(/^inv_(\w+?)_(\d+)$/);
|
||||
if (!match) return null;
|
||||
return { action: match[1]!, viewerId: match[2]! };
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a custom ID belongs to the inventory system.
|
||||
*/
|
||||
export function isInventoryInteraction(customId: string): boolean {
|
||||
return customId.startsWith("inv_");
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the "Use" button — executes item effects.
|
||||
* Returns the result messages array from inventoryService.useItem,
|
||||
* plus handles role-based effects that require the guild member.
|
||||
*/
|
||||
export async function executeItemUse(
|
||||
interaction: ButtonInteraction,
|
||||
userId: string,
|
||||
itemId: number,
|
||||
): Promise<{ results: any[]; usageData: ItemUsageData | null; item: any }> {
|
||||
const result = await inventoryService.useItem(userId, itemId);
|
||||
|
||||
// Handle role effects (same logic as /use command)
|
||||
const usageData = result.usageData;
|
||||
if (usageData) {
|
||||
const guildConfig = await getGuildConfig(interaction.guildId!);
|
||||
const colorRoles = guildConfig.colorRoles ?? [];
|
||||
|
||||
for (const effect of usageData.effects) {
|
||||
if (effect.type === "TEMP_ROLE" || effect.type === "COLOR_ROLE") {
|
||||
try {
|
||||
const member = await interaction.guild?.members.fetch(userId);
|
||||
if (member) {
|
||||
if (effect.type === "TEMP_ROLE") {
|
||||
await member.roles.add(effect.roleId);
|
||||
} else if (effect.type === "COLOR_ROLE") {
|
||||
const rolesToRemove = colorRoles.filter((r: string) => member.roles.cache.has(r));
|
||||
if (rolesToRemove.length > 0) await member.roles.remove(rolesToRemove);
|
||||
await member.roles.add(effect.roleId);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to assign role in inventory use:", e);
|
||||
result.results.push("⚠️ Failed to assign role (Check bot permissions)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user