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

discord.py中如何在@tasks.loop()里无需on_message变量发送消息

问题核心原因

你在机器人还未完成登录、内部缓存未加载的阶段就调用client.get_channel()获取频道对象,此时拿到的channel值为None,调用None.send()自然会抛出属性错误,这是你发送消息失败的根本原因。

修复方案

  1. 将频道获取逻辑移到on_ready事件中,确保机器人登录完成、资源加载完毕后再获取频道对象
  2. 补充缺失的discord导入和新版discord.py要求的权限声明(intents)
  3. 循环任务可直接在on_ready中启动,完全不需要依赖on_message的消息变量

修正后完整代码

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

token = os.environ['goofyToken']
# 替换为你实际的频道ID
CHANNEL_ID = 替换为你的数字频道ID

# 新版discord.py需要显式声明intents
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)

# 先初始化频道变量
channel = None

@client.event
async def on_ready():
    global channel
    # 登录完成后再获取频道
    channel = client.get_channel(CHANNEL_ID)
    print('We have logged in as {0.user}'.format(client))
    # 可直接在此处启动循环任务,不需要等用户发命令,完全不依赖message变量
    # 如果你需要循环定时运行,把count=1改成seconds=你的间隔秒数即可
    myloop.start("初始触发的消息")

# count=1代表只运行一次,需要循环的话改为seconds=间隔秒数
@tasks.loop(count=1)
async def myloop(word):
    if channel is not None:
        await channel.send(word)

@client.event
async def on_message(message):
    msg = message.content
    if msg.startswith('!'):
        message_to_send = 'Hello World!'
        if channel is not None:
            await channel.send(message_to_send)
        # 避免重复启动loop的判断可按需添加
        if not myloop.is_running():
            myloop.start(message_to_send)

keep_alive()
client.run(token)

额外说明

修复后你的循环任务完全独立于on_message事件运行,uptimerobot的ping操作只会触发你keep_alive服务的web请求,不会影响机器人的任务逻辑,也不会出现变量丢失导致循环中断的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 14:21:01