Discord Python计时按钮机器人启动及命令执行报错求助
Discord机器人错误修复方案
错误1:启动时定时任务klok触发TypeError: execute_fetchall() missing 1 required positional argument: 'sql'
原因
aiosqlite API使用错误:不存在db.execute_fetchall()方法,正确流程是通过游标执行SQL后调用fetchall();同时原代码硬编码索引更新数据的逻辑错误,无法适配用户记录的动态变化。
修复步骤
- 使用
async with db.cursor() as cursor获取游标,执行SQL后通过cursor.fetchall()获取查询结果。 - 遍历所有用户记录,判断
NuAanwezig为True时累加AanwezigTime,避免硬编码索引。
错误2:执行!aanwezig命令触发TypeError: to_components() missing 1 required positional argument: 'self'
原因
传递给channel.send的view参数是View类klokken而非类的实例,Discord.py需要View实例生成交互组件;同时类的初始化方法写错为init(),正确构造方法应为__init__()(双下划线)。
修复步骤
- 将
view = klokken改为view = klokken(),创建View类的实例。 - 修正类的初始化方法为标准的
__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
相关产品推荐
相关产品推荐

