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

为什么我的Discord机器人无法发送每日定时消息?

问题根因

你遇到的AttributeError: 'NoneType' object has no attribute 'send'报错,核心原因是后台任务执行时Discord客户端还没有完成登录初始化,内部的频道缓存还未加载完成,所以client.get_channel(channel_id)调用返回了None,后续调用send方法自然触发空对象属性错误。
你把对应代码放到on_ready()中可以正常运行,也能佐证这个判断:on_ready()是Discord客户端完全登录、资源加载完毕后才会触发的事件,这时候调用get_channel()可以正常获取到频道对象。

修复方案

核心调整点

  1. 调整后台任务的启动时机,不要在client.run()之前创建任务,改为在on_ready()事件中启动,保证客户端初始化完成后再执行逻辑
  2. 增加空值校验作为兜底容错,避免因为频道ID错误、机器人未加入对应频道等其他异常场景导致崩溃
  3. 将background_task()的递归调用改为无限循环,避免长时间运行出现栈溢出风险

修复后完整代码示例

import os
import discord
import requests
import json
import asyncio

channel_id = 791884298810163200
# 补全客户端初始化逻辑,注意根据你的需求调整intents权限
client = discord.Client(intents=discord.Intents.default())

def get_quote():
    response = requests.get("https://zenquotes.io/api/random")
    json_data = json.loads(response.text)
    quote = json_data[0]["q"] + " -" + json_data[0]["a"]
    return quote

async def sendQuote():
    channel = client.get_channel(channel_id)
    # 增加空值判断兜底
    if not channel:
        print(f"无法获取ID为{channel_id}的频道,请检查ID是否正确、机器人是否拥有该频道访问权限")
        return
    await channel.send(get_quote())

async def background_task():
    # 替换递归为无限循环,避免栈溢出
    while True:
        # 后续可在此处添加上午8点判断逻辑
        await sendQuote()
        # 测试阶段用5秒,上线后替换为86400(24小时对应的秒数)
        await asyncio.sleep(5)

@client.event
async def on_ready():
    print(f"登录成功,当前账号为:{client.user}")
    # 客户端初始化完成后再启动后台任务
    client.loop.create_task(background_task())

if __name__ == "__main__":
    # 补全你的机器人token获取逻辑
    my_secret = os.getenv("DISCORD_BOT_TOKEN")
    keep_alive()
    client.run(my_secret)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 22:27:03