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

Discord.js bot如何编写递归异步函数定时拉取API检测新增帖子

Discord Bot 定时拉取API检查新帖解决方案

你遇到的问题核心有两点:一是latest_post变量作用域错误导致每次执行被重置,二是setInterval不适合异步任务容易出现请求堆积。以下是可直接使用的递归异步实现方案:


完整实现代码

const prefix = '你的命令前缀'; // 替换为你的实际命令前缀
const CHECK_INTERVAL = 30 * 1000; // 检查间隔,单位为毫秒,当前为30秒可自行修改
const API_URL = '你的API地址'; // 替换为实际请求的API链接
const NOTIFY_CHANNEL_ID = '你的通知频道ID'; // 替换为要发消息的Discord频道ID

// 将latest_post声明在模块顶层,避免每次执行被重置
let latest_post = 12345; // 初始硬编码的最新帖子uid,首次运行后会自动更新

// 独立异步检查函数
async function checkNewPost() {
  try {
    const response = await fetch(API_URL);
    const body = await response.json(); // 直接用内置json()方法解析,无需手动parse
    const obj = body.data;
    const objId = obj[0].post_id;
    const objAuthor = obj[0].author;
    const objTitle = obj[0].title;

    // 修正原代码笔误:原代码未定义objTopic变量,此处使用取到的objId对比
    if (objId > latest_post) {
      const notifyChannel = client.channels.cache.get(NOTIFY_CHANNEL_ID);
      if (notifyChannel) {
        await notifyChannel.send(`Found a new post by ${objAuthor}: ${objTitle}`);
      }
      // 直接更新顶层变量,不要加var/let/const声明,避免生成局部变量
      latest_post = objId;
    } else {
      const d = new Date();
      const n = d.toLocaleTimeString();
      console.log(`No new posts yet at ${n}`);
    }
  } catch (error) {
    console.error('拉取API出错:', error);
  } finally {
    // 无论请求成功失败,处理完成后间隔指定时间发起下一次检查,避免请求堆积
    setTimeout(checkNewPost, CHECK_INTERVAL);
  }
}

// Bot登录完成后启动轮询任务
client.on('ready', () => {
  console.log(`Bot已登录为 ${client.user.tag}`);
  checkNewPost();
});

// 原有的手动触发命令逻辑可以保留,不影响定时任务运行
client.on('messageCreate', async (message) => {
  if (!message.content.startsWith(prefix) || message.author.bot) return;    
  const args = message.content.slice(prefix.length).split(/ +/);
  const command = args.shift().toLowerCase();
  if (command === 'new') {
    try {
      const response = await fetch(API_URL);
      const body = await response.json();
      const obj = body.data;
      const objId = obj[0].post_id;
      message.channel.send(`当前最新帖子ID为:${objId},已记录的最新ID为:${latest_post}`);
    } catch (error) {
      message.channel.send('Oops, there was an error fetching the API');
      console.log(error);
    }
  }
});

补充说明

  • 如果你希望Bot重启后还能保留上次记录的latest_post值,可以把该值持久化存储到本地JSON文件、数据库中,启动时读取即可,避免每次重启都回到初始硬编码值。
  • 不要把检查间隔设置过短,避免触发API站点的限流规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:45:04