英文:
Discord.js dynamically add options to slash command with .addChoices()
问题
我有一个需要用户提供3个选择的斜杠命令:team1、team2和游戏数量。我正在将它们作为命令的参数添加,代码如下:
data: new SlashCommandBuilder()
.setName('addgame')
.setDescription('Sets up a game for placing bets.')
.addStringOption(option =>
option.setName('team1')
.setDescription('Team 1')
.setRequired(true)
.addChoices(
{ name: 'Bilibili Gaming', value: 'Bilibili Gaming'},
{ name: 'JDG Gaming', value: 'JDG Gaming'},
{ name: 'Gen.G', value: 'Gen.G'},
{ name: 'T1', value: 'T1'},
{ name: 'Cloud9', value: 'Cloud9'},
{ name: 'Golden Guardians', value: 'Golden Guardians'},
{ name: 'G2 Esports', value: 'G2 Esports'},
))
.addStringOption(option =>
option.setName('team2')
.setDescription('Team 2')
.setRequired(true)
.addChoices(
{ name: 'Bilibili Gaming', value: 'Bilibili Gaming'},
{ name: 'JDG Gaming', value: 'JDG Gaming'},
{ name: 'Gen.G', value: 'Gen.G'},
{ name: 'T1', value: 'T1'},
{ name: 'Cloud9', value: 'Cloud9'},
{ name: 'Golden Guardians', value: 'Golden Guardians'},
{ name: 'G2 Esports', value: 'G2 Esports'},
))
.addStringOption(option =>
option.setName('series')
.setDescription('Number of games')
.setRequired(true)
.addChoices(
{ name: '1', value: '1'},
{ name: '3', value: '3'},
{ name: '5', value: '5'},
)),
async execute(interaction) {
// Set up team information
const teamList = await getTeams();
const team1 = interaction.options.getString('team1');
const team2 = interaction.options.getString('team2');
...
这里的.addChoices()
属性不仅多余且难以维护,而且我稍后在斜杠命令中使用getTeams()
函数从数据库中获取相同的值。我想知道如何调用getTeams
异步函数并使用结果填充addChoices()
?
我可以这样做:
const teamList = await getTeams();
const choices = teamList.map(team => ({ name: team.name, value: team.value }));
...
.addChoices(...choices)
然而,由于getTeams()
是一个异步函数,我不能在async execute(interaction)
方法之外使用await
。
我想做的事情是否不可能?如果我必须重新构造斜杠命令来实现这一点,那会是什么样子?任何建议都将不胜感激。
编辑:
我甚至尝试在我的index.js中做这样的事情:
async function fetchTeamList() {
const teamList = await getTeams();
const teams = teamList.map(team => ({ name: team.Name, value: team.Name }));
return teams;
}
...
fetchTeamList().then(teams => {
console.log(teams);
module.exports.teams = teams;
});
然后在我的斜杠命令文件中导入teams
,但这也不起作用。我不确定我想做的事情是否可能...
使用Node.js v18.17.0和discord.js: ^14.11.0
编辑:
我也尝试过这样做:
data: new SlashCommandBuilder()
.setName('addgame')
.setDescription('Sets up a game for placing bets.')
.addStringOption(async option =>{
const teamList = await getTeams();
const choices = teamList.map(team => ({ name: team.name, value: team.value }));
return option
.setName('team1')
.setDescription('Team 1')
.setRequired(true)
.addChoices(...choices)
})
这是根据一个答案中的建议,但这会引发与@sapphire/shapeshif
包相关的错误。我认为这不起作用是因为我在addStringOption
中使用了一个异步回调来动态获取团队选择,但后续的选项是同步添加的...这可能会引发问题。
英文:
I have a slash command that requires 3 choices from the user: team1, team2, and how many games. I'm adding those as parameters for the command like this:
data: new SlashCommandBuilder()
.setName('addgame')
.setDescription('Sets up a game for placing bets.')
.addStringOption(option =>
option.setName('team1')
.setDescription('Team 1')
.setRequired(true)
.addChoices(
{ name: 'Bilibili Gaming', value: 'Bilibili Gaming'},
{ name: 'JDG Gaming', value: 'JDG Gaming'},
{ name: 'Gen.G', value: 'Gen.G'},
{ name: 'T1', value: 'T1'},
{ name: 'Cloud9', value: 'Cloud9'},
{ name: 'Golden Guardians', value: 'Golden Guardians'},
{ name: 'G2 Esports', value: 'G2 Esports'},
))
.addStringOption(option =>
option.setName('team2')
.setDescription('Team 2')
.setRequired(true)
.addChoices(
{ name: 'Bilibili Gaming', value: 'Bilibili Gaming'},
{ name: 'JDG Gaming', value: 'JDG Gaming'},
{ name: 'Gen.G', value: 'Gen.G'},
{ name: 'T1', value: 'T1'},
{ name: 'Cloud9', value: 'Cloud9'},
{ name: 'Golden Guardians', value: 'Golden Guardians'},
{ name: 'G2 Esports', value: 'G2 Esports'},
))
.addStringOption(option =>
option.setName('series')
.setDescription('Number of games')
.setRequired(true)
.addChoices(
{ name: '1', value: '1'},
{ name: '3', value: '3'},
{ name: '5', value: '5'},
)),
async execute(interaction) {
// Set up team information
const teamList = await getTeams();
const team1 = interaction.options.getString('team1');
const team2 = interaction.options.getString('team2');
...
Not only are the .addChoices()
properties redundant here and harder to maintain, but I actually get those same values from the database later in the slash command using a getTeams()
function. I'm wondering how I could call that getTeams
async function and use the result to populate addChoices()
?
I could do something like this:
const teamList = await getTeams();
const choices = teamList.map(team => ({ name: team.name, value: team.value }));
...
.addChoices(...choices)
However, because getTeams()
is an async function I can't use await
outside of the async execute(interaction)
method.
Is what I'm wanting to do not possible? If I had to restructure the slash command to achieve this, what would that look like? Any advice appreciated.
EDIT:
I even tried doing something like this in my index.js:
async function fetchTeamList() {
const teamList = await getTeams();
const teams = teamList.map(team => ({ name: team.Name, value: team.Name }));
return teams;
}
...
fetchTeamList().then(teams => {
console.log(teams);
module.exports.teams = teams;
});
And then importing teams
in my slash command file but that didn't work either. I'm not sure that what I'm trying to do is possible...
Using Node.js v18.17.0 and discord.js: ^14.11.0
EDIT:
I have tried this as well:
data: new SlashCommandBuilder()
.setName('addgame')
.setDescription('Sets up a game for placing bets.')
.addStringOption(async option =>{
const teamList = await getTeams();
const choices = teamList.map(team => ({ name: team.name, value: team.value }));
return option
.setName('team1')
.setDescription('Team 1')
.setRequired(true)
.addChoices(...choices)
})
As was recommended in an answer but this throws an error dealing with the ```@sapphire/shapeshifpackage. I believe this isn't working because I'm using an asynchronous callback for
addStringOption```` to fetch the team choices dynamically but the subsequent options are added synchronously... which might cause a problem?
答案1
得分: 1
你可以将addStringOption函数设置为异步函数,并在函数内部获取团队信息,代码如下所示:
.addStringOption(async option => {
const teamList = await getTeams();
const choices = teamList.map(team => ({ name: team.name, value: team.value }));
return option
.setName('team1')
.setDescription('Team 1')
.setRequired(true)
.addChoices(...choices)
})
英文:
You can make the addStringOpton function async and get the teams inside the function like this
.addStringOption(async option => {
const teamList = await getTeams();
const choices = teamList.map(team => ({ name: team.name, value: team.value }));
return option
.setName('team1')
.setDescription('Team 1')
.setRequired(true)
.addChoices(...choices)
}),
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论