尝试部署 SlashCommands 时出现验证错误

问题描述 投票:0回答:1

我正在尝试为我的不和谐机器人创建一些斜杠命令,但是在尝试部署它们时我无法解决一个问题。我使用 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
node.js discord.js
1个回答
0
投票

这个问题很容易解决。

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);
})
© www.soinside.com 2019 - 2024. All rights reserved.