首页 > 解决方案 > 不和谐机器人——IndexError:列表索引超出范围

问题描述

我编写了一个不和谐的机器人,当用户对消息下的表情符号做出反应时,它会给他们一个角色。(反应角色)

如果我使用命令 !reactadd 创建一个反应角色,那么机器人会保存它,我可以使用命令 !reactremove 再次删除数据库中的条目。

但是,如果用户对消息下的表情符号做出反应,则用户不会获得角色。

相反,我收到以下错误消息:

Ignoring exception in on_raw_reaction_add
Traceback (most recent call last):
  File "C:\Users\Kai\AppData\Local\Programs\Python\Python37-32\lib\site-packages\discord\client.py", line 270, in _run_event
    await coro(*args, **kwargs)
  File "E:\dev\discord_bot\cogs\reactrole.py", line 24, in on_raw_reaction_add
    role = discord.utils.get(guild.roles, id=int(result[1]['role']))
IndexError: list index out of range

第 34、52 和 62 行也存在同样的问题。机器人找不到数据库条目。我不知道为什么。

完整的源代码:

import re

import discord
from discord.ext import commands


class Reactrole(commands.Cog, name='Reactrole'):
    def __init__(self, bot):
        self.bot = bot

    @commands.Cog.listener()
    async def on_raw_reaction_add(self, reaction):
        guild = self.bot.get_guild(reaction.guild_id)
        user = guild.get_member(reaction.user_id)
        if user == self.bot.user:
            return
        elif not user == self.bot.user:
            if '<:' in str(reaction.emoji):
                guild_id = str(reaction.guild_id)
                message_id = str(reaction.message_id)
                emoji_id = str(reaction.emoji.id)
                result = await self.bot.pg_con.fetch("SELECT emoji, role, message_id, channel_id FROM reactrole WHERE guild_id = $1 and message_id = $2 and emoji = $3", guild_id, message_id, emoji_id)
                if result:
                    role = discord.utils.get(guild.roles, id=int(result[1]['role']))
                    await user.add_roles(role)
                else:
                    return
            elif '<:' not in str(reaction.emoji):
                guild_id = str(reaction.guild_id)
                message_id = str(reaction.message_id)
                emoji_id = str(reaction.emoji)
                result = await self.bot.pg_con.fetch("SELECT emoji, role, message_id, channel_id FROM reactrole WHERE guild_id = $1 and message_id = $2 and emoji = $3", guild_id, message_id, emoji_id)
                if result:
                    role = discord.utils.get(guild.roles, id=int(result[1]['role']))
                    await user.add_roles(role)
                else:
                    return

    @commands.Cog.listener()
    async def on_raw_reaction_remove(self, reaction):
        guild = self.bot.get_guild(reaction.guild_id)
        user = guild.get_member(reaction.user_id)
        if user == self.bot.user:
            return
        elif not user == self.bot.user:
            if '<:' in str(reaction.emoji):
                guild_id = str(reaction.guild_id)
                message_id = str(reaction.message_id)
                emoji_id = str(reaction.emoji.id)
                result = await self.bot.pg_con.fetch("SELECT emoji, role, message_id, channel_id FROM reactrole WHERE guild_id = $1 and message_id = $2 and emoji = $3", guild_id, message_id, emoji_id)
                if result:
                    role = discord.utils.get(guild.roles, id=int(result[1]['role']))
                    await user.remove_roles(role)
                else:
                    return
            elif '<:' not in str(reaction.emoji):
                guild_id = str(reaction.guild_id)
                message_id = str(reaction.message_id)
                emoji_id = str(reaction.emoji)
                result = await self.bot.pg_con.fetch("SELECT emoji, role, message_id, channel_id FROM reactrole WHERE guild_id = $1 and message_id = $2 and emoji = $3", guild_id, message_id, emoji_id)
                if result:
                    role = discord.utils.get(guild.roles, id=int(result[1]['role']))
                    await user.remove_roles(role)
                else:
                    return

    @commands.command()
    @commands.has_permissions(administrator=True)
    async def reactadd(self, ctx, channel: discord.TextChannel, messageid, emoji, role: discord.Role):
        guild_id = str(ctx.guild.id)
        message_id = str(messageid)
        role_id = str(role.id)
        channel_id = str(channel.id)
        emoji_id = str(emoji)
        result = await self.bot.pg_con.fetch("SELECT emoji, role, message_id, channel_id FROM reactrole WHERE guild_id = $1 and message_id = $2", guild_id, message_id)
        if '<:' in emoji:
            emm = re.sub(':.*?:', '', emoji).strip('<>')
            if not result:
                await self.bot.pg_con.execute('INSERT INTO reactrole(emoji, role, message_id, channel_id, guild_id) VALUES($1, $2, $3, $4, $5)', emm, role_id, message_id, channel_id, guild_id)
                msg = await channel.fetch_message(message_id)
                em = self.bot.get_emoji(int(emm))
                await msg.add_reaction(em)
                await ctx.send(embed=discord.Embed(color=discord.Color.green(), description=f"Reactrole wurde erfolgreich für die Rolle {role.mention} eingerichtet!"))
            elif result:
                if not emm in str(result[0]['emoji']) and role_id in str(result[1]['role']):
                    await self.bot.pg_con.execute('INSERT INTO reactrole(emoji, role, message_id, channel_id, guild_id) VALUES($1, $2, $3, $4, $5)', emm, role_id, message_id, channel_id, guild_id)
                    msg = await channel.fetch_message(message_id)
                    em = self.bot.get_emoji(int(emm))
                    await msg.add_reaction(em)
                    await ctx.send(embed=discord.Embed(color=discord.Color.green(), description=f"Reactrole wurde erfolgreich für die Rolle {role.mention} eingerichtet!"))
                else:
                    await ctx.send(embed=discord.Embed(color=discord.Color.red(), description=f'Der React {emoji} oder die Rolle {role.mention} existieren bereits als Reactrole an dieser Nachricht!'))
        elif '<:' not in emoji:
            if not result:
                await self.bot.pg_con.execute('INSERT INTO reactrole(emoji, role, message_id, channel_id, guild_id) VALUES($1, $2, $3, $4, $5)', emoji_id, role_id, message_id, channel_id, guild_id)
                msg = await channel.fetch_message(message_id)
                await msg.add_reaction(emoji)
                await ctx.send(embed=discord.Embed(color=discord.Color.green(), description=f"Reactrole wurde erfolgreich für die Rolle {role.mention} eingerichtet!"))
            elif result:
                if not emoji_id in str(result[0]['emoji']) and role_id in str(result[1]['role']):
                    await self.bot.pg_con.execute('INSERT INTO reactrole(emoji, role, message_id, channel_id, guild_id) VALUES($1, $2, $3, $4, $5)', emoji_id, role_id, message_id, channel_id, guild_id)
                    msg = await channel.fetch_message(message_id)
                    await msg.add_reaction(emoji)
                    await ctx.send(embed=discord.Embed(color=discord.Color.green(), description=f"Reactrole wurde erfolgreich für die Rolle {role.mention} eingerichtet!"))
                else:
                    await ctx.send(embed=discord.Embed(color=discord.Color.red(), description=f'Der React {emoji} oder die Rolle {role.mention} existieren bereits als Reactrole an dieser Nachricht!'))

    @commands.command()
    @commands.has_permissions(administrator=True)
    async def reactremove(self, ctx, messageid, emoji):
        guild_id = str(ctx.guild.id)
        message_id = str(messageid)
        emoji_id = str(emoji)
        if '<:' in emoji:
            emm = re.sub(':.*?:', '', emoji).strip('<>')
            result = await self.bot.pg_con.fetch("SELECT emoji, role, message_id, channel_id FROM reactrole WHERE guild_id = $1 and message_id = $2 and emoji = $3", guild_id, message_id, emm)
            if not result:
                await ctx.send(embed=discord.Embed(color=discord.Color.red(), description=f'Diese Reaction wurde nicht an der Nachricht gefunden!'))
            elif emm in str(result[0]['emoji']):
                await self.bot.pg_con.execute("DELETE FROM reactrole WHERE guild_id = $1 and message_id = $2 and emoji = $3", guild_id, message_id, emm)
                await ctx.send(embed=discord.Embed(color=discord.Color.green(), description=f'Reactrole wurde für den React {emoji} gelöscht!'))
            else:
                await ctx.send(embed=discord.Embed(color=discord.Color.red(), description=f'Diese Reaction wurde nicht an der Nachricht gefunden!'))
        elif '<:' not in emoji:
            result = await self.bot.pg_con.fetch("SELECT emoji, role, message_id, channel_id FROM reactrole WHERE guild_id = $1 and message_id = $2 and emoji = $3", guild_id, message_id, emoji_id)
            if not result:
                await ctx.send(embed=discord.Embed(color=discord.Color.red(), description=f'Diese Reaction wurde nicht an der Nachricht gefunden!'))
            elif emoji_id in str(result[0]['emoji']):
                await self.bot.pg_con.execute("DELETE FROM reactrole WHERE guild_id = $1 and message_id = $2 and emoji = $3", guild_id, message_id, emoji_id)
                await ctx.send(embed=discord.Embed(color=discord.Color.green(), description=f'Reactrole wurde für den React {emoji} gelöscht!'))
            else:
                await ctx.send(embed=discord.Embed(color=discord.Color.red(), description=f'Diese Reaction wurde nicht an der Nachricht gefunden!'))


def setup(bot):
    bot.add_cog(Reactrole(bot))

标签: python-3.xpostgresqldiscord.pydiscord.py-rewriteasyncpg

解决方案


我现在明白我的错误以及它是如何正确完成的。非常感谢帕特里克的帮助。

第 24、34、52 和 62 行必须如下所示:

role = discord.utils.get(guild.roles, id=int(result[0]['role']))

另外,第85行和第100行有错误。这里我要所有的结果

第 85 行必须如下所示:

if not emm in str(result) and role_id in str(result):

第 100 行必须如下所示:

if not emoji_id in str(result) and role_id in str(result):

推荐阅读