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

Discord.py命令签名报错排查及定时任务实现求助

报错解决与定时任务实现方案

一、当前报错的修复

1. 事件函数误用命令装饰器

on_ready和on_message是Discord Bot的事件函数,不能用@bot.command()装饰,必须改用@bot.event。原代码把它们当成命令注册,导致参数不匹配触发报错。

2. 命令装饰器语法错误

start_count函数里的@bot.commands()多了个s,正确写法是@bot.command();且装饰器会自动完成命令注册,不需要额外调用bot.add_command(start_count)。

3. 消息作者判断逻辑错误

message.author == bot.id判断无效,应该用message.author == bot.user来识别机器人自身发送的消息。

修复后的基础代码:

from discord.ext import commands
import requests
import discord
import asyncio
from discord.ext import tasks

intents = discord.Intents.all()
bot = commands.Bot(command_prefix="?", intents=intents)

@bot.command()
async def foo(ctx, arg):
    await ctx.send(arg)

@bot.event
async def on_ready():
    print("bot online")

@bot.event
async def on_message(message):
    if message.author == bot.user:
        return
    # 必须保留该行,否则自定义命令会失效
    await bot.process_commands(message)
    if message.content == "ana":
        await message.channel.send("baban")

@bot.command()
async def start_count(ctx):
    key = "some-crypto-shit-api"
    data = requests.get(key)  
    data = data.json()
    price = data["price"]
    coin = data["symbol"]
    await ctx.send(f"{coin} 当前价格: {price}")

bot.run('my_Token')

二、定时任务实现(每n分钟执行特定代码)

使用discord.ext.tasks模块的loop装饰器实现定时任务,步骤如下:

  1. 导入tasks模块:from discord.ext import tasks
  2. 用@tasks.loop(minutes=n)装饰定时任务函数(n为你需要的间隔分钟数)
  3. 在on_ready事件中启动任务,或通过命令触发启动
  4. 可通过全局变量或命令上下文指定消息发送的目标频道

示例代码(以每5分钟查询价格并发送到指定频道为例):

# 全局变量存储目标频道ID,也可通过命令动态设置
target_channel_id = None

@tasks.loop(minutes=5)  # 每5分钟执行一次
async def price_reminder():
    if target_channel_id is None:
        return
    channel = bot.get_channel(target_channel_id)
    if not channel:
        return
    try:
        key = "some-crypto-shit-api"
        data = requests.get(key)  
        data.raise_for_status()  # 捕获请求异常
        data_json = data.json()
        price = data_json["price"]
        coin = data_json["symbol"]
        await channel.send(f"⏰ {coin} 价格提醒: {price}")
    except Exception as e:
        await channel.send(f"价格查询失败: {str(e)}")

@bot.command()
async def start_count(ctx):
    global target_channel_id
    target_channel_id = ctx.channel.id
    # 任务未运行时启动
    if not price_reminder.is_running():
        price_reminder.start()
    await ctx.send("价格提醒已启动,每5分钟发送一次更新!")

@bot.command()
async def stop_count(ctx):
    if price_reminder.is_running():
        price_reminder.stop()
        await ctx.send("价格提醒已停止")
    else:
        await ctx.send("价格提醒未在运行")

注意事项:

  • 定时任务中的网络请求需用try-except捕获异常,避免任务崩溃
  • 若需动态调整间隔,可调用price_reminder.change_interval(minutes=new_n)
  • 需确保开启intents.message_content权限,否则无法读取消息内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 14:56:29