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
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