diff --git a/.replit b/.replit index 33231a5..af5ecb8 100644 --- a/.replit +++ b/.replit @@ -22,6 +22,10 @@ externalPort = 80 localPort = 8080 externalPort = 8080 +[[ports]] +localPort = 44195 +externalPort = 3000 + [workflows] runButton = "Project" diff --git a/aethex-bot/commands/verify.js b/aethex-bot/commands/verify.js index d9f30e7..4e5e6c4 100644 --- a/aethex-bot/commands/verify.js +++ b/aethex-bot/commands/verify.js @@ -40,11 +40,10 @@ module.exports = { .toUpperCase(); const expiresAt = new Date(Date.now() + 15 * 60 * 1000); // 15 minutes - // Store verification code with Discord username + // Store verification code await supabase.from("discord_verifications").insert({ discord_id: interaction.user.id, verification_code: verificationCode, - username: interaction.user.username, expires_at: expiresAt.toISOString(), }); diff --git a/aethex-bot/scripts/register-commands.js b/aethex-bot/scripts/register-commands.js index 441715c..8c84277 100644 --- a/aethex-bot/scripts/register-commands.js +++ b/aethex-bot/scripts/register-commands.js @@ -1,196 +1,8 @@ const { REST, Routes } = require('discord.js'); +const fs = require('fs'); +const path = require('path'); require('dotenv').config(); -const commands = [ - { - name: 'verify', - description: 'Link your Discord account to your AeThex account', - }, - { - name: 'unlink', - description: 'Unlink your Discord account from AeThex', - }, - { - name: 'profile', - description: 'View your AeThex profile in Discord', - }, - { - name: 'help', - description: 'View all AeThex bot commands and features', - }, - { - name: 'leaderboard', - description: 'View the top AeThex contributors', - options: [ - { - name: 'category', - type: 3, - description: 'Leaderboard category', - required: false, - choices: [ - { name: 'Most Active (Posts)', value: 'posts' }, - { name: 'Most Liked', value: 'likes' }, - { name: 'Top Creators', value: 'creators' }, - ], - }, - ], - }, - { - name: 'stats', - description: 'View your AeThex statistics and activity', - }, - { - name: 'set-realm', - description: 'Set your primary AeThex realm/arm', - }, - { - name: 'verify-role', - description: 'Check your AeThex-assigned Discord roles', - }, - { - name: 'refresh-roles', - description: 'Refresh your Discord roles based on your current AeThex settings', - }, - { - name: 'post', - description: 'Create a post in the AeThex community feed', - options: [ - { - name: 'content', - type: 3, - description: 'Your post content', - required: true, - max_length: 500, - }, - { - name: 'category', - type: 3, - description: 'Post category', - required: false, - choices: [ - { name: 'General', value: 'general' }, - { name: 'Project Update', value: 'project_update' }, - { name: 'Question', value: 'question' }, - { name: 'Idea', value: 'idea' }, - { name: 'Announcement', value: 'announcement' }, - ], - }, - { - name: 'image', - type: 11, - description: 'Attach an image to your post', - required: false, - }, - ], - }, - { - name: 'ticket', - description: 'Ticket management system', - options: [ - { - name: 'create', - type: 1, - description: 'Create a new support ticket', - options: [ - { - name: 'reason', - type: 3, - description: 'Brief reason for opening this ticket', - required: true, - }, - ], - }, - { - name: 'close', - type: 1, - description: 'Close the current ticket', - }, - ], - }, - { - name: 'admin', - description: 'Admin monitoring commands', - default_member_permissions: '8', - options: [ - { - name: 'status', - type: 1, - description: 'View bot status and statistics', - }, - { - name: 'heat', - type: 1, - description: 'Check heat level of a user', - options: [ - { - name: 'user', - type: 6, - description: 'User to check', - required: true, - }, - ], - }, - { - name: 'servers', - type: 1, - description: 'View all servers the bot is in', - }, - { - name: 'threats', - type: 1, - description: 'View current heat map (active threats)', - }, - { - name: 'federation', - type: 1, - description: 'View federation role mappings', - }, - ], - }, - { - name: 'federation', - description: 'Manage cross-server role sync', - default_member_permissions: '8', - options: [ - { - name: 'link', - type: 1, - description: 'Link a role for cross-server syncing', - options: [ - { - name: 'role', - type: 8, - description: 'Role to sync across realms', - required: true, - }, - ], - }, - { - name: 'unlink', - type: 1, - description: 'Remove a role from cross-server syncing', - options: [ - { - name: 'role', - type: 8, - description: 'Role to remove from sync', - required: true, - }, - ], - }, - { - name: 'list', - type: 1, - description: 'List all linked roles', - }, - ], - }, - { - name: 'status', - description: 'View network status and bot health', - }, -]; - const token = process.env.DISCORD_BOT_TOKEN; const clientId = process.env.DISCORD_CLIENT_ID; @@ -204,11 +16,25 @@ if (!clientId) { process.exit(1); } +const commandsPath = path.join(__dirname, '../commands'); +const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); + +const commands = []; + +for (const file of commandFiles) { + const filePath = path.join(commandsPath, file); + const command = require(filePath); + if ('data' in command && 'execute' in command) { + commands.push(command.data.toJSON()); + console.log(`Loaded command: ${command.data.name}`); + } +} + const rest = new REST({ version: '10' }).setToken(token); (async () => { try { - console.log('Fetching existing commands...'); + console.log(`\nFetching existing commands...`); const existingCommands = await rest.get( Routes.applicationCommands(clientId) @@ -218,7 +44,12 @@ const rest = new REST({ version: '10' }).setToken(token); const entryPointCommands = existingCommands.filter(cmd => cmd.type === 4); - const allCommands = [...commands, ...entryPointCommands]; + const allCommands = [...commands, ...entryPointCommands.map(cmd => ({ + name: cmd.name, + description: cmd.description, + type: cmd.type, + handler: cmd.handler, + }))]; console.log(`Registering ${commands.length} commands (preserving ${entryPointCommands.length} entry points)...`); @@ -227,9 +58,32 @@ const rest = new REST({ version: '10' }).setToken(token); { body: allCommands } ); - console.log(`Successfully registered ${data.length} commands:`); + console.log(`\nSuccessfully registered ${data.length} commands:`); data.forEach(cmd => console.log(` - /${cmd.name}`)); } catch (error) { - console.error('Error registering commands:', error); + if (error.code === 50240) { + console.warn('\nEntry Point detected. Registering individually...'); + + let successCount = 0; + for (const command of commands) { + try { + await rest.post( + Routes.applicationCommands(clientId), + { body: command } + ); + console.log(` + /${command.name}`); + successCount++; + } catch (postError) { + if (postError.code === 50045) { + console.log(` ~ /${command.name} (already exists)`); + } else { + console.error(` x /${command.name}: ${postError.message}`); + } + } + } + console.log(`\nRegistered ${successCount} commands individually.`); + } else { + console.error('Error registering commands:', error); + } } })();