You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用于同步双服务器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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 13:38:22