Ejemplo n.º 1
0
    async def on_command_error(self, ctx: utils.Context,
                               error: commands.CommandError):
        """
        Listens for command not found errors and tries to run them as interactions.
        """

        if not isinstance(error, commands.CommandNotFound):
            return

        # Deal with common aliases
        command_name = ctx.invoked_with.lower()
        for aliases in COMMON_COMMAND_ALIASES:
            if command_name in aliases:
                command_name = aliases[0]

        # See if we wanna deal with it
        guild_ids = [0] if ctx.guild is None else [0, ctx.guild.id]
        async with self.bot.database() as db:
            rows = await db(
                "SELECT response FROM interaction_text WHERE interaction_name=$1 AND guild_id=ANY($2::BIGINT[]) ORDER BY RANDOM() LIMIT 1",
                command_name.lower(), guild_ids)
        if not rows:
            self.logger.info("Nothing found")
            return  # No responses found

        # Create a command we can invoke
        ctx.interaction_response = rows[0]['response']
        ctx.interaction_name = command_name
        ctx.invoke_meta = True
        ctx.command = self.bot.get_command("interaction_command_meta")
        await self.bot.invoke(ctx)
Ejemplo n.º 2
0
    async def on_command_error(self, ctx: utils.Context,
                               error: commands.CommandError):
        """
        CommandNotFound handler so the bot can search for that custom command.
        """

        # Filter out DMs
        if isinstance(ctx.channel, discord.DMChannel):
            return  # Fail silently on DM invocation

        # Handle commandnotfound which is really just handling the set/get/delete/etc commands
        if not isinstance(error, commands.CommandNotFound):
            return

        # Get the command and used template
        prefixless_content = ctx.message.content[len(ctx.prefix):]
        matches = self.COMMAND_REGEX.search(prefixless_content)
        if matches is None:
            matches = self.OLD_COMMAND_REGEX.search(prefixless_content)
            if matches is None:
                return
        command_operator = matches.group("command")  # get/get/delete/edit
        template_name = matches.group("template")  # template name

        # Find the template they asked for on their server
        async with self.bot.database() as db:
            template = await localutils.Template.fetch_template_by_name(
                db, ctx.guild.id, template_name, fetch_fields=False)
        if not template:
            self.logger.info(
                f"Failed at getting template '{template_name}' in guild {ctx.guild.id}"
            )
            return  # Fail silently on template doesn't exist

        # Invoke command
        metacommand: utils.Command = self.bot.get_command(
            f'{command_operator.lower()}_profile_meta')
        ctx.command = metacommand
        ctx.template = template
        ctx.invoke_meta = True
        ctx.invoked_with = f"{matches.group('template')} {matches.group('command')}"
        ctx.view = commands.view.StringView(matches.group('args'))
        try:
            self.bot.dispatch("command", ctx)
            await metacommand.invoke(
                ctx)  # This converts the args for me, which is nice
        except (commands.CommandInvokeError, commands.CommandError) as e:
            self.bot.dispatch(
                "command_error", ctx, e
            )  # Throw any errors we get in this command into its own error handler