Example #1
0
    async def close_channel(self, ctx, reason, anon: bool = False):
        await ctx.send(Embed("Closing channel..."))

        data = await tools.get_data(self.bot, ctx.guild.id)

        if data[7] is True:
            messages = await ctx.channel.history(limit=10000).flatten()

        try:
            await ctx.channel.delete()
        except discord.Forbidden:
            await ctx.send(
                ErrorEmbed("Missing permissions to delete this channel."))
            return

        embed = ErrorEmbed(
            "Ticket Closed",
            reason if reason else "No reason was provided.",
            timestamp=True,
        )
        embed.set_author(
            str(ctx.author) if anon is False else "Anonymous#0000",
            ctx.author.avatar_url if anon is False else
            "https://cdn.discordapp.com/embed/avatars/0.png",
        )
        embed.set_footer(f"{ctx.guild.name} | {ctx.guild.id}",
                         ctx.guild.icon_url)

        try:
            member = await ctx.guild.fetch_member(
                tools.get_modmail_user(ctx.channel).id)
        except discord.NotFound:
            member = None
        else:
            dm_channel = tools.get_modmail_channel(self.bot, ctx.channel)

            if data[6]:
                embed2 = Embed(
                    "Closing Message",
                    tools.tag_format(data[6], member),
                    colour=0xFF4500,
                    timestamp=True,
                )
                embed2.set_footer(f"{ctx.guild.name} | {ctx.guild.id}",
                                  ctx.guild.icon_url)
                try:
                    await dm_channel.send(embed2)
                except discord.Forbidden:
                    pass

            try:
                await dm_channel.send(embed)
            except discord.Forbidden:
                pass

        if data[4] is None:
            return

        channel = await ctx.guild.get_channel(data[4])
        if channel is None:
            return

        if member is None:
            try:
                member = await self.bot.fetch_user(
                    tools.get_modmail_user(ctx.channel))
            except discord.NotFound:
                pass

        if member:
            embed.set_footer(f"{member} | {member.id}", member.avatar_url)
        else:
            embed.set_footer(
                "Unknown#0000 | 000000000000000000",
                "https://cdn.discordapp.com/embed/avatars/0.png",
            )

        embed.set_author(
            str(ctx.author) if anon is False else f"{ctx.author} (Anonymous)",
            ctx.author.avatar_url,
        )

        if data[7] is True:
            history = ""

            for message in messages:
                if message.author.bot and (
                        message.author.id != self.bot.id
                        or len(message.embeds) <= 0 or message.embeds[0].title
                        not in ["Message Received", "Message Sent"]):
                    continue

                if not message.author.bot and message.content == "":
                    continue

                if message.author.bot:
                    if not message.embeds[0].author.name:
                        author = f"{' '.join(message.embeds[0].footer.text.split()[:-2])} (User)"
                    elif message.embeds[0].author.name.endswith(
                            " (Anonymous)"):
                        author = f"{message.embeds[0].author.name[:-12]} (Staff)"
                    else:
                        author = f"{message.embeds[0].author.name} (Staff)"

                    description = message.embeds[0].description

                    for attachment in [
                            field.value for field in message.embeds[0].fields
                            if field.name.startswith("Attachment ")
                    ]:
                        if not description:
                            description = f"(Attachment: {attachment})"
                        else:
                            description += f" (Attachment: {attachment})"
                else:
                    author = f"{message.author} (Comment)"
                    description = message.content

                history = (
                    f"[{str(message.created_at.replace(microsecond=0))}] {author}: {description}\n"
                    + history)

            history = io.BytesIO(history.encode())

            file = discord.File(
                history,
                f"modmail_log_{tools.get_modmail_user(ctx.channel).id}.txt")

            try:
                msg = await channel.send(embed, file=file)
            except discord.Forbidden:
                return

            log_url = msg.attachments[0].url[39:-4]
            log_url = log_url.replace("modmail_log_", "")
            log_url = [hex(int(some_id))[2:] for some_id in log_url.split("/")]
            log_url = f"{self.bot.config.BASE_URI}/logs/{'-'.join(log_url)}"
            embed.add_field("Message Logs", log_url, False)

            await asyncio.sleep(0.5)
            await msg.edit(embed)
            return

        try:
            await channel.send(embed)
        except discord.Forbidden:
            pass
Example #2
0
    async def _on_command_error(self, ctx, error, bypass=False):
        if (
            hasattr(ctx.command, "on_error")
            or (ctx.command and hasattr(ctx.cog, f"_{ctx.command.cog_name}__error"))
            and not bypass
        ):
            return

        if isinstance(error, commands.CommandNotFound):
            return
        elif isinstance(error, commands.NoPrivateMessage):
            await ctx.send(
                ErrorEmbed("Command Unavailable", "This command cannot be used in direct message.")
            )
        elif isinstance(error, commands.PrivateMessageOnly):
            await ctx.send(
                ErrorEmbed(
                    "Command Unavailable",
                    "This command can only be used in direct message.",
                )
            )
        elif isinstance(error, commands.MissingRequiredArgument) or isinstance(
            error, commands.BadArgument
        ):
            embed = ErrorEmbed(
                "Invalid Arguments",
                "Please check the usage below or join the support server with "
                f"`{ctx.prefix}support` if you don't know what went wrong.",
            )
            usage = "\n".join([ctx.prefix + x.strip() for x in ctx.command.usage.split("\n")])
            embed.add_field("Usage", f"```{usage}```")
            await ctx.send(embed)
        elif isinstance(error, commands.NotOwner):
            await ctx.send(
                ErrorEmbed("Permission Denied", "You do not have permission to use this command.")
            )
        elif isinstance(error, commands.MissingPermissions):
            await ctx.send(
                ErrorEmbed(
                    "Permission Denied",
                    "You do not have permission to use this command. Permissions needed: "
                    f"{', '.join([tools.perm_format(x) for x in error.missing_perms])}.",
                )
            )
        elif isinstance(error, commands.BotMissingPermissions):
            await ctx.send(
                ErrorEmbed(
                    "Bot Missing Permissions",
                    "Bot is missing permissions to perform that action. Permissions needed: "
                    f"{', '.join([tools.perm_format(x) for x in error.missing_perms])}.",
                )
            )
        elif isinstance(error, discord.HTTPException):
            await ctx.send(
                ErrorEmbed(
                    "Unknown HTTP Exception",
                    f"Please report this in the support server.\n```{error.text}````",
                )
            )
        elif isinstance(error, commands.CommandInvokeError):
            log.error(
                f"{error.original.__class__.__name__}: {error.original} (In {ctx.command.name})\n"
                f"Traceback:\n{''.join(traceback.format_tb(error.original.__traceback__))}"
            )

            try:
                await ctx.send(
                    ErrorEmbed(
                        "Unknown Error",
                        "Please report this in the support server.\n"
                        f"```{error.original.__class__.__name__}: {error.original}```",
                    )
                )
            except discord.HTTPException:
                pass