async def info(self, inter, poll_id: int = Param(default=None, description="ID of the poll")): """Shows info about current poll or provided poll id""" if poll_id is None: if self.get_current_poll(inter) is None: await inter.response.send_message("There is ongoing poll", ephemeral=True) return else: poll_id = self.get_current_poll(inter).id poll = self.get_poll(inter, poll_id) embed = disnake.Embed(title=poll.name, color=disnake.Color.blurple()) embed.add_field(name="ID", value=poll.id, inline=False) embed.add_field(name="Link", value=poll.link, inline=False) embed.add_field( name="Options", value=" ".join(self.parse_options(poll.options)), inline=False, ) result = self.count_votes(poll) msg = "" for x in result.keys(): msg += f"{x}: {result[x]} " embed.add_field(name="Votes", value=msg, inline=False) await inter.response.send_message(embed=embed)
def urban_embeds(self, author, dict): """Generate embeds from dictionary of resposes""" embed_list = [] for idx, item in enumerate(dict["list"]): definition = item["definition"] example = item["example"] if len(definition) > 1024: definition = definition[0:1021] + "`…`" if len(example) > 1024: example = example[0:1021] + "`…`" embed = disnake.Embed( title=item["word"], url=item["permalink"], ) embed.add_field(name="Definition", value=definition, inline=False) if example: embed.add_field(name="Example", value=example, inline=False) embed.add_field( name="Page", value=f"{idx + 1}/{len(dict['list'])}", inline=False, ) utils.add_author_footer(embed, author) embed_list.append(embed) return embed_list
async def cmd_leaderboard(self, ctx, all=None): leaderboard = self.data["leaderboard"] embed = disnake.Embed(title="Emojijagd Leaderboard", description="Wer hat am meisten Emojis gefunden?") embed.set_thumbnail(url="https://external-preview.redd.it/vFsRraBXc5hfUGRWtPPF-NG5maHEPRWTIqamB24whF8.jpg?width=960&crop=smart&auto=webp&s=24d42c9b4f5239a4c3cac79e704b7129c9e2e4d3") places = scores = "\u200b" place = 0 max = 0 if all == "all" else 10 ready = False for key, value in sorted(leaderboard.items(), key=lambda item: item[1], reverse=True): try: place += 1 if 0 < max < place: if ready: break elif str(ctx.author.id) != key: continue places += f"{place}: <@!{key}>\n" scores += f"{value:,}\n".replace(",", ".") if str(ctx.author.id) == key: ready = True except: pass embed.add_field(name=f"Jägerin", value=places) embed.add_field(name=f"Emojis", value=scores) await ctx.send("", embed=embed)
async def _bot(self, ctx): em = discord.Embed(color=discord.Color.green(), title='Bot Info') em.description = 'Universal bot made by MatesXs using Pycord.py' em.add_field(name="Servers", value=str(len(self.bot.guilds))) em.add_field(name='Total Users', value=str(len(self.bot.users))) em.add_field( name='Channels', value=f"{sum(1 for g in self.bot.guilds for _ in g.channels)}") em.add_field(name="Library", value=f"[disnake](https://github.com/DisnakeDev/disnake)") em.add_field(name="Bot Latency", value=f"{round(self.bot.latency * 1000)} ms") em.add_field(name="Uptime", value=humanize.naturaldelta(datetime.datetime.utcnow() - self.start_date)) if Config.enable_invite_link: em.add_field( name="Invite", value= f"[Click Here](https://discordapp.com/oauth2/authorize?client_id={self.bot.user.id}&scope=bot%20applications.commands&permissions=8)" ) else: em.add_field(name="Invite", value=f"WIP") general_util.add_author_footer(em, ctx.message.author) await general_util.delete_message(self.bot, ctx) await ctx.channel.send(embed=em, delete_after=Config.base_long_success_duration)
async def studijni(self, inter: disnake.ApplicationCommandInteraction): await inter.response.defer(with_message=True) link = "https://www.fit.vut.cz/fit/room/C109/.cs" htmlparser = etree.HTMLParser() session = requests.session() result = session.get(link, timeout=10) xDoc2 = etree.fromstring(result.text, htmlparser) hours_div = xDoc2.xpath( "//*[b[contains(text(),'Úřední hodiny')]]//following-sibling::div") embed = disnake.Embed(title=Messages.studijni_title, url=link) if hours_div: hours = etree.tostring(hours_div[0], encoding=str, method="text") additional_info = xDoc2.xpath("//main//section/p") if additional_info: info = etree.tostring(additional_info[0], encoding=str, method="text").split(':', 1) if len(info) > 1: embed.add_field(name=info[0], value=info[1], inline=False) else: hours_div = xDoc2.xpath("//main//section") if len(hours_div): hours = ''.join(hours_div[0].itertext()) hours = hours.strip() else: hours = Messages.studijni_web_error embed.add_field(name=Messages.studijni_office_hours, value=hours, inline=False) add_author_footer(embed, inter.author) await inter.edit_original_message(embed=embed)
async def reply(self, ctx, *, msg: Optional[Text] = ""): if not ctx.channel.category_id or ctx.channel.category_id != CATEGORY: raise InvalidDMContext() user = await self.user_from_channel(ctx.channel) files = await self.attachments_to_files(ctx.message.attachments) try: sent = await user.send(msg, files=files) except disnake.Forbidden as e: await self.system_message(ctx, f'Error: {e.text}') return e = disnake.Embed(color=0x2196F3) e.description = f'{msg}' e.timestamp = disnake.utils.utcnow() e.set_author(name=f'{ctx.author.name}#{ctx.author.discriminator}', icon_url=ctx.author.display_avatar) # lazyass files = await self.attachments_to_files(sent.attachments) await ctx.send(embed=e, files=files) await ctx.message.delete()
async def stats(self, ctx, *, member: disnake.Member = None): '''Get your own or another members' trivia stats.''' member = member or ctx.author entry = await self.config.get_entry(ctx.guild.id, member.id) total_games = entry.correct_count + entry.wrong_count if total_games == 0: win_rate = 0 else: win_rate = int(entry.correct_count / total_games * 100) e = disnake.Embed() e.set_author(name=member.display_name, icon_url=member.display_avatar.url) e.add_field(name='Score', value=str(entry.score)) e.add_field(name='Correct', value='{} games'.format(str(entry.correct_count))) e.add_field(name='Wrong', value='{} games'.format(str(entry.wrong_count))) e.add_field(name='Games played', value='{} games'.format(str(total_games))) e.add_field(name='Correct percentage', value='{}%'.format(str(win_rate))) await ctx.send(embed=e)
async def help(self, ctx: commands.Context, *, module_name: str = None): await general_util.delete_message(self.bot, ctx) pages = [] for cog in self.bot.cogs.values(): if module_name is not None: if module_name.lower() != cog.qualified_name.lower() and \ module_name.lower() != cog.file.lower() and \ module_name.lower() != cog.file.lower().replace("_", " "): continue cog_pages = generate_help_for_cog(cog, ctx) if cog_pages is not None: pages.extend(cog_pages) if pages: p_session = PaginatorSession(bot=self.bot, ctx=ctx, timeout=Config.help_duration, pages=pages) await p_session.run() else: emb = discord.Embed(title="Help", description="*No help available*", colour=discord.Color.green()) await ctx.send(embed=emb, delete_after=Config.help_duration)
async def on_message(self, message: disnake.Message): if message.channel.id not in config.subscribable_channels: return subscribers: List[Subscription] = repo.get_channel_subscribers(message.channel.id) if not len(subscribers): return embed = disnake.Embed(description=message.content[:2048]) embed.set_author( name=message.author.name, icon_url=message.author.avatar.with_size(128).url, ) embed.add_field( name=Messages.subscriptions_message_link, value=f"[{message.guild.name} #{message.channel.name}]({message.jump_url})", ) if len(message.attachments) or len(message.embeds): embed.add_field( name=Messages.subscriptions_embed_name, value=Messages.subscriptions_embed_value, ) for subscriber in subscribers: member = message.guild.get_member(subscriber.user_id) if member is None: continue if not self.phone_or_offline(member): continue try: await member.send(embed=embed) except disnake.errors.HTTPException: continue
async def _stats_member(self, ctx, member): past_day = datetime.utcnow() - timedelta(days=1) first_command = await self.db.fetchval( 'SELECT timestamp FROM log WHERE guild_id=$1 AND user_id=$2 LIMIT 1', ctx.guild.id, member.id) total_uses = await self.db.fetchval( 'SELECT COUNT(id) FROM log WHERE guild_id=$1 AND user_id=$2', ctx.guild.id, member.id) commands_alltime = await self.db.fetch( 'SELECT COUNT(id), command FROM log WHERE guild_id=$1 AND user_id=$2 GROUP BY command ' 'ORDER BY COUNT DESC LIMIT 5', ctx.guild.id, member.id) commands_today = await self.db.fetch( 'SELECT COUNT(id), command FROM log WHERE guild_id=$1 AND user_id=$2 AND timestamp > $3 ' 'GROUP BY command ORDER BY COUNT DESC LIMIT 5', ctx.guild.id, member.id, past_day) e = disnake.Embed() e.set_author(name=member.name, icon_url=member.display_avatar.url) e.add_field(name='Top Commands', value=self._stats_craft_list(commands_alltime)) e.add_field(name='Top Commands Today', value=self._stats_craft_list(commands_today)) self._stats_embed_fill(e, total_uses, first_command) await ctx.send(embed=e)
async def run_discord(self, func, inter, *args, **kwargs): data = func(*args, **kwargs) if "view" in data: await inter.send( embed=data["embed"][0], view=data["view"](data["embed"], data["choices"]), ) else: title = data.get("title", "") embed = disnake.Embed( title=title, colour=cfg.COLOR, description=data.get("description", "") ) embed.set_author( name=cfg.AUTHOR_NAME, icon_url=cfg.AUTHOR_ICON_URL, ) if "imagefile" in data: image = disnake.File(data["imagefile"]) embed.set_image(url=f"attachment://{data['imagefile']}") os.remove(data["imagefile"]) await inter.send(embed=embed, file=image) else: await inter.send(embed=embed)
async def _about_command(self, ctx, command: commands.Command): e = disnake.Embed(title=command.qualified_name + ' ' + command.signature, description=command.description or command.help) e.add_field(name='Qualified name', value=command.qualified_name) try: can_run = await command.can_run(ctx) except commands.CommandError: can_run = False e.add_field(name='Can you run it?', value=yesno(can_run)) e.add_field(name='Enabled', value=yesno(command.enabled)) invokes = await self.db.fetchval( 'SELECT COUNT(*) FROM log WHERE command=$1', command.qualified_name) e.add_field(name='Total invokes', value='{0:,d}'.format(invokes)) here_invokes = await self.db.fetchval( 'SELECT COUNT(*) FROM log WHERE command=$1 AND guild_id=$2', command.qualified_name, ctx.guild.id) e.add_field(name='Invokes in this server', value='{0:,d}'.format(here_invokes)) if command.aliases: e.set_footer(text='Also known as: ' + ', '.join(command.aliases)) await ctx.send(embed=e)
def generate_item_embed(item: Item) -> discord.Embed: embed = discord.Embed(title=item.name, color=RarityColors[item.rarity]) embed.add_field(name="ID", value=str(item.id)) embed.add_field(name="Level req", value=str(item.level_req)) embed.add_field(name="Rarity", value=RarityEnum.get_name(item.rarity)) if item.icon_path is not None: if general_util.is_url(item.icon_path): embed.set_thumbnail(url=item.icon_path) if item.item_slot is not None: embed.add_field(name="Slot", value=ItemSlotEnum.get_name(item.item_slot)) if item.sell_value is not None: embed.add_field(name="Sell value", value=f"{item.sell_value} coins") if item.description is not None: embed.description = item.description if item.effects: for idx, effect in enumerate(item.effects): embed.add_field(name=EffectEnum.get_name(effect.effect_id), value=str(effect.ammount), inline=False) else: embed.add_field(name="No effects", value="This item don't have any effects") return embed
async def version(self, ctx): '''Get changelog and download for the latest AutoHotkey_L version.''' url = 'https://api.github.com/repos/Lexikos/AutoHotkey_L/releases' async with ctx.http.get(url) as resp: if resp.status != 200: raise commands.CommandError('Query failed.') js = await resp.json() latest = js[0] asset = latest['assets'][0] content = self.h2m_version.convert(latest['body']) e = disnake.Embed(description=content, color=disnake.Color.green()) e.set_author(name='AutoHotkey_L ' + latest['name'], icon_url=latest['author']['avatar_url']) e.add_field(name='Release page', value=f"[Click here]({latest['html_url']})") e.add_field(name='Installer download', value=f"[Click here]({asset['browser_download_url']})") e.add_field(name='Downloads', value=asset['download_count']) await ctx.send(embed=e)
async def apexstats(self, ctx, platform: ApexPlatform, *, username): """about_apexstats""" headers = {"TRN-Api-Key": Configuration.get_master_var("APEX_KEY")} url = "https://public-api.tracker.gg/apex/v1/standard/profile/" + platform + "/" + ( username) async with self.bot.aiosession.get(url, headers=headers) as resp: if resp.status == 404: await MessageUtils.send_to(ctx, "NO", "apexstats_user_not_found") return elif not resp.status == 200: await MessageUtils.send_to(ctx, "NO", "apexstats_api_error") return else: responsejson = await resp.json() embed = disnake.Embed( colour=disnake.Colour(0x00cea2), timestamp=datetime.datetime.utcfromtimestamp( time.time()).replace(tzinfo=datetime.timezone.utc)) embed.add_field( name=Translator.translate('apexstats_username', ctx), value=await Utils.clean( responsejson["data"]["metadata"]["platformUserHandle"] )) for stat_type in responsejson["data"]["stats"]: type_key_name = stat_type["metadata"]["key"] type_key_value = stat_type["displayValue"] embed.add_field(name=Translator.translate( f'apexstats_key_{type_key_name}', ctx), value=type_key_value) await ctx.send(embed=embed)
async def locale(self, ctx, locale=None): if locale == 'gnida': rlocale = collection.find_one({"_id": ctx.author.id})["locale"] collection.update_one({ "locale": 'ru', '_id': ctx.author.id }, {"$set": { 'locale': 'gnida' }}) await ctx.send('Твоя ёбаная локаль была установлена на `gnida`!') if locale == 'ru': glocale = collection.find_one({"_id": ctx.author.id})["locale"] collection.update_one({ "locale": 'gnida', '_id': ctx.author.id }, {"$set": { 'locale': 'ru' }}) await ctx.send('Ваша локаль была установлена на `ru`.') if locale == 'test': rlocale = collection.find_one({"_id": ctx.author.id})["locale"] if rlocale == 'ru': await ctx.send('Ваша локаль равна `ru`') if rlocale == 'gnida': await ctx.send('Твоя ёбаная локаль равна `gnida`') if locale == None: await ctx.send(embed=disnake.Embed( description= 'Возможные локали:\nru\ngnida\n\nУстановка локали на gnida может подходить не всем серверам.', color=0x2f3136))
async def _info(self, inter): emb = disnake.Embed(colour=disnake.Color.orange()) emb.set_author(name=self.client.user.name, url='https://warframe.fandom.com/wiki/Cephalon_Cy', icon_url=self.client.user.avatar.url) emb.add_field(name='Версия', value='0.12.12.10.16367') emb.add_field(name='Написан на', value='disnake.py v2.4.0') emb.add_field( name='Разработчик', value='[сасиска#2472](https://discord.com/users/338714886001524737)' ) if inter.guild.id == 693929822543675455: emb.add_field(name='Принадлежность', value='Это - мой основной сервер.') if inter.guild.id == 735874149578440855: emb.add_field(name='Тестирование', value='Это - мой тестовый сервер.') emb.add_field(name='Обслуживаю', value=f'{len(self.client.users)} человек') emb.add_field(name='Существую на', value=f'{len(self.client.guilds)} серверах') emb.set_footer( text= 'Данное приложение не имеет никакого причастия к игре Warframe.', icon_url='https://i.playground.ru/p/yVaOZNSTdgUTxmzy_qvzzQ.png') await inter.response.send_message(embed=emb)
async def choose(self, ctx, *choices: commands.clean_content): '''Pick a random item from a list separated by spaces.''' choose_prompts = ( 'I have chosen', 'I have a great feeling about', 'I\'ve decided on', 'Easy choice', 'I think', ) if len(choices) < 2: raise commands.CommandError('At least two choices are necessary.') selected = choice(choices) e = disnake.Embed( description=selected ) e.set_author(name=choice(choose_prompts), icon_url=self.bot.user.display_avatar.url) msg = await ctx.send(':thinking:') await asyncio.sleep(3) await msg.edit(content=None, embed=e)
async def categories(self, ctx): '''Get a list of valid categories for the trivia command.''' e = disnake.Embed(description='\n'.join(self.trivia_categories.keys())) e.set_footer(text='Specifying a category halves your winnings.') await ctx.send(embed=e)
async def info(self, ctx, *, message: StarConverter()): '''Show info about a starred message.''' row = message star_ret = await self.db.fetchval( 'SELECT COUNT(id) FROM starrers WHERE star_id=$1', row.get('id')) author = await ctx.guild.fetch_member(row.get('user_id')) stars = star_ret + 1 e = disnake.Embed() e.set_author(name=author.display_name, icon_url=author.display_avatar.url) e.add_field(name='Stars', value=self.star_emoji(stars) + ' ' + str(stars)) e.add_field(name='Starred in', value='<#{}>'.format(row.get('channel_id'))) e.add_field(name='Author', value=f'<@{author.id}>') e.add_field(name='Starrer', value='<@{}>'.format(row.get('starrer_id'))) e.add_field(name='Posted', value=yesno(row.get('star_message_id') is not None)) e.add_field( name='Context', value='[Click here!](https://discordapp.com/channels/{}/{}/{})'. format(row.get('guild_id'), row.get('channel_id'), row.get('message_id'))) e.set_footer(text='ID: {}'.format(row.get('message_id'))) e.timestamp = row.get('starred_at') await ctx.send(embed=e)
def generate_embed(self, page): embed = disnake.Embed(title=Messages.help_title, description=Messages.help_description, color=0xeee657) embed.set_thumbnail(url=self.bot.user.display_avatar.url) self.add_fields(embed, page["commands"]) return embed
async def starrers(self, ctx, *, message: StarConverter()): '''List every starrer of a starred message.''' row = message starrers = await self.db.fetch( 'SELECT user_id FROM starrers WHERE star_id=$1', row.get('id')) e = disnake.Embed() e.add_field(name='Original starrer', value='<@{}>'.format(row.get('starrer_id')), inline=False) if starrers: desc = '\n'.join('<@{}>'.format(srow.get('user_id')) for srow in starrers) else: desc = 'No one yet!' e.add_field(name='Additional starrers', value=desc, inline=False) e.set_footer(text='Total: {}'.format(len(starrers) + 1)) await ctx.send(embed=e)
async def flip_func(ctx: commands.Context): embed = discord.Embed(title="Coin flip", description=random.choice(["True", "False"]), color=discord.Color.gold()) general_util.add_author_footer(embed, ctx.author) await ctx.send(embed=embed, delete_after=Config.base_long_success_duration)
async def help_card(self, ctx, name): try: command = data['command'][name] if command['mod'] and not utils.is_mod(ctx): return #raise KeyError except KeyError: await ctx.channel.send( "Fehler! Für dieses Kommando habe ich keinen Hilfe-Eintrag. Gib `!help` ein um eine Übersicht zu erhalten. " ) return title = command['name'] text = f"**{title}**\n" text += f"{command['brief']}\n\n" if command['brief'] else "" text += f"**Syntax:**\n `{command['syntax']}`\n" text += "**Parameter:**\n" if len(command['parameters']) > 0 else "" for param, desc in command['parameters'].items(): text += f"`{param}` - {desc}\n" text += f"**Beispiel:**\n `{command['example']}`\n" if command[ 'example'] else "" text += f"\n{command['description']}\n" if command[ 'description'] else "" embed = disnake.Embed(title=title, description=text, color=19607) text += "==========================\n" await utils.send_dm(ctx.author, text) # , embed=embed) for subname in data['command']: if subname.startswith(f"{name} "): await self.help_card(ctx, subname)
def generate_weather_embed( weather: weather_manager.observation.weather.Weather, place: str): temp = weather.temperature('celsius') wind = weather.wind() embed = discord.Embed( title=f"Weather at {place}", description= f"**UTC Time**: {weather.reference_time('date').strftime('%d.%b.%Y %H:%M')}", color=discord.Color.from_rgb(150, 165, 255)) embed.add_field(name="Weather", value=str(weather.detailed_status)) embed.add_field(name="Pressure (hPa)", value=str(weather.pressure["press"])) embed.add_field( name="Wind", value= f"Speed: {wind['speed']}, Deg: {wind['deg']}, Gust: {wind['gust']}") embed.add_field(name="Temp (°C)", value=str(temp["temp"])) embed.add_field(name="Min Temp (°C)", value=str(temp["temp_min"])) embed.add_field(name="Max Temp (°C)", value=str(temp["temp_max"])) embed.add_field(name="Feeling Temp (°C)", value=str(temp["feels_like"])) embed.add_field(name="Dew point", value=str(weather.dewpoint)) embed.add_field(name='\u200b', value='\u200b') embed.add_field(name="Humidity", value=f"{weather.humidity}%") embed.add_field(name="Precipitation probability", value=f"{weather.precipitation_probability}%") embed.add_field(name="UVI", value=str(weather.uvi)) return embed
async def start_work(self, ctx: commands.Context, hours: int = 1): await general_util.delete_message(self.bot, ctx) if not self.player_repo.is_idle(ctx.author.id): return await ctx.send(embed=general_util.generate_error_message( Strings.rpg_cant_perfor_action_no_idle), delete_after=Config.base_error_duration) if hours < 0 or hours > 12: return await ctx.send(embed=general_util.generate_error_message( Strings.rpg_work_invalid_work_time), delete_after=Config.base_error_duration) end_date = datetime.now(tz=timezone.utc) + timedelta(hours=hours) action = self.player_repo.create_action(ctx.author, ActionsEnum.WORK, end_date) reward_string = rpg_util.get_expected_rewards_string(action.rewards) embed = discord.Embed(title="Work started", description=reward_string, color=discord.Color.blue()) embed.add_field(name="Duration", value=f"{hours}h") embed.add_field(name="End time (UTC)", value=end_date.strftime("%d.%b.%Y %H:%M")) general_util.add_author_footer(embed, ctx.author) await ctx.send(embed=embed, delete_after=Config.base_long_success_duration)
async def run_discord(self, func, inter, *args, **kwargs): data = func(*args, **kwargs) if "view" in data: await inter.send( embed=data["embed"][0], view=data["view"](data["embed"], data["choices"]), ) else: title = data.get("title", "") embed = disnake.Embed(title=title, colour=imps.COLOR, description=data.get("description", "")) embed.set_author( name=imps.AUTHOR_NAME, icon_url=imps.AUTHOR_ICON_URL, ) if "imagefile" in data: filename = data["imagefile"] imagefile = imps.IMG_DIR.joinpath(filename) image = disnake.File(imagefile, filename=filename) embed.set_image(url=f"attachment://{filename}") await inter.send(embed=embed, file=image) image.close() os.remove(imagefile) else: await inter.send(embed=embed)
async def get_action(self, ctx: commands.Context): await general_util.delete_message(self.bot, ctx) action = self.player_repo.get_action(ctx.author.id) embed = discord.Embed(title="Current action", color=discord.Color.blue()) if action is None: embed.description = "*No action*" else: if action.rewards: rewards_str = rpg_util.get_expected_rewards_string( action.rewards) if rewards_str != "": embed.description = rewards_str embed.add_field(name="Action type", value=ActionsEnum.get_name(action.action_id)) embed.add_field(name="Remaining time", value=humanize.naturaldelta( action.end_date.replace(tzinfo=timezone.utc) - datetime.now(tz=timezone.utc))) embed.add_field(name="End time (UTC)", value=action.end_date.strftime("%d.%b.%Y %H:%M")) general_util.add_author_footer(embed, ctx.author) await ctx.send(embed=embed, delete_after=Config.base_long_success_duration)
async def list(self, ctx): """List premade presences""" e = disnake.Embed(color=ctx.me.color) e.description = '\n'.join(list(self.activities)) e.set_footer(text=f'{len(self.activities)} activities') await ctx.send(embed=e)
async def reload(self, ctx: KurisuContext, *cogs): """Reload cogs""" succeed = 0 failed = 0 error_str = "" embed = disnake.Embed(description=":ok_hand:", color=self.bot.info_color) for ext in cogs: try: self.bot.reload_extension(ext) succeed += 1 except commands.ExtensionError as e: failed += 1 error_str += ( f"**Error for {ext}**:\n\n{''.join(traceback.format_exception(None, e, e.__traceback__))}\n" ) if failed > 0: embed.set_footer( text=f"Failed to reload {failed} cogs. Sending error file...") await ctx.send(embed=embed) if error_str: await ctx.send(file=disnake.File( io.BytesIO(error_str.encode("utf-8")), "error.nim"))