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

Discord Python计时按钮机器人启动及命令执行报错求助

Discord机器人错误修复方案

错误1:启动时定时任务klok触发TypeError: execute_fetchall() missing 1 required positional argument: 'sql'

原因

aiosqlite API使用错误:不存在db.execute_fetchall()方法,正确流程是通过游标执行SQL后调用fetchall();同时原代码硬编码索引更新数据的逻辑错误,无法适配用户记录的动态变化。

修复步骤

  1. 使用async with db.cursor() as cursor获取游标,执行SQL后通过cursor.fetchall()获取查询结果。
  2. 遍历所有用户记录,判断NuAanwezig为True时累加AanwezigTime,避免硬编码索引。

错误2:执行!aanwezig命令触发TypeError: to_components() missing 1 required positional argument: 'self'

原因

传递给channel.send的view参数是View类klokken而非类的实例,Discord.py需要View实例生成交互组件;同时类的初始化方法写错为init(),正确构造方法应为__init__()(双下划线)。

修复步骤

  1. 将view = klokken改为view = klokken(),创建View类的实例。
  2. 修正类的初始化方法为标准的__init__格式。

其他问题修复

  • 将定时任务klok从View类中移出至全局作用域,避免实例依赖问题。
  • 统一数据库字段名:将AanwezigTijd改为AanwezigTime,与表结构定义一致。
  • 替换过时的client.send_message方法为channel.send。
  • 移除不必要的全局变量,直接从数据库读取用户数据。
  • 修复on_ready中过早关闭数据库连接的问题,改为每次操作时重新连接(更安全的短连接模式)。
  • 添加用户初始化逻辑,确保目标用户存在于数据库表中。

修正后的完整代码

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

intent = discord.Intents.default()
intent.members = True
intent.message_content = True

client = commands.Bot(command_prefix='!', intents=intent)

# 定时任务:每分钟更新在线用户的时长
@tasks.loop(seconds=60)
async def klok():
    async with aiosqlite.connect("Aanwezigheid.db") as db:
        async with db.cursor() as cursor:
            # 获取所有用户的ID、当前状态和时长
            await cursor.execute("SELECT User, NuAanwezig, AanwezigTime FROM Aanwezigheid")
            users = await cursor.fetchall()
            
            # 遍历用户,在线则累加时长
            for user in users:
                user_id, is_present, current_time = user
                if is_present:
                    await cursor.execute(
                        "UPDATE Aanwezigheid SET AanwezigTime = ? WHERE User = ?",
                        (current_time + 1, user_id)
                    )
            await db.commit()

class klokken(discord.ui.View):
    def __init__(self, *, timeout=None):
        super().__init__(timeout=timeout)

    # 更新在线状态消息
    async def messageupdate(self, interaction: discord.Interaction):
        async with aiosqlite.connect("Aanwezigheid.db") as db:
            async with db.cursor() as cursor:
                await cursor.execute("SELECT User, NuAanwezig FROM Aanwezigheid")
                aanwezig_data = await cursor.fetchall()
        
        # 整理用户状态映射
        status_map = {user[0]: user[1] for user in aanwezig_data}
        await interaction.message.delete()
        channel = client.get_channel(945349385997398037)
        
        embed = discord.Embed(
            title="Aanwezig in winkel",
            description="Klik op de emoji zodra je in de winkel staat en klik er nog een keer op als je weg gaat uit winkel",
            color=0x0ad6ff
        )
        embed.set_author(name="Daily Firework")
        # 替换为实际用户ID
        embed.add_field(name="IamKiaran", value=status_map.get(1234567890, False), inline=False)
        embed.add_field(name="GwnDaan_", value=status_map.get(9876543210, False), inline=False)
        embed.add_field(name="hamburger7439", value=status_map.get(1122334455, False), inline=False)
        
        await channel.send(embed=embed, view=klokken())

    # 设置用户为在线
    async def aanwezig(self, interaction: discord.Interaction):
        async with aiosqlite.connect("Aanwezigheid.db") as db:
            async with db.cursor() as cursor:
                await cursor.execute(
                    "UPDATE Aanwezigheid SET NuAanwezig = ? WHERE User = ?",
                    (True, interaction.user.id)
                )
                await db.commit()
        await self.messageupdate(interaction)

    # 设置用户为离线
    async def afwezig(self, interaction: discord.Interaction):
        async with aiosqlite.connect("Aanwezigheid.db") as db:
            async with db.cursor() as cursor:
                await cursor.execute(
                    "UPDATE Aanwezigheid SET NuAanwezig = ? WHERE User = ?",
                    (False, interaction.user.id)
                )
                await db.commit()
        await self.messageupdate(interaction)

    # 在线按钮
    @discord.ui.button(
        label="Aanwezig", 
        emoji="✅", 
        style=discord.ButtonStyle.green,
        custom_id="aanwezig_button"
    )
    async def aanwezig_button(self, button: discord.ui.Button, interaction: discord.Interaction):
        await self.aanwezig(interaction)

    # 离线按钮
    @discord.ui.button(
        label="Afwezig", 
        emoji="✖️", 
        style=discord.ButtonStyle.red, 
        custom_id="afwezig_button"
    )
    async def afwezig_button(self, button: discord.ui.Button, interaction: discord.Interaction):
        await self.afwezig(interaction)

# 发送在线状态面板命令
@client.command()
async def aanwezig(ctx):
    channel = client.get_channel(945349385997398037)
    # 初始获取用户状态
    async with aiosqlite.connect("Aanwezigheid.db") as db:
        async with db.cursor() as cursor:
            await cursor.execute("SELECT User, NuAanwezig FROM Aanwezigheid")
            aanwezig_data = await cursor.fetchall()
    
    status_map = {user[0]: user[1] for user in aanwezig_data}
    embed = discord.Embed(
        title="Aanwezig in winkel",
        description="Klik op de emoji zodra je in de winkel staat en klik er nog een keer op als je weg gaat uit winkel",
        color=0x0ad6ff
    )
    embed.set_author(name="Daily Firework")
    # 替换为实际用户ID
    embed.add_field(name="IamKiaran", value=status_map.get(1234567890, False), inline=False)
    embed.add_field(name="GwnDaan_", value=status_map.get(9876543210, False), inline=False)
    embed.add_field(name="hamburger7439", value=status_map.get(1122334455, False), inline=False)
    
    await channel.send(embed=embed, view=klokken())

# 重置时长命令
@client.command()
@commands.is_owner()
async def Tijdreset(ctx):
    async with aiosqlite.connect("Aanwezigheid.db") as db:
        async with db.cursor() as cursor:
            await cursor.execute("SELECT User, AanwezigTime FROM Aanwezigheid")
            tijden = await cursor.fetchall()
            await cursor.execute("UPDATE Aanwezigheid SET AanwezigTime = 0")
            await db.commit()
    
    time_map = {user[0]: user[1] for user in tijden}
    embed = discord.Embed(
        title="Aanwezigheid in winkel",
        description="De tijden die de medewerkers in de afgelopen dagen hebben gewerkt. Zijn nu gereset naar 0.",
        color=0x0ad6ff
    )
    embed.set_author(name="Daily Firework")
    # 替换为实际用户ID
    embed.add_field(name="IamKiaran", value=f"{time_map.get(1234567890, 0)} minuten aanwezig", inline=False)
    embed.add_field(name="GwnDaan_", value=f"{time_map.get(9876543210, 0)} minuten aanwezig", inline=False)
    embed.add_field(name="hamburger7439", value=f"{time_map.get(1122334455, 0)} minuten aanwezig", inline=False)
    
    channel = client.get_channel(945349385997398037)
    await channel.send(embed=embed)

@client.event
async def on_ready():
    # 初始化数据库表和用户
    async with aiosqlite.connect("Aanwezigheid.db") as db:
        async with db.cursor() as cursor:
            await cursor.execute("""
                CREATE TABLE IF NOT EXISTS Aanwezigheid (
                    User INTEGER PRIMARY KEY,
                    NuAanwezig BOOLEAN DEFAULT False,
                    AanwezigTime INTEGER DEFAULT 0
                )
            """)
            # 确保目标用户存在于表中(替换为实际用户ID)
            users_to_add = [1234567890, 9876543210, 1122334455]
            for user_id in users_to_add:
                await cursor.execute("INSERT OR IGNORE INTO Aanwezigheid (User) VALUES (?)", (user_id,))
            await db.commit()
    
    print("Kloksys. De Klok database verbinding gemaakt!")
    print("Bot is currently online!")
    klok.start()

client.run('YOUR_BOT_TOKEN')

注意:请将代码中的用户ID和机器人令牌替换为实际值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:25:35