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

Discord后台任务读取JSON存储的频道ID发消息报10003未知频道错误

问题根因
  • 内存中的channels字典仅在程序启动时从JSON文件读取一次,后续JSON文件的改动不会自动同步到内存,get_general()始终返回启动时读取到的频道ID
  • chanid在全局作用域仅赋值一次,属于固定常量,运行过程中不会自动更新
  • 频道对象chan仅在循环开始前获取一次,后续ID更新后不会重新拉取有效频道对象
  • 没有捕获发送消息的404异常,频道失效后会直接终止任务,不会触发ID重新读取逻辑
  • 原有循环没有添加等待间隔,会高频重复发送消息直接触发接口限流
修复方案
import json
import asyncio
import discord

try:
    with open("channels.json", 'r') as fp:
        channels = json.load(fp)
except Exception:
    channels = {}

def save_channels():
    with open("channels.json", "w+") as fp:
        json.dump(channels, fp, indent=4)

def get_general():
    # 每次调用都重新读取最新的JSON文件,适配外部修改JSON的场景
    try:
        with open("channels.json", 'r') as fp:
            latest_channels = json.load(fp)
        return latest_channels.get("general", 0)
    except Exception:
        return 0

async def hello_loop():
    await client.wait_until_ready()
    while not client.is_closed():
        # 每次循环都拉取最新ID、获取最新频道对象
        chanid = get_general()
        chan = client.get_channel(chanid)
        if not chan:
            # 频道不存在,等待1分钟后重试
            await asyncio.sleep(60)
            continue
        try:
            msg = 'hello'
            msgsend = await chan.send(msg)
        except discord.errors.NotFound:
            # 频道已失效,等待1分钟后重试
            await asyncio.sleep(60)
            continue
        # 按需求设置发送间隔,示例为1小时发一次
        await asyncio.sleep(3600)

client.loop.create_task(hello_loop())

如果频道ID是本程序内部更新的,不需要每次都读文件,更新channels全局变量后,每次循环调用get_general()拉取最新值即可,可减少IO开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:24:03