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

使用discord.js实现用户指定频道消息检测功能遇异常求助

解决Discord机器人检测用户24小时未发消息失效的问题

原代码的核心问题

你当前的代码依赖message.channel.messages.cache查找用户消息,但这个缓存只存储机器人启动后该频道接收的新消息,无法获取机器人启动前的历史消息。这会导致两种错误判断:

  1. 用户在机器人启动前24小时内发过消息,代码会误判为“未发消息”;
  2. 用户在机器人启动后没发过消息,代码直接进入判断分支,但实际用户可能之前发过消息只是不在缓存里。

另外,把判断符<改成>后逻辑完全反转:原本是判断“消息时间早于24小时前”,改成>后变成“消息时间晚于24小时前”(即最近24小时内发过消息),只要缓存里有用户的消息就会重复触发私信逻辑,若代码监听了全局message事件,甚至会形成循环,导致无限发送。

修复方案:主动获取完整历史消息

要正确检测用户24小时内的消息,必须通过channel.messages.fetch()主动拉取频道历史消息,而非依赖缓存。以下是修正后的代码:

// 替换为你要检测的指定频道ID
const TARGET_CHANNEL_ID = '你的频道ID';

async function checkUserRecentMessage(interactionOrMessage) {
  const targetChannel = interactionOrMessage.guild.channels.cache.get(TARGET_CHANNEL_ID);
  if (!targetChannel) {
    console.error('指定频道不存在');
    return false;
  }

  const twentyFourHoursAgo = Date.now() - 24 * 3600 * 1000;
  let userHasRecentMessage = false;
  let lastFetchedMessageId = null;

  // 分页获取历史消息,直到找到用户消息或超出24小时范围
  try {
    while (true) {
      const fetchOptions = { limit: 100 };
      if (lastFetchedMessageId) fetchOptions.before = lastFetchedMessageId;

      const messages = await targetChannel.messages.fetch(fetchOptions);
      if (messages.size === 0) break; // 无更多消息可获取

      // 检查当前页是否有用户24小时内发送的消息
      const userRecentMessage = messages.find(msg => 
        msg.author.id === interactionOrMessage.author.id && 
        msg.createdTimestamp >= twentyFourHoursAgo
      );

      if (userRecentMessage) {
        userHasRecentMessage = true;
        break;
      }

      // 当前页最早消息已超出24小时范围,停止查询
      const earliestMessage = messages.last();
      if (earliestMessage.createdTimestamp < twentyFourHoursAgo) break;

      lastFetchedMessageId = earliestMessage.id;
    }
  } catch (error) {
    console.error('获取历史消息失败:', error);
    return false;
  }

  return userHasRecentMessage;
}

// 调用示例(绑定到特定命令或定时任务)
async function handleUserReminder(message) {
  const hasRecentMessage = await checkUserRecentMessage(message);
  if (!hasRecentMessage) {
    try {
      await message.author.send('你在指定频道已经24小时没发消息了,请及时互动!');
      console.log('已向用户发送提醒私信');
    } catch (error) {
      console.error('无法发送私信(用户可能关闭了私信权限):', error);
    }
  }
}

关键注意事项

  • 确保机器人拥有ReadMessageHistory权限,否则无法获取频道历史消息;
  • 避免在全局message事件中直接触发检测逻辑,建议绑定到特定命令(如!check)或定时任务,防止循环触发;
  • 若频道消息量极大,可适当添加延迟(如await new Promise(resolve => setTimeout(resolve, 1000))),避免触发Discord API速率限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 01:40:32