使用Discord.js斜杠命令处理器时遇405 Method Not Allowed错误求助
Discord.js v13.11.0 斜杠命令权限设置触发405 Method Not Allowed错误
使用Discord.js v13.11.0开发机器人,机器人在目标服务器已拥有管理员权限,但在设置斜杠命令权限时触发405: Method Not Allowed错误,错误发生在调用guild.commands.permissions.set()时。
命令加载文件
const { glob } = require("glob"); const { promisify } = require("util"); const { Client } = require("discord.js"); const mongoose = require("mongoose"); const globPromise = promisify(glob); /** * @param {Client} client */ module.exports = async (client) => { // Commands const commandFiles = await globPromise(`${process.cwd()}/commands/**/*.js`); commandFiles.map((value) => { const file = require(value); const splitted = value.split("/"); const directory = splitted[splitted.length - 2]; if (file.name) { const properties = { directory, ...file }; client.commands.set(file.name, properties); } }); // Events const eventFiles = await globPromise(`${process.cwd()}/events/*.js`); eventFiles.map((value) => require(value)); // Slash Commands const slashCommands = await globPromise( `${process.cwd()}/SlashCommands/*/*.js` ); const arrayOfSlashCommands = []; slashCommands.map((value) => { const file = require(value); if (!file?.name) return; client.slashCommands.set(file.name, file); if (["MESSAGE", "USER"].includes(file.type)) delete file.description; if (file.userPermissions) file.defaultPermission = false; arrayOfSlashCommands.push(file); }); client.on("ready", async () => { // Register for a single guild const guild = client.guilds.cache.get("1014471738844790844"); await guild.commands.set(arrayOfSlashCommands).then((cmd) => { const getRoles = (commandName) => { const permissions = arrayOfSlashCommands.find((x) => x.name === commandName).userPermissions; if (!permissions) return null; return guild.roles.cache.filter(x => x.permissions.has(permissions) && !x.managed); }; const fullPermissions = cmd.reduce((accumulator, x) => { const roles = getRoles(x.name); if (!roles) return accumulator; const permissions = roles.reduce((a, v) => { return [ ...a, { id: v.id, type: 'ROLE', permission: true, } ]; }, []); return [ ...accumulator, { id: x.id, permission: permissions, } ]; }, []); guild.commands.permissions.set({ fullPermissions }); }); // Register for all the guilds the bot is in // await client.application.commands.set(arrayOfSlashCommands); }); // mongoose const { mongooseConnectionString } = require('../config.json') if (!mongooseConnectionString) return; mongoose.connect(mongooseConnectionString).then(() => console.log('Connected to mongodb')); };
interactionCreate.js 文件
const client = require("../index"); client.on("interactionCreate", async (interaction) => { // Slash Command Handling if (interaction.isCommand()) { await interaction.deferReply({ ephemeral: false }).catch(() => { }); const cmd = client.slashCommands.get(interaction.commandName); if (!cmd) return interaction.followUp({ content: "An error has occurred " }); const args = []; for (let option of interaction.options.data) { if (option.type === "SUB_COMMAND") { if (option.name) args.push(option.name); option.options?.forEach((x) => { if (x.value) args.push(x.value); }); } else if (option.value) args.push(option.value); } interaction.member = interaction.guild.members.cache.get(interaction.user.id); if (!interaction.member.permissions.has(cmd.userPermissions || [])) return interaction.followUp({ content: `Error: Mission Permissions.` }); cmd.run(client, interaction, args); } // Context Menu Handling if (interaction.isContextMenu()) { await interaction.deferReply({ ephemeral: false }); const command = client.slashCommands.get(interaction.commandName); if (command) command.run(client, interaction); } });
错误日志
C:\Users\pines\OneDrive\桌面\ROBO_Head-v2\node_modules\discord.js\src\rest\RequestHandler.js:350 throw new DiscordAPIError(data, res.status, request); ^ DiscordAPIError: 405: Method Not Allowed at RequestHandler.execute (C:\Users\pines\OneDrive\桌面\ROBO_Head-v2\node_modules\discord.js\src\rest\RequestHandler.js:350:13) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async RequestHandler.push (C:\Users\pines\OneDrive\桌面\ROBO_Head-v2\node_modules\discord.js\src\rest\RequestHandler.js:51:14) at async ApplicationCommandPermissionsManager.set (C:\Users\pines\OneDrive\桌面\ROBO_Head-v2\node_modules\discord.js\src\managers\ApplicationCommandPermissionsManager.js:186:18) { method: 'put', path: '/applications/991997852538634311/guilds/1014471738844790844/commands/permissions', code: 0, httpStatus: 405, requestData: { json: [], files: [] } }
问题原因
- 参数字段拼写错误:构建权限规则时,将
permissions误写为permission,导致API无法识别有效数据。 - 空数组请求:当所有命令都未配置
userPermissions时,fullPermissions为空数组,调用set()方法会触发无效请求,返回405错误。
修复方案
修改命令加载文件中ready事件内的权限设置逻辑:
client.on("ready", async () => { // Register for a single guild const guild = client.guilds.cache.get("1014471738844790844"); await guild.commands.set(arrayOfSlashCommands).then((cmd) => { const getRoles = (commandName) => { const permissions = arrayOfSlashCommands.find((x) => x.name === commandName).userPermissions; if (!permissions) return null; return guild.roles.cache.filter(x => x.permissions.has(permissions) && !x.managed); }; const fullPermissions = cmd.reduce((accumulator, x) => { const roles = getRoles(x.name); // 过滤无符合条件角色的命令 if (!roles || roles.size === 0) return accumulator; const permissions = roles.reduce((a, v) => { return [ ...a, { id: v.id, type: 'ROLE', permission: true, } ]; }, []); return [ ...accumulator, { id: x.id, permissions: permissions, // 修正字段名 } ]; }, []); // 仅当存在有效权限规则时执行设置 if (fullPermissions.length > 0) { guild.commands.permissions.set({ fullPermissions }); } }); // Register for all the guilds the bot is in // await client.application.commands.set(arrayOfSlashCommands); });
额外检查项
- 确认机器人OAuth2授权链接包含
applications.commands权限。 - 验证服务器内机器人的管理员权限未被角色层级或频道权限限制。
内容的提问来源于stack exchange,提问作者Squl032
相关产品推荐
相关产品推荐

