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

如何使用python脚本检测Discord bot是否处于离线状态

实现Discord Bot离线检测+备机自动拉起的可行方案

以下是两种落地成本低、准确率高的实现思路,可根据你的现有部署条件选择:

方案1:基于心跳上报的高可靠检测方案

该方案准确率最高,不会受Discord官方接口限制影响,适合稳定生产环境使用:

  • 逻辑原理:主服务器运行的Bot每间隔30秒往共享存储内更新最新在线时间戳,备机的检测脚本定期读取该时间戳,若判定超过阈值无更新则自动拉起本地Bot进程
  • 推荐用Redis做共享存储,自带过期时间能力可避免旧状态误判

主Bot端心跳上报代码(基于discord.py)

import discord
from discord.ext import tasks
import redis
import time

# 替换为你自己的Redis连接信息
r = redis.Redis(host='共享Redis服务地址', port=6379, db=0, password='Redis访问密码')
bot = discord.Bot(intents=discord.Intents.all())

@tasks.loop(seconds=30)
async def heartbeat_report():
    # 写入时间戳同时设置5分钟过期,避免主服务挂了残留无效数据
    r.set("discord_bot_last_online", time.time(), ex=300)

@bot.event
async def on_ready():
    heartbeat_report.start()
    print(f"主Bot已登录: {bot.user}")

bot.run("你的Discord Bot Token")

备机检测+拉起脚本

import redis
import time
import subprocess
import os

r = redis.Redis(host='共享Redis服务地址', port=6379, db=0, password='Redis访问密码')
BOT_FILE_PATH = "你备机上存放的Bot启动文件路径,比如./discord_bot.py"
CHECK_INTERVAL = 60
# 离线判定阈值,建议设为2分钟,避免临时网络波动导致误判
OFFLINE_THRESHOLD = 120

def is_local_bot_running():
    # 检测本地是否已经启动了Bot,避免重复拉起多进程
    try:
        return len(subprocess.check_output(["pgrep", "-f", BOT_FILE_PATH]).decode().strip()) > 0
    except subprocess.CalledProcessError:
        return False

while True:
    last_online = r.get("discord_bot_last_online")
    if not last_online or (time.time() - float(last_online)) > OFFLINE_THRESHOLD:
        if not is_local_bot_running():
            print("主Bot判定离线,启动备机Bot")
            subprocess.Popen(["python3", BOT_FILE_PATH], cwd=os.path.dirname(os.path.abspath(__file__)))
    time.sleep(CHECK_INTERVAL)

方案2:无共享存储的简易检测方案

如果不想额外搭建共享存储,可以用Discord状态查询能力实现检测,适合个人小型Bot使用:

  • 逻辑原理:申请一个专门用来做检测的测试Bot,和你要托管的业务Bot加入同一个私有服务器,测试Bot定期查询业务Bot的在线状态,判定离线后直接拉起本地进程
  • 注意需要在Discord开发者后台给测试Bot开启Presence Intent和Server Members Intent权限

备机检测脚本示例

import discord
from discord.ext import tasks
import subprocess
import os

CHECK_BOT_TOKEN = "检测用测试Bot的Token"
TARGET_BOT_ID = 123456789 # 替换为你业务Bot的数字用户ID
GUILD_ID = 987654321 # 替换为两个Bot共同加入的服务器数字ID
BOT_FILE_PATH = "备机上的业务Bot启动文件路径"

intents = discord.Intents.default()
intents.presences = True
intents.members = True
check_bot = discord.Bot(intents=intents)

def is_local_bot_running():
    try:
        return len(subprocess.check_output(["pgrep", "-f", BOT_FILE_PATH]).decode().strip()) > 0
    except subprocess.CalledProcessError:
        return False

@tasks.loop(minutes=1)
async def check_bot_status():
    guild = check_bot.get_guild(GUILD_ID)
    target_member = guild.get_member(TARGET_BOT_ID)
    if target_member.status == discord.Status.offline:
        if not is_local_bot_running():
            print("主Bot判定离线,启动备机Bot")
            subprocess.Popen(["python3", BOT_FILE_PATH], cwd=os.path.dirname(os.path.abspath(__file__)))

@check_bot.event
async def on_ready():
    check_bot_status.start()

check_bot.run(CHECK_BOT_TOKEN)

注意事项

  • 所有方案都必须加本地进程重复启动校验,避免网络波动、接口延迟等情况导致重复拉起多个Bot进程,触发官方限流
  • 可按需扩展告警逻辑,检测到离线时触发Discord私信、邮件等通知,方便你及时排查主服务器故障
  • 担心共享存储单点故障的话,可以同时运行两套检测逻辑做双重校验,降低误判概率
  • 如果业务Bot用了分片、集群部署,需要把所有分片的心跳状态都做上报,避免单分片离线没检测到

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:15:03