用于同步双服务器Booster角色的Discord Bot工作异常求助
问题:Discord.js 跨服务器Booster角色同步Bot运行异常
我查阅Discord.js官方文档未找到有效解决方案,尝试多种方法并咨询JS开发者后仍无法定位问题。该Bot基于discord.js开发,功能为同步两个服务器的Booster角色,但运行异常。
原代码
const { Client, GatewayIntentBits } = require("discord.js"); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMembers, ], }); const mainServerId = "998283287481036820"; const subServerId = "1058071888775090256"; const boosterRoleName = "Booster"; client.once("ready", () => { console.log(`Eingeloggt als ${client.user.tag}`); }); client.on("guildMemberUpdate", (oldMember, newMember) => { syncBoosterRole(oldMember, newMember); }); async function syncBoosterRole(oldMember, newMember) { const mainServer = client.guilds.cache.get(mainServerId); const subServer = client.guilds.cache.get(subServerId); const boosterRoleMain = mainServer.roles.cache.find( (role) => role.name === boosterRoleName, ); const boosterRoleSub = subServer.roles.cache.find( (role) => role.name === boosterRoleName, ); if (!boosterRoleMain || !boosterRoleSub) { console.error("Rolle nicht gefunden."); return; } const isBoosterOnMain = oldMember.roles.cache.has(boosterRoleMain.id); const isBoosterOnSub = newMember.roles.cache.has(boosterRoleSub.id); if (isBoosterOnMain && !isBoosterOnSub) { // Wenn auf dem Mainserver die Booster-Rolle hinzugefügt wurde, füge sie dem Subserver hinzu await newMember.roles.add(boosterRoleSub); console.log( `Booster-Rolle zu ${newMember.user.tag} auf dem Subserver hinzugefügt.`, ); } else if (!isBoosterOnMain && isBoosterOnSub) { // Wenn auf dem Mainserver die Booster-Rolle entfernt wurde, entferne sie auch auf dem Subserver await newMember.roles.remove(boosterRoleSub); console.log( `Booster-Rolle von ${newMember.user.tag} auf dem Subserver entfernt.`, ); } } client.login("Gib mir den Token");
问题分析与修复方案
核心问题点
- 成员对象混淆:
guildMemberUpdate事件返回的oldMember/newMember是触发事件服务器的成员,直接用它操作子服务器角色会失败,因为该对象不属于子服务器。 - 事件范围未过滤:未判断事件是否发生在主服务器,子服务器的角色变更也会触发同步逻辑,导致错误。
- 过度依赖缓存:
cache.get()可能获取不到最新的服务器/成员/角色数据,需用fetch()确保数据有效性。 - 无错误捕获:异步操作未加
try/catch,运行时错误无法被捕获和排查。
修复后的代码
const { Client, GatewayIntentBits } = require("discord.js"); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, // 仅保留必要的意图,减少资源占用 ], }); const mainServerId = "998283287481036820"; const subServerId = "1058071888775090256"; const boosterRoleName = "Booster"; client.once("ready", () => { console.log(`登录成功:${client.user.tag}`); }); client.on("guildMemberUpdate", async (oldMember, newMember) => { // 仅处理主服务器的角色变更 if (newMember.guild.id !== mainServerId) return; try { await syncBoosterRole(newMember); } catch (err) { console.error("同步角色时出错:", err); } }); async function syncBoosterRole(mainServerMember) { // 强制获取最新服务器数据,不依赖缓存 const mainServer = await client.guilds.fetch(mainServerId); const subServer = await client.guilds.fetch(subServerId); // 获取主服务器的Booster角色 const boosterRoleMain = mainServer.roles.cache.find( role => role.name === boosterRoleName ); if (!boosterRoleMain) { throw new Error("主服务器未找到Booster角色"); } // 获取子服务器的Booster角色 const boosterRoleSub = subServer.roles.cache.find( role => role.name === boosterRoleName ); if (!boosterRoleSub) { throw new Error("子服务器未找到Booster角色"); } // 判断主服务器成员是否拥有Booster角色 const hasBoosterMain = mainServerMember.roles.cache.has(boosterRoleMain.id); // 获取子服务器中对应的成员(需确保成员已加入子服务器) const subServerMember = await subServer.members.fetch(mainServerMember.user.id).catch(() => null); if (!subServerMember) { console.log(`用户${mainServerMember.user.tag}未加入子服务器,跳过同步`); return; } // 判断子服务器成员当前是否拥有Booster角色 const hasBoosterSub = subServerMember.roles.cache.has(boosterRoleSub.id); // 执行同步逻辑 if (hasBoosterMain && !hasBoosterSub) { await subServerMember.roles.add(boosterRoleSub); console.log(`已为${mainServerMember.user.tag}在子服务器添加Booster角色`); } else if (!hasBoosterMain && hasBoosterSub) { await subServerMember.roles.remove(boosterRoleSub); console.log(`已为${mainServerMember.user.tag}在子服务器移除Booster角色`); } } client.login("你的Bot Token");
额外说明
- 移除了不必要的
GuildMessages和MessageContent意图,仅保留角色同步所需的核心权限。 - 增加了完整的错误捕获机制,便于排查运行时问题。
- 加入了成员未加入子服务器的判断,避免无意义的错误。
内容的提问来源于stack exchange,提问作者Jan V
相关产品推荐
相关产品推荐

