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

Discord.JS机器人成员缓存异常求助:仅返回2名成员

Discord机器人提醒系统失效:成员缓存异常与私信发送失败解决方法

核心问题分析

  1. 成员缓存缺失:Discord.js v14及以上版本默认不再自动缓存所有服务器成员,且当服务器成员超过100人时,必须开启「服务器成员特权网关意图」才能获取完整成员列表,否则只能缓存机器人自身和最近互动的成员(比如你自己)。
  2. 代码逻辑缺陷:原代码用forEach结合async/await会导致异步执行混乱,依赖缓存获取成员不可靠,且未处理发送失败的异常情况。
  3. 私信发送限制:用户可能关闭了来自服务器机器人的私信权限,导致发送失败。

具体修复步骤

一、配置网关意图与特权权限

  1. 代码中启用必要意图:初始化Client时添加GuildMembers和DirectMessages意图:
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMembers,
    GatewayIntentBits.DirectMessages
  ]
});
  1. 开启服务器成员特权意图:
    登录Discord开发者平台→进入你的应用→「Bot」页面→找到「Privileged Gateway Intents」,开启Server Members Intent。这是成员超过100人的服务器必须开启的权限,否则无法获取完整成员数据。

二、修复代码异步逻辑与成员获取

原代码的forEach无法正确处理异步操作,且依赖缓存取成员容易失败,改用for...of遍历并直接fetch目标成员:

if (settingsCheck('Reminders') === true) {
  const reminderFiles = fs.readdirSync(`${__dirname}/reminders/`);
  const currentUnix = Math.floor(Date.now() / 1000);
  const targetGuild = client.guilds.cache.get(config.guildID);
  
  if (!targetGuild) {
    console.error('目标服务器不在缓存中');
    return;
  }

  // 用for...of确保异步操作顺序执行
  for (const file of reminderFiles) {
    try {
      const rawData = fs.readFileSync(`${__dirname}/reminders/${file}`);
      const jsonData = JSON.parse(rawData);

      if (jsonData.time < currentUnix) {
        // 直接fetch目标成员,不依赖缓存
        const member = await targetGuild.members.fetch(jsonData.user_id);
        if (!member) {
          console.error(`找不到用户 ${jsonData.user_id}`);
          fs.unlinkSync(`${__dirname}/reminders/${file}`);
          continue;
        }

        // 发送提醒并处理可能的私信权限问题
        await member.send({
          content: `<@${jsonData.user_id}> **SCHEDULED REMINDER**\n<t:${jsonData.time}>: ${jsonData.reminder}`
        });

        fs.unlinkSync(`${__dirname}/reminders/${file}`);
        console.log(`已给用户 ${jsonData.user_id} 发送提醒`);
      }
    } catch (error) {
      console.error(`处理文件 ${file} 出错:`, error);
      // 捕获无法发送私信的错误(用户关闭私信),直接删除文件
      if (error.code === 50007) {
        fs.unlinkSync(`${__dirname}/reminders/${file}`);
      }
    }
  }
}

三、私信发送失败的额外处理

  • 如果遇到50007错误码,说明用户关闭了来自服务器的私信,这种情况下无法强制发送,直接删除对应提醒文件即可。
  • 确认用户确实在目标服务器中,若用户已退出,也会导致无法获取成员和发送私信。

内容的提问来源于stack exchange,提问作者CarterNLong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:32:54