如何让Discord服务器管理员无需开发者即可自主添加更新命令?
解决方案:数据驱动命令+管理员自主同步Discord命令(含Choices)
一、核心思路
把命令的元数据(名称、描述、Choices、权限要求等)完全托管在Firebase实时数据库,Bot代码仅保留通用执行逻辑;同时给服务器管理员开放自主触发命令同步的入口,彻底摆脱对开发者的依赖。
二、具体实现步骤
1. 重构命令结构,实现数据与代码分离
将原command/xxx.js中的命令配置抽离到Firebase,数据库结构示例:
{ "commands": { "game_select": { "name": "game_select", "description": "选择要玩的游戏", "choices": [ { "name": "原神", "value": "genshin" }, { "name": "星穹铁道", "value": "hsr" } ], "required_perms": ["ADMINISTRATOR"], "handler": "gameHandler" // 对应Bot代码中的通用处理函数标识 } } }
Bot代码中编写通用处理逻辑,根据handler字段匹配对应的执行函数,新增命令仅需在Firebase添加配置,无需修改代码。
2. 实现管理员自主触发命令同步
替代手动运行deploy-commands.js,新增一个仅管理员可用的Discord命令/sync-commands,执行时自动拉取Firebase配置并同步到Discord API:
const { REST, Routes } = require('discord.js'); const admin = require('firebase-admin'); // 初始化客户端 const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN); admin.initializeApp({ /* Firebase配置 */ }); const db = admin.database(); // 同步命令核心函数 async function syncCommands(guildId) { const commandsSnapshot = await db.ref('commands').once('value'); const commandsData = commandsSnapshot.val() || {}; // 转换为Discord API要求的格式 const discordCommands = Object.values(commandsData).map(cmd => ({ name: cmd.name, description: cmd.description, options: cmd.choices ? [{ type: 3, // STRING类型选项 name: "target", description: "选择目标选项", choices: cmd.choices }] : [], default_member_permissions: cmd.required_perms ? cmd.required_perms.join(',') : null })); // 同步到指定服务器(全局命令移除guildId参数) await rest.put( Routes.applicationGuildCommands(process.env.CLIENT_ID, guildId), { body: discordCommands } ); } // 管理员触发命令 client.on('interactionCreate', async interaction => { if (!interaction.isChatInputCommand()) return; if (interaction.commandName === 'sync-commands') { if (!interaction.member.permissions.has('ADMINISTRATOR')) { return interaction.reply({ content: "无权限执行此命令", ephemeral: true }); } await interaction.deferReply({ ephemeral: true }); try { await syncCommands(interaction.guildId); interaction.editReply("命令已同步完成"); } catch (err) { interaction.editReply(`同步失败:${err.message}`); } return; } // 通用命令执行逻辑 const cmdSnapshot = await db.ref(`commands/${interaction.commandName}`).once('value'); const cmdData = cmdSnapshot.val(); if (!cmdData) return; const handlers = require('./command-handlers'); if (handlers[cmdData.handler]) { await handlers[cmdData.handler](interaction, cmdData); } });
3. 可选:给管理员做极简Web表单(提升易用性)
如果管理员不熟悉Firebase操作,可在Heroku同应用下部署一个极简Web表单,字段对应命令名称、描述、Choices等,提交后直接写入Firebase并自动触发同步逻辑(例如通过内部接口通知Bot执行同步)。
三、最简方案总结
- 命令配置全移至Firebase,代码仅保留通用处理逻辑,实现数据与代码分离。
- 新增管理员命令
/sync-commands,让管理员自主触发命令同步,无需开发者介入。 - 可选:Web表单降低管理员操作门槛,无需直接接触数据库。
这个方案完全满足服务器管理员独立添加/更新命令(含Choices)的需求,全程无需操作代码或Git。
内容的提问来源于stack exchange,提问作者LosmiNCL
相关产品推荐
相关产品推荐

