discord.js Bot如何检测单服权限 避免fetchInvites触发Missing Access崩溃
实现方案
你可以通过提前权限校验+异步错误捕获的双重逻辑实现单服务器跳过,避免全局崩溃,具体修改如下:
1. 核心逻辑说明
- 首先校验Bot在当前服务器是否拥有
MANAGE_GUILD(管理服务器)权限,这是调用guild.fetchInvites()的必要权限,不需要更高的Administrator权限 - 给异步请求添加错误捕获,就算权限校验漏判也能接住
Missing Access等异常,直接跳过当前服务器 - 所有错误都在单服务器处理逻辑内部消化,不会向上抛出导致程序崩溃
2. 修改后完整代码
// discord.js v14版本导入,v13版本改为引入Permissions即可 const { PermissionsBitField } = require('discord.js'); module.exports = (client) => { const invites = {} // { guildId: { memberId: count } } const db = require("quick.db") // 原参数中的message未使用,可以直接删除 const getInviteCounts = async (guild) => { return await new Promise((resolve) => { // 第一步:提前校验Bot的权限 const botMember = guild.members.me; if (!botMember.permissions.has(PermissionsBitField.Flags.ManageGuild)) { console.log(`跳过服务器${guild.name}(${guild.id}):缺少管理服务器权限`); // 无权限直接返回空对象,不抛出错误 return resolve({}); } // 第二步:给邀请接口添加错误捕获,兜底处理所有异常 guild.fetchInvites().then((invites) => { const inviteCounter = {} // { memberId: count } invites.forEach((invite) => { // 跳过无邀请人的特殊邀请链接(如服务器 vanity 链接) if (!invite.inviter) return; const { uses, inviter } = invite const { username, discriminator } = inviter const name = `${username}#${discriminator}` inviteCounter[name] = (inviteCounter[name] || 0) + uses }) resolve(inviteCounter) }).catch(err => { console.log(`获取服务器${guild.name}(${guild.id})邀请数据失败:${err.message}`); // 出错也返回空对象,避免崩溃 resolve({}); }) }) } // 原有遍历所有服务器的逻辑,额外加一层try catch做双保险 client.guilds.cache.forEach(async guild => { try { const guildInvites = await getInviteCounts(guild); invites[guild.id] = guildInvites; // 此处保留你原有存储到数据库等后续逻辑 } catch (err) { console.log(`处理服务器${guild.name}(${guild.id})失败:${err.message}`) } }) }
3. 适配说明
- 若你使用discord.js v13版本,将代码中的
PermissionsBitField替换为Permissions即可 - 若你的Bot确实需要Administrator权限处理其他逻辑,把权限校验的参数改为
PermissionsBitField.Flags.Administrator即可
内容的提问来源于stack exchange,提问作者AminCoder
相关产品推荐
相关产品推荐

