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

Discord Python Bot统计VC停留时长数值减少问题排查

Discord Python Bot 语音频道停留时长统计异常减少修复方案

核心问题原因

  • 两个定时任务存在并发冲突:track_user_time 每60秒执行一次时长累加,update_file 每90秒执行一次文件覆盖写入,两者会在180秒、360秒等公倍数时间点同时触发,容易出现还没完成时长累加就先写入了旧数据的情况,导致时长丢失。
  • 文件操作不规范:读写文件未使用上下文管理器、没有主动关闭文件,缓冲区内容未完全刷入磁盘就结束进程,会导致写入内容不完整,下次启动读取到错误的旧数据。
  • 无异常兜底逻辑:写入文件时直接使用覆盖模式,若写入过程中程序崩溃、断电,会直接清空原有统计数据,无备份恢复能力。
  • 缺少语音状态意图:discord.Intents.default() 默认未开启voice_states权限,无法实时获取语音频道的成员列表,会导致时长统计漏加,累计下来看起来就是时长比实际少。
  • 新用户统计缺失:未加入新用户判断逻辑,首次进入语音频道的用户不会被加入member_info列表,对应时长不会被统计。

优化修复方案

1. 初始化权限与数据结构优化

将列表存储改为字典存储,提升查询效率,避免双层循环逻辑错误,同时开启必要的权限意图:

import os
import discord
from discord.ext import commands, tasks

# 改为字典存储,key为用户ID,value为统计时长
member_info = {}
intents = discord.Intents.default()
intents.members = True
intents.voice_states = True # 新增开启语音状态权限
bot = commands.Bot(command_prefix='$', intents = intents)

2. 启动文件读取逻辑优化

使用with上下文管理器读取文件,增加异常处理:

@bot.event
async def on_ready():
    print("We have logged in as {0.user}".format(bot))
    global member_info
    # 增加文件不存在的异常处理
    try:
        with open("times.txt", "r", encoding="utf-8") as f:
            content = f.readlines()
            for line in content:
                line = line.strip()
                if not line:
                    continue
                uid, times = line.split(", ")
                member_info[int(uid)] = int(times)
    except FileNotFoundError:
        # 文件不存在则初始化空字典
        member_info = {}
    print(member_info)
    track_user_time.start()

3. 时长统计与文件写入逻辑合并

取消独立的update_file定时任务,每次统计完成后写入,避免并发冲突,同时增加新用户判断和备份逻辑:

@tasks.loop(seconds=60)
async def track_user_time():
    global member_info 
    active_members = []
    await bot.wait_until_ready()
    # 采集三个频道的活跃用户
    channel_ids = [868830478705233993, 868835241958182984, 868835476147146752]
    for cid in channel_ids:
        channel = bot.get_channel(cid)
        if not channel:
            continue
        for member in channel.members:
            if member.id not in active_members:
                active_members.append(member.id)
    print(active_members)
    # 累加时长,新用户自动添加
    for uid in active_members:
        if uid in member_info:
            member_info[uid] += 1
        else:
            member_info[uid] = 1
    # 写入文件前先备份旧文件,避免写入失败丢数据
    try:
        if os.path.exists("times.txt"):
            os.replace("times.txt", "times.txt.bak")
        # 写入新数据
        with open("times.txt", "w", encoding="utf-8") as f:
            for uid, times in member_info.items():
                f.write(f"{uid}, {times}\n")
    except Exception as e:
        print(f"写入文件失败: {e}")
    print("时长统计更新完成")

4. 查询逻辑优化

适配字典结构,简化查询代码:

@bot.command()
async def myTime(ctx):
    author = ctx.author.id
    global member_info
    time_spent = member_info.get(author, 0)
    user_days = time_spent // 3600
    user_hours = (time_spent - (user_days*3600)) // 60
    user_minutes = time_spent - (user_days*3600) - (user_hours *60) 
    time_msg = f"""
    Time Spent by: {ctx.author.name}
    Days Spent Studying: {user_days} day(s)
    Hours Spent Studying: {user_hours} hour(s)
    Minutes Spent Studying: {user_minutes} minutes
    """
    await ctx.send(time_msg)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 06:18:03