Discord.js命令选项choices超25限制的解决方法咨询
问题
我用Node.js的Discord.js开发Discord机器人,JSON文件里存了30条货币数据。把这些数据作为命令选项的choices时,因为Discord限制choices最多只能有25个,触发了DiscordAPIError[50035]错误。试过排序但没用,求Node.js里的解决办法。
代码示例:
const currencyData = require("../../json/commands/currency.json"); const currencyChocies = currencyData.currency; module.exports = { deleted: false, name: "pricecurrency", description: "Currency Price", type: ApplicationCommandOptionType.String, options: [ { name: "currency", description: "currency name", type: ApplicationCommandOptionType.String, choices: currencyChocies, required: true, }, ], callback: async (client, interaction) => { const currencyName = interaction.options.getString("currency"); try { const data = await fetchCurrencyData("Currency"); const desiredCurrency = data.find( (item) => item.detailsId === currencyName ); if (desiredCurrency) { const chaosEquivalent = desiredCurrency.chaosEquivalent; const currencyTypeName = desiredCurrency.currencyTypeName; interaction.reply( "Name:" + currencyTypeName + " Chaos Price:" + chaosEquivalent ); } else { interaction.reply("Nothing Found Currency"); } } catch (error) { console.log(error); await interaction.reply("API Error"); } }, };
错误信息:
DiscordAPIError[50035]: Invalid Form Body options[0].choices[BASE_TYPE_MAX_LENGTH]: Must be 25 or fewer in length.
DiscordAPIError[50035]: 无效的请求体
options[0].choices[BASE_TYPE_MAX_LENGTH]: 长度必须小于等于25。
解决方案
方法1:用Discord自动补全(Autocomplete)功能
Discord的命令选项支持自动补全,这个功能没有25个选项的限制,用户输入时会实时匹配显示相关结果。修改代码如下:
const currencyData = require("../../json/commands/currency.json"); const currencyList = currencyData.currency; module.exports = { deleted: false, name: "pricecurrency", description: "Currency Price", options: [ { name: "currency", description: "currency name", type: ApplicationCommandOptionType.String, required: true, autocomplete: true, // 开启自动补全 }, ], // 处理自动补全请求 autocomplete: async (interaction) => { const userInput = interaction.options.getFocused(); // 过滤匹配用户输入的货币,转小写避免大小写问题 const matchedCurrencies = currencyList.filter(item => item.name.toLowerCase().includes(userInput.toLowerCase()) ); // 一次最多返回25个结果(Discord自动补全的限制) await interaction.respond(matchedCurrencies.slice(0, 25)); }, callback: async (client, interaction) => { const currencyName = interaction.options.getString("currency"); try { const data = await fetchCurrencyData("Currency"); const desiredCurrency = data.find( (item) => item.detailsId === currencyName ); if (desiredCurrency) { const chaosEquivalent = desiredCurrency.chaosEquivalent; const currencyTypeName = desiredCurrency.currencyTypeName; interaction.reply( `Name: ${currencyTypeName} Chaos Price: ${chaosEquivalent}` ); } else { interaction.reply("Nothing Found Currency"); } } catch (error) { console.log(error); await interaction.reply("API Error"); } }, };
方法2:让用户手动输入,事后验证有效性
去掉choices选项,让用户直接输入货币名称/ID,在回调里先验证输入是否在你的货币列表中:
const currencyData = require("../../json/commands/currency.json"); // 把所有有效的货币ID存到Set里,方便快速验证 const validCurrencyIds = new Set(currencyData.currency.map(item => item.value)); module.exports = { deleted: false, name: "pricecurrency", description: "Currency Price", options: [ { name: "currency", description: "currency name or ID", type: ApplicationCommandOptionType.String, required: true, // 移除choices字段 }, ], callback: async (client, interaction) => { const currencyName = interaction.options.getString("currency"); // 先检查输入是否有效 if (!validCurrencyIds.has(currencyName)) { return interaction.reply("Invalid currency name/ID, please check and try again."); } try { const data = await fetchCurrencyData("Currency"); const desiredCurrency = data.find( (item) => item.detailsId === currencyName ); if (desiredCurrency) { const chaosEquivalent = desiredCurrency.chaosEquivalent; const currencyTypeName = desiredCurrency.currencyTypeName; interaction.reply( `Name: ${currencyTypeName} Chaos Price: ${chaosEquivalent}` ); } else { interaction.reply("Nothing Found Currency"); } } catch (error) { console.log(error); await interaction.reply("API Error"); } }, };
方法3:拆分命令(可选)
如果不想用自动补全或手动输入,可以把货币分成几组(比如常用/稀有),创建多个子命令,每个子命令的choices不超过25个。但这种方法会增加命令数量,灵活性不如前两种。
内容的提问来源于stack exchange,提问作者ayberkgezer
相关产品推荐
相关产品推荐

