如何在 discord.py 中将 on_message 与 sqlite3 集成?

Posted

技术标签:

【中文标题】如何在 discord.py 中将 on_message 与 sqlite3 集成?【英文标题】:How to integrate on_message with sqlite3 in discord.py? 【发布时间】:2020-12-18 01:31:00 【问题描述】:

我创建了一个on_message 事件,每当您在特定频道中提及 3 个人时,它都会为您提供角色,现在我正在尝试将其与数据库集成,以便它可以在多个公会中使用。

我写的:

class ScrimsCog(commands.Cog, name='Scrims-Commands') :

        def __init__(self,bot):
            self.bot = bot
    
        @commands.Cog.listener()
        async def on_message(self,message):
            db = sqlite3.connect('main.sqlite')
            cursor = db.cursor()
            cursor.execute(f"SELECT channel_id FROM main WHERE guild_id = message.guild.id")
            result =  cursor.fetchone()
            if result is None:
                return
            else:
                cursor.execute(f"SELECT role FROM main WHERE guild_id = message.guild.id")
                if not channel.id == channel_id:
                    return
                if len(message.mentions) >= 3:
                    await message.add_reaction(emoji="<a:tick:748476262640779276>")
                role = discord.utils.get(message.guild.roles, name=role)
                user = message.author
                await user.add_roles(role)
            await self.bot.process_commands(message)
            

        
        
        @commands.group(invoke_without_command=True)
        async def scrimsmod(self,ctx):
            await ctx.send('Available Setup Commands: \nscrimsmod channel <#channel>\nscrimsmod role  <message>')
        @scrimsmod.command()
        async def channel(self, ctx, channel:discord.TextChannel):
            if ctx.message.author.guild_permissions.manage_messages:
                db = sqlite3.connect('main.sqlite')
                cursor = db.cursor()
                cursor.execute(f"SELECT channel_id FROM main WHERE guild_id = ctx.guild.id")
                result =  cursor.fetchone()
                if result is None:
                    sql = ("INSERT INTO main(guild_id, channel_id) VALUES(?,?)")
                    val = (ctx.guild.id, channel.id)
                    await ctx.send(f" Default Registration Channel has been set to channel.mention")
                elif result is not None:
                    sql = ("UPDATE main SET channel_id = ? WHERE guild_id = ?")
                    val = (channel.id, ctx.guild.id)
                    await ctx.send(f"Default Registration Channel has been updated to channel.mention")
                cursor.execute(sql, val)
                db.commit()
                cursor.close()
                db.close()

        @scrimsmod.command()
        async def role(self, ctx,role: discord.Role):
            if ctx.message.author.guild_permissions.manage_messages:
                db = sqlite3.connect('main.sqlite')
                cursor = db.cursor()
                cursor.execute(f"SELECT role FROM main WHERE guild_id = ctx.guild.id")
                result =  cursor.fetchone()
                if result is None:
                    sql = ("INSERT INTO main(guild_id, role) VALUES(?,?)")
                    val = (ctx.guild.id, role)
                    await ctx.send(f"Default role to give on correct registration have been set to `role`")
                elif result is not None:
                    sql = ("UPDATE main SET role = ? WHERE guild_id = ?")
                    val = (role, ctx.guild.id)
                    await ctx.send(f"Default role to give on correct registration have been updated to  `role`")
                cursor.execute(sql, val)
                db.commit()
                cursor.close()
                db.close()
    

def setup(bot):
    bot.add_cog(ScrimsCog(bot))
    print("Scrims cog is loaded!")

从现在开始,我认为问题出在on_message 部分,channel.idchannel-idrole 未定义,但即使我定义了它们,它仍然不起作用。

【问题讨论】:

有什么问题? 我不知道如何定义公会ID,频道ID,然后如何将它们与数据库中的ID匹配,on_message部分抛出所有错误,on_message的简短语法就是所有搞砸了@nurqm 我不确定你想用这段代码做什么。你想给提到 3 个人的用户赋予一个特定的角色,这将适用于每个公会吗?为什么需要数据库? 是的,你是对的,我想为每个提到三个人的用户赋予角色,我需要 db,因为只有当用户在特定频道中提及时才会赋予角色,并且还会赋予特定角色。因此,我必须记录机器人将为该特定公会提供的消息所扮演的角色。 @nurqm 【参考方案1】:

f-string 可能会导致问题,试试这个..

cursor.execute("SELECT channel_id FROM main WHERE guild_id = ?", [message.guild.id])

【讨论】:

【参考方案2】:

首先,如果您在on_message 事件下连接到数据库,这会降低您的机器人的效率。对于其他问题,您必须更改这些命令参数

async def channel(self, ctx, channel):, async def role(self, ctx,role):

而不是这些role: discord.Role channel: discord.TextChannel

那么,当你要调用频道或角色时,必须使用discord.utils.get

频道:

await ctx.send(f"Default Registration Channel has been updated to discord.utils.get(ctx.guild.text_channels, name=channel).mention")

对于角色:

await ctx.send(f"Default role to give on correct registration have been updated to discord.utils.get(ctx.guild.roles, name=role)")

所以当用户使用rolechannel命令时,他们必须写出准确的频道。

当你将频道 ID 与数据库进行比较时,你也可以像这样使用discord.utils.get

channel_in_database = discord.utils.get(ctx.guild.text_channels, name="in here, you need to connect to the database and take the channel name for this guild.")

那么,if not channel_in_database.id == ctx.channel.id:,或者你可以(我不是 100% 确定这会起作用)从数据库中为该公会获取频道名称并执行以下操作:

if "channel name from the database" == ctx.channel.name

如果其中之一提出任何问题,或者如果您仍有未解决的问题,请发表评论

【讨论】:

以上是关于如何在 discord.py 中将 on_message 与 sqlite3 集成?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 discord.py 中将字符串更改为不和谐 id

如何在 discord.py 中将图像裁剪为带有枕头的圆形?

如何在 discord.py 中将 on_message 与 sqlite3 集成?

如何在 Discord Py 中将列表附加并保存到另一个文件中?

如何使用 discord.py 获取所有文本频道?

如何从我的 json 文件中将某些内容打印到不和谐频道中? - 不和谐.py