我正在尝试为我的不和谐机器人创建一些斜杠命令,但是在尝试部署它们时我无法解决一个问题。我使用 discord.js 通过
SlashCommandBuilder
创建命令,并通过提供的处理程序 REST
与 Discord 进行通信。
每当我尝试启动机器人时都会收到此错误:
c:\PROJECT_PATH\node_modules\@sapphire\shapeshift\dist\cjs\index.cjs:1469
return value instanceof this.expected ? Result.ok(value) : Result.err(new ExpectedValidationError("s.instance(V)", "Expected", value, this.expected));
^
ExpectedValidationError: Expected
at _InstanceValidator.handle (c:\PROJECT_PATH\node_modules\@sapphire\shapeshift\dist\cjs\index.cjs:1469:75)
at _InstanceValidator.parse (c:\PROJECT_PATH\node_modules\@sapphire\shapeshift\dist\cjs\index.cjs:939:90)
at assertReturnOfBuilder (c:\PROJECT_PATH\node_modules\@discordjs\builders\dist\index.js:1620:53)
at MixedClass._sharedAddOptionMethod (c:\PROJECT_PATH\node_modules\@discordjs\builders\dist\index.js:2382:5)
at MixedClass.addStringOption (c:\PROJECT_PATH\node_modules\@discordjs\builders\dist\index.js:2353:17)
at file:///c:/PROJECT_PATH/commands/utility/command0.js:24:10
at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
at async loadESM (node:internal/process/esm_loader:91:5) {
validator: 's.instance(V)',
given: undefined,
expected: [Function: SlashCommandStringOption]
}
Node.js v18.12.1
据我了解,问题应该出在构建 command0 时的
addStringOption
,但我无法弄清楚验证失败的位置。我确保命令名称满足 Discord 所需的 regex ,并且描述只是一个小字符串,没有任何特殊内容。
此外,我想了解为什么会有
[Function: SlashCommandStringOption]
预期。
这是我的app.js
import { config } from 'dotenv';
import { REST, Routes, Client, Collection, Events, GatewayIntentBits } from 'discord.js';
import { commands } from './commands/commands.js';
config();
const client = new Client({intents: [GatewayIntentBits.GuildMembers, GatewayIntentBits.Guilds]});
client.once(Events.ClientReady, readyClient => {
console.log(`Logged in as ${readyClient.user.tag}`);
});
// Setting up the possible commands of the client
client.commands = new Collection();
for (const name in commands) {
await client.commands.set(name, commands[name].default);
}
const rest = new REST().setToken(process.env.DISCORD_TOKEN);
// Deploy of commands
(async () => {
try {
console.log('Deploying (/) commands');
client.commands.toJSON().forEach(async element => {
const data = await rest.post(
Routes.applicationCommands(process.env.APP_ID),
{
headers: {
'content-type':'application/json',
'Authorization':`Bot ${process.env.DISCORD_TOKEN}`,
},
body: element,
},
);
});
console.log('Depoloyed (/) commands');
} catch (error) {
console.error(error);
}
})();
// Listener that execute interactions
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand()) return;
const command = interaction.client.commands.get(interaction.commandName);
if (!command) {
console.error(`No command matching ${interaction.commandName} found`);
return;
}
try {
await command.execute(interaction);
} catch (error) {
console.error(error);
if (interaction.replied || interaction.deferred) {
await interaction.followUp({content: 'There was an error while executing this command!', ephemeral: true});
} else {
await interaction.reply({content: 'There was an error while executing this command!', ephemeral: true});
}
}
});
client.login(process.env.DISCORD_TOKEN);
export {client};
这是commands.js
import * as command0 from "./utility/command0.js";
import * as comand1 from "./utility/command1.js";
export const commands = {
'command0': command0,
'command1': command1,
};
command0.js
import { SlashCommandBuilder } from "discord.js";
export default {
'data': new SlashCommandBuilder()
.setName('add')
.setNameLocalizations({
it:'aggiungi',
})
.setDescription('Description')
.setDescriptionLocalizations({
it:'Descrizione',
})
.addStringOption(option => {
option.setName('name')
.setNameLocalizations({
it:'nome',
})
.setDescription('Name')
.setDescriptionLocalizations({
it:'Nome',
})
.setRequired(true);
})
.addUserOption(option => {
option.setName('user')
.setNameLocalizations({
it:'utente',
})
.setDescription('User to add')
.setDescriptionLocalizations({
it:'Utente da aggiungere',
})
.setRequired(true);
}),
'execute': async function(interaction) {
// Execute stuff
}
};
如果需要的话,我的项目结构是这样的:
| app.js
|
+---commands
| | commands.js
| |
| \---utility
| command0.js
| command1.js
这个问题很容易解决。
SlashcommandBuilder#add...Option
方法中的lambda函数需要返回修改后的选项对象。所以你要么必须删除花括号:
new SlashCommandBuilder()
.setName('add')
.setNameLocalizations({
it: 'aggiungi',
})
.setDescription('Description')
.setDescriptionLocalizations({
it: 'Descrizione',
})
.addStringOption(option =>
option.setName('name')
.setNameLocalizations({
it: 'nome',
})
.setDescription('Name')
.setDescriptionLocalizations({
it: 'Nome',
})
.setRequired(true)
)
.addUserOption(option =>
option.setName('user')
.setNameLocalizations({
it: 'utente',
})
.setDescription('User to add')
.setDescriptionLocalizations({
it: 'Utente da aggiungere',
})
.setRequired(true)
)
或者在修改
option
实例之前添加 return 语句
new SlashCommandBuilder()
.setName('add')
.setNameLocalizations({
it: 'aggiungi',
})
.setDescription('Description')
.setDescriptionLocalizations({
it: 'Descrizione',
})
.addStringOption(option => {
return option.setName('name')
.setNameLocalizations({
it: 'nome',
})
.setDescription('Name')
.setDescriptionLocalizations({
it: 'Nome',
})
.setRequired(true);
})
.addUserOption(option => {
return option.setName('user')
.setNameLocalizations({
it: 'utente',
})
.setDescription('User to add')
.setDescriptionLocalizations({
it: 'Utente da aggiungere',
})
.setRequired(true);
})