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

如何在外部应用中检测Discord.js机器人的在线状态?

如何在外部应用中检测Discord.js机器人的在线状态?

嘿,我明白你的需求啦——想在自己的状态网站上用JavaScript检测Discord机器人的在线状态,而且不想依赖另一个机器人来做这事,对吧?我给你两个实用的方案,都是可以直接在前端或前后端配合实现的:

方案一:给机器人加健康检查接口

这个思路很直接:让你的Discord机器人启动一个简单的HTTP服务器,对外暴露一个健康检查端点。当机器人在线时,这个端点会返回成功响应;如果机器人离线,请求就会失败。前端只需要定期请求这个端点,就能判断状态了。

机器人端代码(Node.js + Discord.js)

const { Client, GatewayIntentBits } = require('discord.js');
const http = require('http');

// 初始化Discord客户端
const client = new Client({ intents: [GatewayIntentBits.Guilds] });

// 启动HTTP服务器处理健康检查请求
const healthServer = http.createServer((req, res) => {
  // 只处理/health路径的请求
  if (req.url === '/health') {
    // 检查机器人是否已登录就绪
    if (client.isReady()) {
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ status: 'online' }));
    } else {
      res.writeHead(503, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ status: 'offline' }));
    }
  } else {
    res.writeHead(404);
    res.end();
  }
});

// 监听3001端口(可以自定义,记得在服务器防火墙开放这个端口)
healthServer.listen(3001, () => {
  console.log('健康检查服务已启动,端口3001');
});

// 机器人登录成功后的回调
client.on('ready', () => {
  console.log(`已登录为 ${client.user.tag}`);
});

// 替换成你的机器人TOKEN
client.login('你的机器人TOKEN');

前端状态页面代码

// 检测机器人状态的函数
async function checkBotStatus() {
  const statusElement = document.getElementById('bot-status');
  try {
    // 替换成你的机器人服务器IP和端口
    const response = await fetch('http://你的机器人服务器IP:3001/health');
    if (response.ok) {
      const data = await response.json();
      console.log('机器人状态:', data.status);
      statusElement.textContent = '在线';
      statusElement.style.color = '#2ecc71';
    } else {
      throw new Error('机器人未就绪');
    }
  } catch (error) {
    console.error('状态检测失败:', error);
    statusElement.textContent = '离线';
    statusElement.style.color = '#e74c3c';
  }
}

// 页面加载时检测一次,之后每5分钟轮询一次
window.addEventListener('load', checkBotStatus);
setInterval(checkBotStatus, 5 * 60 * 1000);

方案二:心跳机制(无需开放额外端口)

如果不想给机器人开放额外端口,可以让机器人定期向你的状态页面后端发送“心跳”请求,后端记录最后一次心跳的时间。前端通过查询后端接口,判断最后一次心跳是否在合理时间内(比如10分钟),来确定机器人是否在线。

机器人端心跳代码

const { Client, GatewayIntentBits } = require('discord.js');
const axios = require('axios');

const client = new Client({ intents: [GatewayIntentBits.Guilds] });

// 发送心跳到状态页面后端的函数
async function sendHeartbeat() {
  try {
    // 替换成你的状态页面后端接口地址
    await axios.post('https://你的状态页面域名/api/bot-heartbeat', {
      botId: client.user.id
    });
    console.log('心跳发送成功');
  } catch (error) {
    console.error('心跳发送失败:', error);
  }
}

client.on('ready', () => {
  console.log(`已登录为 ${client.user.tag}`);
  // 登录成功后立即发一次心跳,之后每5分钟发一次
  sendHeartbeat();
  setInterval(sendHeartbeat, 5 * 60 * 1000);
});

client.login('你的机器人TOKEN');

状态页面后端代码(Node.js + Express)

const express = require('express');
const app = express();
app.use(express.json());

// 存储机器人最后一次心跳时间(生产环境建议用数据库持久化)
const botHeartbeats = {};

// 接收机器人心跳的接口
app.post('/api/bot-heartbeat', (req, res) => {
  const { botId } = req.body;
  botHeartbeats[botId] = Date.now();
  res.status(200).json({ success: true });
});

// 提供给前端查询状态的接口
app.get('/api/bot-status', (req, res) => {
  const { botId } = req.query;
  const lastHeartbeat = botHeartbeats[botId];
  
  if (!lastHeartbeat) {
    return res.json({ status: 'offline' });
  }
  
  // 判断最后一次心跳是否在10分钟内(600000毫秒)
  const isOnline = Date.now() - lastHeartbeat < 600000;
  res.json({ status: isOnline ? 'online' : 'offline' });
});

app.listen(3000, () => {
  console.log('状态页面后端服务已启动,端口3000');
});

前端状态页面代码

async function checkBotStatus() {
  const statusElement = document.getElementById('bot-status');
  try {
    // 替换成你的后端接口地址和机器人ID
    const response = await fetch('https://你的状态页面域名/api/bot-status?botId=你的机器人ID');
    const data = await response.json();
    
    if (data.status === 'online') {
      statusElement.textContent = '在线';
      statusElement.style.color = '#2ecc71';
    } else {
      statusElement.textContent = '离线';
      statusElement.style.color = '#e74c3c';
    }
  } catch (error) {
    console.error('状态检测失败:', error);
    statusElement.textContent = '离线';
    statusElement.style.color = '#e74c3c';
  }
}

window.addEventListener('load', checkBotStatus);
setInterval(checkBotStatus, 5 * 60 * 1000);

一些注意事项

  • 方案一要确保机器人服务器的端口已在防火墙/安全组中开放,如果需要HTTPS,可以用Nginx反向代理配置证书。
  • 方案二的后端心跳记录如果用内存存储,重启后端会丢失数据,生产环境建议用SQLite、MongoDB等数据库持久化。
  • 绝对不要把机器人的TOKEN暴露在前端代码里,所有涉及TOKEN的操作都要在机器人端或后端完成。

备注:内容来源于stack exchange,提问作者Tuggummi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 06:59:50