async def nowplaying(self, ctx: cmds.Context, channel: str = None): """See what is now playing on the radio. Use "!nowplaying [<channel>]" to show what is now playing on the radio. Short version is "!np[<channel>]". Leave off <channel> to auto-detect the channel you are tuned to.""" async with ctx.typing(): cmd = ctx.invoked_with chan = None if cmd in ['npgame', 'nprw']: chan = RainwaveChannel.game elif cmd in ['npoc', 'npocr']: chan = RainwaveChannel.ocr elif cmd in ['npcover', 'npcovers', 'npmw', 'npvw']: chan = RainwaveChannel.cover elif cmd in ['npbw', 'npch', 'npchip']: chan = RainwaveChannel.chip elif cmd in ['npall', 'npomni', 'npow']: chan = RainwaveChannel.all elif cmd in ['nowplaying', 'np']: if channel: if channel.lower() in RainwaveChannel.__members__.keys(): chan = RainwaveChannel[channel.lower()] if chan is None: listener_id = await self.get_id_for_user(ctx.author) chan = await self.get_current_channel_for_id(listener_id) if chan is None: await ctx.author.send(self.not_tuned_in) return m = f'Now playing on the {chan.long_name}' d = await self.rw_info(chan.channel_id) event = d.get('sched_current') sched_id = int(event.get('id')) sched_type = event.get('type') sched_name = event.get('name') if sched_type == 'Election' and sched_name: m += f' ({sched_name})' elif sched_type == 'OneUp': m += f' ({sched_name} Power Hour)' song = event.get('songs')[0] embed = self.build_embed(song) m += f': {self.song_string(song)}' if ctx.guild: last = self.bot.config.get(f'rainwave:np:{chan.channel_id}', 0) if sched_id == last: c = f'You can only use **{cmd}** in {ctx.channel.mention} once per song.' await ctx.author.send(c) await ctx.author.send(m, embed=embed) else: self.bot.config.set(f'rainwave:np:{chan.channel_id}', sched_id) await ctx.send(m, embed=embed) else: await ctx.send(m, embed=embed)
async def _dice(self, ctx: commands.Context, amount: int = 2, dots: int = 6): if amount <= 0 or dots <= 0 or amount > 100 or dots > 100: await dice_help(ctx.channel) else: async with ctx.typing(): ld: list = [random.randint(1, dots) for i in range(amount)] desc: str = "```" for i in ld: desc += f"{i} " desc += "```" emb = discord.Embed( title="🎲 Dice Rolled", description=f"{desc}\nSum of all Dice : **{sum(ld)}**", colour=WHITE) emb.set_footer(text=f"{amount} Dices, {dots} Faces") await ctx.send(embed=emb)
async def rad_blur(self, ctx: Context, image_url: str = None) -> None: rate_limits.MemeCommand.check_rate_limit( ctx, cooldown_group="manips", priority_blacklist=self.blacklisted_channels) image_url = await self._get_image_url(ctx, image_url) async with ctx.typing(): base_bytes = await self.download_image_to_bytes(image_url) with CustomImage(file=base_bytes) as img: rotation = int( self._parameter_cache.get("rad_blur_degrees", 10)) img.radial_blur(rotation) f = BytesIO() img.save(file=f) f.seek(0) await ctx.send(file=discord.File(f, filename="blur.png"))
async def needsmorejpeg(self, ctx: Context, *, image_url: str = None) -> None: """Do I look like I know what a jpeg is?""" rate_limits.MemeCommand.check_rate_limit( ctx, cooldown_group="manips", priority_blacklist=self.blacklisted_channels) image_url = await self._get_image_url(ctx, image_url) async with ctx.typing(): base_bytes = await self.download_image_to_bytes(image_url) self.add_more_jpeg(base_bytes, output_path="more.jpeg", quality=randint(1, 2)) await ctx.send(file=discord.File("more.jpeg")) remove("more.jpeg")
async def github(self, ctx: commands.Context, *, repository=None): self.repository = repository if self.repository is None: await ctx.send(embed=errorhandler.BotAlert( "warn", "You need to give me a repository!").get_error_embed()) return try: self.github_session = GitHub(self.repository) except GitHubRepositoryError: await ctx.send(embed=errorhandler.BotAlert( "error", f"Had an error getting that repository. Are you sure {self.repository} exists?", ).get_error_embed()) return async with ctx.typing(): self.our_github_respostory = self.github_session.get_github_repo() self.our_embed = embeds.GitHubEmbed(discord.Color.greyple(), self.our_github_respostory) await ctx.send(embed=self.our_embed.get_embed_message())
async def cah(self, ctx: Context) -> None: """Sends a random 'Cyanide and Happiness' comic.""" url = "http://explosm.net/comics/random" async with ctx.typing(): async with self.session.get(url) as response: soup = BeautifulSoup(await response.text(), "html.parser") img_url = soup.find(property="og:image")["content"] async with self.session.get(img_url) as response: img = io.BytesIO(await response.read()) embed = Embed(title="Random Cyanide and Happiness", color=Color.blurple()) embed.set_image(url="attachment://cah.png") file = File(img, "cah.png") await ctx.send(file=file, embed=embed)
async def sarah(self, ctx: Context) -> None: """Sarah's Scribbles""" url = "http://www.gocomics.com/random/sarahs-scribbles" async with ctx.typing(): async with self.session.get(url) as response: soup = BeautifulSoup(await response.text(), "html.parser") img_url = soup.find(property="og:image")["content"] async with self.session.get(img_url) as response: img = io.BytesIO(await response.read()) embed = Embed(title="Random Sarah Scribbles", color=Color.blurple()) embed.set_image(url="attachment://sarahscribbles.png") file = File(img, "sarahscribbles.png") await ctx.send(file=file, embed=embed)
async def _play(self, ctx: commands.Context, *, search: str): if not ctx.voice_state.voice: await ctx.invoke(self._join) async with ctx.typing(): try: source = await YTDLSource.create_source(ctx, search, loop=self.bot.loop) except YTDLError as e: await ctx.send( 'An error occurred while processing this request: {}'. format(str(e))) else: song = Song(source) await ctx.voice_state.songs.put(song) await ctx.send('Enqueued {}'.format(str(source)))
async def hug(self, ctx: commands.Context, user: discord.Member = None, intensity: int = 0): """Because everyone likes hugs""" if user is None: user = ctx.author elif user.bot: await ctx.send(self.get_default_emoji("huggers") or ":people_hugging:") return async with ctx.typing(): emojis = config.hug_emojis if user != ctx.author: self.hugs_repo.do_hug(giver_id=ctx.author.id, receiver_id=user.id) user_str = utils.get_username(user) if 0 <= intensity < len(emojis): await ctx.send(f"{emojis[intensity]} **{user_str}**") else: await ctx.send(f"{choice(emojis)} **{user_str}**")
async def _unmorse(self, ctx: commands.Context, *, msg: str): '''Converts international morse code to ASCII.''' with ctx.typing(): result = '' msg0 = msg msg = msg.split('/') msg = [m.split() for m in msg] for word in msg: for char in word: try: result += morse.ascii[char] except KeyError: result += '<?>' result += ' ' embed = cmn.embed_factory(ctx) embed.title = f'ASCII for {msg0}' embed.description = result embed.colour = cmn.colours.good await ctx.send(embed=embed)
async def mrls(self, ctx: Context) -> None: """Send a random 'Mr. Lovenstein' comic.""" url = "http://www.mrlovenstein.com/shuffle" async with ctx.typing(): async with self.bot.session.get(url) as response: soup = BeautifulSoup(await response.text(), "html.parser") img_url = ( f"http://www.mrlovenstein.com{soup.find(id='comic_main_image')['src']}" ) async with self.bot.session.get(img_url) as response: img = io.BytesIO(await response.read()) embed = Embed(title="Random Mr. Lovenstein", color=Color.blurple()) embed.set_image(url="attachment://mrls.png") file = File(img, "mrls.png") await ctx.send(file=file, embed=embed)
async def _play(self, ctx: commands.Context, *, search: str): if not ctx.voice_state.voice: await ctx.invoke(self._summon) async with ctx.typing(): try: source = await YTDLSource.create_source(self.bot, ctx, search, loop=self.bot.loop) if not source: return await ctx.send(f"노래 재생/예약이 취소 되었습니다.") except YTDLError as e: await ctx.send('에러가 발생했습니다 : {}'.format(str(e))) else: song = Song(source) await ctx.voice_state.songs.put(song) await ctx.send('재생목록 추가 : {}'.format(str(source)))
async def send_pride_image(ctx: commands.Context, image_bytes: bytes, pixels: int, flag: str, option: str) -> None: """Gets and sends the image in an embed. Used by the pride commands.""" async with ctx.typing(): file_name = file_safe_name("pride_avatar", ctx.author.display_name) file = await in_executor(PfpEffects.apply_effect, image_bytes, PfpEffects.pridify_effect, file_name, pixels, flag) embed = discord.Embed( name="Your Lovely Pride Avatar!", description= f"Here is your lovely avatar, surrounded by\n a beautiful {option} flag. Enjoy :D" ) embed.set_image(url=f"attachment://{file_name}") embed.set_footer(text=f"Made by {ctx.author.display_name}.", icon_url=ctx.author.avatar_url) await ctx.send(file=file, embed=embed)
async def _stream(self, ctx: commands.Context, *, search: str): """播放直播""" if not ctx.voice_state.voice: await ctx.invoke(self._join) async with ctx.typing(): try: source = await YTDLSource.create_source(ctx, search, loop=self.bot.loop, stream=True) except YTDLError as e: await ctx.send('處理請求時發生錯誤 {}'.format(str(e))) else: song = Song(source) await ctx.voice_state.songs.put(song) await ctx.send('{} 已加入歌單'.format(str(source)))
async def reset_entire_leaderboard(self, ctx: commands.Context) -> None: update_members = \ """UPDATE MEMBERS SET xp=0, lvl=0 WHERE guild_id=$1""" c = disputils.Confirmation(self.bot, color=bot_config.COLOR) await c.confirm("Are you sure? This is irreversable!", ctx.message.author, ctx.channel) if c.confirmed: await c.quit("Resetting the leaderboard, please wait...") conn = self.bot.db.conn async with ctx.typing(): async with self.bot.db.lock: async with conn.transaction(): await conn.execute(update_members, ctx.guild.id) await ctx.send("Finished!") else: await c.quit("Leaderboard reset cancelled.")
async def update(self, ctx: commands.Context) -> None: """Update the entire starboard collection (restricted to owner-only).""" if database.Backend.db is None: raise database.DatabaseNotConnected(database.Backend.address) collection = database.Backend.db["starboarded_messages"] async with ctx.typing(): async for document in collection.find({}, {"_id": False}): channel = self.bot.get_channel(document["channel_id"]) message = await channel.fetch_message(document["message_id"]) entry = database.StarboardMessage.new( message, document["reaction_count"]) await entry.write() print( f"starboard.update(): successfully updated message {message.id}" ) await ctx.reply("`stdout` dump complete.")
async def _messages(self, ctx: commands.Context, member: typing.Optional[discord.Member]): """ display how many messages a user has sent in the past 24 hours defaults to your own """ if (not member): member = ctx.author async with ctx.typing(): messages = 0 yesterday = datetime.datetime.utcnow() - datetime.timedelta(days=1) async for (message) in ctx.channel.history(limit=1000, after=yesterday): if (message.author == member): messages += 1 s = "" if (messages == 1) else "s" await ctx.send("{0} sent {1} message{2} to this channel in the past 24 hours".format(member, messages, s))
async def snakify_command(self, ctx: Context, *, message: str = None) -> None: """ How would I talk if I were a snake? If `message` is passed, the bot will snakify the message. Otherwise, a random message from the user's history is snakified. Written by Momo and kel. Modified by lemon. """ with ctx.typing(): embed = Embed() user = ctx.message.author if not message: # Get a random message from the users history messages = [] async for message in ctx.channel.history(limit=500).filter( lambda msg: msg.author == ctx.message. author # Message was sent by author. ): messages.append(message.content) message = self._get_random_long_message(messages) # Set the avatar if user.avatar is not None: avatar = f"https://cdn.discordapp.com/avatars/{user.id}/{user.avatar}" else: avatar = ctx.author.default_avatar_url # Build and send the embed embed.set_author( name=f"{user.name}#{user.discriminator}", icon_url=avatar, ) embed.description = f"*{self._snakify(message)}*" await ctx.channel.send(embed=embed)
async def nether(self, ctx: Context, *, query: str): """Gets an image from https://ceapa.cool/nether.""" async with ctx.typing(): quoted = parse.quote(query) async with self.bot.session.get(f"https://ceapa.cool/nether/?obj={quoted}") as resp: image = await resp.read() ext = imghdr.what(None, h=image) if not ext: embed = discord.Embed(color=EGG_COLOR, timestamp=ctx.message.created_at) embed.set_author(name="No images found.", icon_url=ctx.me.display_avatar.url) return await ctx.send(embed=embed) ext = ext.lower().replace("jpeg", "jpg") await ctx.send( file=discord.File( BytesIO(image), filename=f"nether_{query.replace(' ', '_')}.{ext}" ) )
async def refresh_command(self, ctx: commands.Context) -> None: """Refresh inventories and send differences to channel.""" old_inventories = set(self.base_urls) with ctx.typing(): await self.refresh_inventory() # Get differences of added and removed inventories added = ', '.join(inv for inv in self.base_urls if inv not in old_inventories) if added: added = f"+ {added}" removed = ', '.join(inv for inv in old_inventories if inv not in self.base_urls) if removed: removed = f"- {removed}" embed = discord.Embed( title="Inventories refreshed", description=f"```diff\n{added}\n{removed}```" if added or removed else "" ) await ctx.send(embed=embed)
async def aoc_leaderboard(self, ctx: commands.Context) -> None: """Get the current top scorers of the Python Discord Leaderboard.""" async with ctx.typing(): try: leaderboard = await _helpers.fetch_leaderboard() except _helpers.FetchingLeaderboardFailed: await ctx.send(":x: Unable to fetch leaderboard!") return number_of_participants = leaderboard["number_of_participants"] top_count = min(AocConfig.leaderboard_displayed_members, number_of_participants) header = f"Here's our current top {top_count}! {Emojis.christmas_tree * 3}" table = f"```\n{leaderboard['top_leaderboard']}\n```" info_embed = _helpers.get_summary_embed(leaderboard) await ctx.send(content=f"{header}\n\n{table}", embed=info_embed)
async def hugs(self, ctx: commands.Context, user: discord.Member = None): """ Get your lovely hug stats. """ if user is None or user == ctx.author: user = ctx.author user_str = utils.get_username(user) title = "{0} Your Lovely Hug Stats {0}" else: user_str = utils.get_username(user) title = f"{{0}} {user_str}'s Lovely Hug Stats {{0}}" async with ctx.typing(): stats = self.hugs_repo.get_members_stats(user.id) positions = self.hugs_repo.get_member_position(stats) avg_position = int((positions[0] + positions[1]) // 2) embed = discord.Embed( title=title.format( self.get_default_emoji("peepoHugger") or "" ), description=" | ".join( ( "**Ranks**", f"Given: **{positions[0]}.**", f"Received: **{positions[1]}.**", f"Avg: **{avg_position}.**", ) ), ) embed.set_author(name=user_str, icon_url=user.avatar_url) utils.add_author_footer(embed, ctx.author) given_emoji = self.get_default_emoji("peepohugs") or "" recv_emoji = self.get_default_emoji("huggers") or "" embed.add_field(name=f"{given_emoji} Given", value=str(stats.given)) embed.add_field(name=f"{recv_emoji} Received", value=str(stats.received)) await ctx.send(embed=embed) await self.check.botroom_check(ctx.message)
async def aoc_leaderboard(self, ctx: commands.Context, number_of_people_to_display: int = 10) -> None: """ Pull the top number_of_people_to_display members from the PyDis leaderboard and post an embed. For readability, number_of_people_to_display defaults to 10. A maximum value is configured in the Advent of Code section of the bot constants. number_of_people_to_display values greater than this limit will default to this maximum and provide feedback to the user. """ async with ctx.typing(): await self._check_leaderboard_cache(ctx) if not self.cached_private_leaderboard: # Feedback on issues with leaderboard caching are sent by _check_leaderboard_cache() # Short circuit here if there's an issue return number_of_people_to_display = await self._check_n_entries( ctx, number_of_people_to_display) # Generate leaderboard table for embed members_to_print = self.cached_private_leaderboard.top_n( number_of_people_to_display) table = AocPrivateLeaderboard.build_leaderboard_embed( members_to_print) # Build embed aoc_embed = discord.Embed( description= f"Total members: {len(self.cached_private_leaderboard.members)}", colour=Colours.soft_green, timestamp=self.cached_private_leaderboard.last_updated) aoc_embed.set_author(name="Advent of Code", url=self.private_leaderboard_url) aoc_embed.set_footer(text="Last Updated") await ctx.send( content= f"Here's the current Top {number_of_people_to_display}! {Emojis.christmas_tree*3}\n\n{table}", embed=aoc_embed, )
async def role_all(self, ctx: commands.Context, role: Role): async with ctx.typing(): number_of_roles_given = 0 number_of_errors = 0 for member in ctx.guild.members: if member.id != self.bot.user.id: await member.add_roles(role) number_of_roles_given += 1 file = File(fp="./assets/vgcrollsafe.png") embed = Embed(title="Mass role assignment done!", description=f"Added the role {role.mention} to {number_of_roles_given}" f"members, with {number_of_errors} errors.", color=0xff0000) embed.set_thumbnail(url="attachment://vgcrollsafe.png") await ctx.send(file=file, embed=embed)
async def _playFromSaved(self, ctx: commands.Context): """Add songs from your saved to the current playlist.""" author = ctx.message.author.id if not ctx.voice_state.voice: try: await ctx.invoke(self._join) except AttributeError: raise commands.CommandError('You are not connected to any voice channel.') async with ctx.typing(): songs = self.get_user_playlist(author) await ctx.send(f'Enqueued {str(len(songs))} songs!') for search in songs: try: source = await YTDLSource.create_source(ctx, search, loop=self.bot.loop) except YTDLError as e: await ctx.send(f'"{search}" could not be added to the queue.') else: song = Song(source) await ctx.voice_state.songs.put(song) return
async def _longplay(self, ctx: commands.Context, *, search: str): """Plays a song with longer duration. A list of these sites can be found here: https://rg3.github.io/youtube-dl/supportedsites.html """ role = discord.utils.get(ctx.guild.roles, name = 'Loli Bot') if not ctx.voice_state.voice: await ctx.invoke(self._join) async with ctx.typing(): try: source = await YTDLSource.create_source(ctx, search, loop=self.bot.loop) splits = str(source.duration) if role in ctx.author.roles: await ctx.send('This user has :microphone: `Loli Bot` :microphone: role. Permission granted.') song = Song(source) await ctx.voice_state.songs.put(song) await ctx.send(' :notes: Enqueued :notes: :`{}`'.format(str(source))) else: await ctx.send(':negative_squared_cross_mark: Only users with `Loli Bot` role can use this command. Use `!play` instead.') except YTDLError as e: await ctx.send('An error occurred while processing this request: {}'.format(str(e)))
async def rating(self, ctx: commands.Context, player: str, server_name: str = 'ScrollsGuide'): async with ctx.typing(): async with self.bot.db_engine.acquire() as conn: server = await self.__get_server_check_api( ctx, conn, server_name) if server is None: return else: api = CBSAPI(server.cbsapi) try: player_data = await api.player(player) except PlayerNotFound: await ctx.send(f"Player `{player}` not found") else: await ctx.send( f"{player_data['name']} has rating {int(player_data['rating'])}" )
async def _play(self, ctx: commands.Context, *, search: str): """Plays a song. If there are songs in the queue, this will be queued until the other songs finished playing. This command automatically searches from various sites if no URL is provided. A list of these sites can be found here: https://rg3.github.io/youtube-dl/supportedsites.html """ async with ctx.typing(): try: source = await ytdl.YTDLSource.create_source(ctx, search, loop=self.bot.loop) except ytdl.YTDLError as e: await ctx.send('エラー: {}'.format(str(e))) else: if not ctx.voice_state.voice: await ctx.invoke(self._join) song = voice.Song(source) await ctx.voice_state.songs.put(song) await ctx.send('リストに追加 {}'.format(str(source)))
async def part(self, ctx: commands.Context, *part_numbers): """ Look up a part by number/ID. Supports AndyMark and VexPro. """ await ctx.message.add_reaction(self.bot.get_emoji(393852367751086090)) async with ctx.typing(): r = {} for p in part_numbers: _p = None try: _p = await self.get_part_page(parts.part_url(p)) except (NotFound, InternalServerError): r[p] = "Could not find part `{}`".format(p) else: r[_p.title.contents[0]] = parts.part_url(p) for key, value in r.items(): await ctx.send("{}: {}\n".format(key, value)) await ctx.message.remove_reaction( self.bot.get_emoji(393852367751086090), ctx.guild.me) await ctx.message.add_reaction(self.bot.get_emoji(314349398811475968))
async def key(self, ctx: commands.Context): """ How much is a TF2 key worth right now? """ if ctx.bot._config['backpacktf_key'] is None: await ctx.reply("I dunno?", delete_after=10, mention_author=False) async with ctx.typing(): with urlopen( Request( f"https://backpack.tf/api/IGetCurrencies/v1?key={ctx.bot._config['backpacktf_key']}", headers={ "User-Agent": "Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11" })) as api: v = json.loads(api.read().decode( ))["response"]["currencies"]["keys"]["price"]["value"] await ctx.send(fmt_codeblock( f"Mann Co. Supply Crate Key\n" \ f"{v} ref = {ceil(v * 3 * 3)} scrap = {ceil(v * 3 * 3) * 2} weapon drops" ))
async def get_stats(self, ctx: commands.Context, github_username: str): """ Query GitHub's API for PRs created by a GitHub user during the month of October. PRs with the 'invalid' tag are ignored If a valid github_username is provided, an embed is generated and posted to the channel Otherwise, post a helpful error message """ async with ctx.typing(): prs = await self.get_october_prs(github_username) if prs: stats_embed = self.build_embed(github_username, prs) await ctx.send('Here are some stats!', embed=stats_embed) else: await ctx.send( f"No October GitHub contributions found for '{github_username}'" )
async def prevplayed(self, ctx: cmds.Context, *, args: str = None): """Show what was previously playing on the radio. Use "!prevplayed [<channel>] [<index>]" to show what was previously playing on the radio. Short version is "!pp[<channel>] [<index>]". Leave off <channel> to auto-detect the channel you are tuned to. <index> should be a number from 0 to 4 (default 0). The higher the number, the further back in time you go.""" async with ctx.typing(): cmd = ctx.invoked_with if args is None: args = '' tokens = args.split() chan = None idx = 0 if cmd in ['ppgame', 'pprw']: chan = RainwaveChannel.game elif cmd in ['ppoc', 'ppocr']: chan = RainwaveChannel.ocr elif cmd in ['ppcover', 'ppcovers', 'ppmw', 'ppvw']: chan = RainwaveChannel.cover elif cmd in ['ppbw', 'ppch', 'ppchip']: chan = RainwaveChannel.chip elif cmd in ['ppall', 'ppomni', 'ppow']: chan = RainwaveChannel.all if chan in RainwaveChannel and len(tokens) > 0 and tokens[0].isdigit(): if int(tokens[0]) in range(5): idx = int(tokens[0]) if cmd in ['prevplayed', 'pp']: if len(tokens) > 0: if tokens[0].isdigit() and int(tokens[0]) in range(5): idx = int(tokens[0]) else: if tokens[0].lower() in RainwaveChannel.__members__.keys(): chan = RainwaveChannel[tokens[0].lower()] if len(tokens) > 1: if tokens[1].isdigit() and int(tokens[1]) in range(5): idx = int(tokens[1]) if chan is None: listener_id = await self.get_id_for_user(ctx.author) if listener_id is None: await ctx.author.send(self.nick_not_recognized) return chan = await self.get_current_channel_for_id(listener_id) if chan is None: await ctx.author.send(self.not_tuned_in) return m = f'Previously on the {chan.long_name}' d = await self.rw_info(chan.channel_id) event = d.get('sched_history')[idx] sched_id = int(event.get('id')) sched_type = event.get('type') sched_name = event.get('name') if sched_type == 'Election' and sched_name: m += f' ({sched_name})' elif sched_type == 'OneUp': m += f' ({sched_name} Power Hour)' song = event.get('songs')[0] embed = self.build_embed(song) m += f': {self.song_string(song)}' if ctx.guild: last_sched_id = f'rainwave:pp:{chan.channel_id}:{idx}' if sched_id == self.bot.config.get(last_sched_id, 0): await ctx.author.send(f'You can only use {cmd} in {ctx.channel.mention} once per song.') await ctx.author.send(m, embed=embed) else: self.bot.config.set(last_sched_id, sched_id) await ctx.send(m, embed=embed) else: await ctx.send(m, embed=embed)