async def remove(self, ctx, name): """Remove a custom command.""" owner_id = await self.bot.db.execute( "SELECT added_by FROM custom_command WHERE command_trigger = %s AND guild_id = %s", name, ctx.guild.id, one_value=True, ) if not owner_id: raise exceptions.Warning( f"Custom command `{ctx.prefix}{name}` does not exist") owner = ctx.guild.get_member(owner_id) if owner is not None and owner != ctx.author: if not ctx.author.guild_permissions.manage_guild: raise exceptions.Warning( f"`{ctx.prefix}{name}` can only be removed by **{owner}** unless you have `manage_server` permission." ) await self.bot.db.execute( "DELETE FROM custom_command WHERE guild_id = %s AND command_trigger = %s", ctx.guild.id, name, ) await util.send_success( ctx, f"Custom command `{ctx.prefix}{name}` has been deleted")
async def prefix(self, ctx, prefix): """ Set a custom command prefix for this server. Usage: >prefix <text> >prefix \"<text with spaces>\" """ if prefix.strip() == "": raise exceptions.Warning("Prefix cannot be empty.") if prefix.startswith(" "): raise exceptions.Warning("Prefix cannot start with a space.") if len(prefix) > 32: raise exceptions.Warning("Prefix cannot be over 32 characters.") prefix = prefix.lstrip() await self.bot.db.execute( """ INSERT INTO guild_prefix (guild_id, prefix) VALUES (%s, %s) ON DUPLICATE KEY UPDATE prefix = VALUES(prefix) """, ctx.guild.id, prefix, ) self.bot.cache.prefixes[str(ctx.guild.id)] = prefix await util.send_success( ctx, f"Command prefix for this server is now `{prefix}`. " f"Example command usage: {prefix}ping", )
async def add(self, ctx, name, *, response): """Add a new custom command.""" if not await self.can_add_commands(ctx): raise commands.MissingPermissions(["manage_server"]) if name in self.bot_command_list(): raise exceptions.Warning( f"`{ctx.prefix}{name}` is already a built in command!") if await self.bot.db.execute( "SELECT content FROM custom_command WHERE guild_id = %s AND command_trigger = %s", ctx.guild.id, name, one_value=True, ): raise exceptions.Warning( f"Custom command `{ctx.prefix}{name}` already exists on this server!" ) await self.bot.db.execute( "INSERT INTO custom_command VALUES(%s, %s, %s, %s, %s)", ctx.guild.id, name, response, arrow.utcnow().datetime, ctx.author.id, ) await util.send_success( ctx, f"Custom command `{ctx.prefix}{name}` added with the response \n```{response}```" )
async def add(self, ctx, *, keyword): """Add a notification.""" if ctx.guild is None: raise exceptions.Warning( "Global notifications have been removed for performance reasons." ) amount = await self.bot.db.execute( "SELECT COUNT(*) FROM notification WHERE user_id = %s", ctx.author.id, one_value=True) if amount and amount >= 30: raise exceptions.Warning( f"You can only have a maximum of **30** notifications. You have **{amount}**" ) await ctx.message.delete() guild_id = ctx.guild.id keyword = keyword.lower().strip() check = await self.bot.db.execute( """ SELECT * FROM notification WHERE guild_id = %s AND user_id = %s AND keyword = %s """, guild_id, ctx.author.id, keyword, ) if check: raise exceptions.Warning("You already have this notification!") try: await util.send_success( ctx.author, f"New keyword notification for `{keyword}` set in **{ctx.guild.name}**", ) except discord.errors.Forbidden: raise exceptions.Warning( "I was unable to send you a DM! Please change your settings.") await self.bot.db.execute( """ INSERT INTO notification (guild_id, user_id, keyword) VALUES (%s, %s, %s) """, guild_id, ctx.author.id, keyword, ) if self.notifications_cache.get(str(guild_id)) is None: self.notifications_cache[str(guild_id)] = {} try: self.notifications_cache[str(guild_id)][keyword].append( ctx.author.id) except KeyError: self.notifications_cache[str(guild_id)][keyword] = [ctx.author.id] await util.send_success( ctx, f"New notification set! Check your DM {emojis.VIVISMIRK}")
async def add(self, ctx, *, keyword): """Add a notification""" dm = ctx.guild is None if dm: guild_id = 0 else: await ctx.message.delete() guild_id = ctx.guild.id check = await self.bot.db.execute( """ SELECT * FROM notification WHERE guild_id = %s AND user_id = %s AND keyword = %s """, guild_id, ctx.author.id, keyword, ) if check: raise exceptions.Warning("You already have this notification!") try: await util.send_success( ctx.author, f'New keyword notification for `"{keyword}"` set ' + ("globally" if dm else f"in **{ctx.guild.name}**"), ) except discord.errors.Forbidden: raise exceptions.Warning("I was unable to send you a DM. Please change your settings.") await self.bot.db.execute( """ INSERT INTO notification (guild_id, user_id, keyword) VALUES (%s, %s, %s) """, guild_id, ctx.author.id, keyword, ) if guild_id == 0: try: self.global_notifications_cache[keyword].append(ctx.author.id) except KeyError: self.global_notifications_cache[keyword] = [ctx.author.id] else: if self.notifications_cache.get(str(guild_id)) is None: self.notifications_cache[str(guild_id)] = {} try: self.notifications_cache[str(guild_id)][keyword].append(ctx.author.id) except KeyError: self.notifications_cache[str(guild_id)][keyword] = [ctx.author.id] if not dm: await util.send_success( ctx, "Succesfully set a new notification!" + ("" if dm else f" Check your DM {emojis.VIVISMIRK}"), )
async def test(self, ctx): """Test if Miso can send you a notification.""" try: await self.send_notification(ctx.author, ctx.message) await ctx.send(":ok_hand:") except discord.errors.Forbidden: raise exceptions.Warning("I was unable to send you a DM. Please change your settings.")
async def tz_list(self, ctx): """List current time of all server members.""" content = discord.Embed( title=f":clock2: Current time in {ctx.guild}", color=int("3b88c3", 16), ) rows = [] user_ids = [user.id for user in ctx.guild.members] data = await self.bot.db.execute( "SELECT user_id, timezone FROM user_settings WHERE user_id IN %s AND timezone IS NOT NULL", user_ids, ) if not data: raise exceptions.Warning( "No one on this server has set their timezone yet!") dt_data = [] for user_id, tz_str in data: dt_data.append((arrow.now(tz_str), ctx.guild.get_member(user_id))) for dt, member in sorted(dt_data, key=lambda x: int(x[0].format("Z"))): if member is None: continue rows.append( f"{dt.format('MMM Do HH:mm')} - **{util.displayname(member)}**" ) await util.send_as_pages(ctx, content, rows)
async def tz_set(self, ctx, your_timezone): """ Set your timezone. Give timezone as a tz database name (case sensitive): https://en.wikipedia.org/wiki/List_of_tz_database_time_zones Example: >timezone set Europe/Helsinki """ try: ts = arrow.now(your_timezone) except arrow.ParserError as e: raise exceptions.Warning(str(e), help_footer=True) await ctx.bot.db.execute( """ INSERT INTO user_settings (user_id, timezone) VALUES (%s, %s) ON DUPLICATE KEY UPDATE timezone = VALUES(timezone) """, ctx.author.id, your_timezone, ) await util.send_success( ctx, f"Saved your timezone as **{your_timezone}**\n:clock2: Current time: **{ts.ctime()}**", )
async def list(self, ctx): """List your current notifications.""" words = await self.bot.db.execute( """ SELECT guild_id, keyword, times_triggered FROM notification WHERE user_id = %s ORDER BY keyword """, ctx.author.id, ) if not words: raise exceptions.Info("You have not set any notifications yet!") content = discord.Embed(title=":love_letter: Your notifications", color=int("dd2e44", 16)) rows = [] for guild_id, keyword, times_triggered in words: if guild_id == 0: guild = "globally" else: guild = f"in {self.bot.get_guild(guild_id)}" rows.append( f'`"{keyword}"` *{guild}* - triggered **{times_triggered}** times' ) try: await util.send_as_pages(ctx.author, content, rows) except discord.errors.Forbidden: raise exceptions.Warning( "I was unable to send you a DM. Please change your settings.") if ctx.guild is not None: await ctx.send( f"Notification list sent to your DM {emojis.VIVISMIRK}")
async def editprofile_color(self, ctx, color): """ Set a background color to be used instead of your role color. Set as default to use role color again. """ if color.lower() == "default": color_value = None else: color = "#" + color.strip("#") color_hex = await util.get_color(ctx, color) if color_hex is None: raise exceptions.Warning(f"Invalid color {color}") color_value = str(color_hex).strip("#") await self.bot.db.execute( """ INSERT INTO user_profile (user_id, background_color) VALUES (%s, %s) ON DUPLICATE KEY UPDATE background_color = VALUES(background_color) """, ctx.author.id, color_value, ) await util.send_success( ctx, f"Profile background color set to `{color_value or 'default'}`!")
async def purge(self, ctx, amount: int): """ Delete some amount of messages in current channel. Optionally if users are mentioned, only messages by those users are deleted. Usage: >purge <amount> [mentions...] """ if amount > 100: raise exceptions.Warning( "You cannot delete more than 100 messages at a time.") await ctx.message.delete() if ctx.message.mentions: deleted = [] async for message in ctx.channel.history(limit=100, oldest_first=False): if message.author in ctx.message.mentions: deleted.append(message) if len(deleted) >= amount: break try: await ctx.channel.delete_messages(deleted) except discord.errors.HTTPException: raise exceptions.Error( "You can only delete messages that are under 14 days old.") else: deleted = await ctx.channel.purge(limit=amount) await ctx.send( f":put_litter_in_its_place: Deleted `{len(deleted)}` messages.", delete_after=5, )
async def remove(self, ctx, *, name): """Remove a role from the picker.""" role_id = await self.bot.db.execute( """ SELECT role_id FROM rolepicker_role WHERE guild_id = %s AND role_name = %s """, ctx.guild.id, name.lower(), one_value=True, ) if not role_id: raise exceptions.Warning( f"Could not find role with the name `{name}` in the picker.") await self.bot.db.execute( """ DELETE FROM rolepicker_role WHERE guild_id = %s AND role_name = %s """, ctx.guild.id, name.lower(), ) await util.send_success( ctx, f"<@&{role_id}> can no longer be acquired from the rolepicker channel.", )
async def unmute(self, ctx, member: discord.Member): """Unmute user.""" mute_role_id = await self.bot.db.execute( """ SELECT mute_role_id FROM guild_settings WHERE guild_id = %s """, ctx.guild.id, one_value=True, ) mute_role = ctx.guild.get_role(mute_role_id) if not mute_role: raise exceptions.Warning( "Mute role for this server has been deleted or is not set, " f"please use `{ctx.prefix}muterole <role>` to set it.") try: await member.remove_roles(mute_role) except discord.errors.Forbidden: raise exceptions.Error( f"It seems I don't have permission to unmute {member.mention}") await util.send_success(ctx, f"Unmuted {member.mention}") await self.bot.db.execute( """ DELETE FROM muted_user WHERE guild_id = %s AND user_id = %s """, ctx.guild.id, member.id, ) self.cache_needs_refreshing = True
async def fastban(self, ctx, *discord_users): """Ban user(s) without confirmation box.""" if not discord_users: return await util.send_command_help(ctx) for discord_user in discord_users: user = await util.get_user(ctx, discord_user) if user is None: try: user = await self.bot.fetch_user(int(discord_user)) except (ValueError, discord.NotFound): raise exceptions.Warning( f"Invalid user or id `{discord_user}`") if user.id == 133311691852218378: return await ctx.send("no.") try: await ctx.guild.ban(user, delete_message_days=0) except discord.errors.Forbidden: raise exceptions.Error( f"It seems I don't have the permission to ban **{user}**") else: await ctx.send(embed=discord.Embed( description=f":hammer: Banned `{user}`", color=int("f4900c", 16)))
async def votechannel_add(self, ctx, channel: discord.TextChannel, reaction_type=None): """ Set a channel to be a voting channel. Available types: [ vote | rate ] Defaults to vote. """ if reaction_type is None: channel_type = "voting" elif reaction_type.lower() in ["rate", "rating"]: channel_type = "rating" elif reaction_type.lower() in ["vote", "voting"]: channel_type = "voting" else: raise exceptions.Warning(f"Unknown reaction type `{reaction_type}`", help_footer=True) await self.bot.db.execute( """ INSERT INTO voting_channel (guild_id, channel_id, voting_type) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE voting_type = VALUES(voting_type) """, ctx.guild.id, channel.id, channel_type, ) self.bot.cache.votechannels.add(channel.id) await util.send_success( ctx, f"{channel.mention} is now a voting channel of type `{channel_type}`" )
async def starboard_emoji(self, ctx, emoji): """Change the emoji to use for starboard.""" if emoji[0] == "<": # is custom emoji emoji_obj = await util.get_emoji(ctx, emoji) if emoji_obj is None: raise exceptions.Warning("I don't know this emoji!") await self.bot.db.execute( """ INSERT INTO starboard_settings (guild_id, emoji_name, emoji_id, emoji_type) VALUES (%s, %s, %s, %s) ON DUPLICATE KEY UPDATE emoji_name = VALUES(emoji_name), emoji_id = VALUES(emoji_id), emoji_type = VALUES(emoji_type) """, ctx.guild.id, None, emoji_obj.id, "custom", ) await util.send_success( ctx, f"Starboard emoji is now {emoji} (emoji id `{emoji_obj.id}`)" ) else: # unicode emoji emoji_name = emoji_literals.UNICODE_TO_NAME.get(emoji) if emoji_name is None: raise exceptions.Warning("I don't know this emoji!") await self.bot.db.execute( """ INSERT INTO starboard_settings (guild_id, emoji_name, emoji_id, emoji_type) VALUES (%s, %s, %s, %s) ON DUPLICATE KEY UPDATE emoji_name = VALUES(emoji_name), emoji_id = VALUES(emoji_id), emoji_type = VALUES(emoji_type) """, ctx.guild.id, emoji_name, None, "unicode", ) await util.send_success(ctx, f"Starboard emoji is now {emoji}") await self.bot.cache.cache_starboard_settings()
async def remove(self, ctx, *, keyword): """Remove notification.""" dm = ctx.guild is None if dm: guild_id = 0 else: await ctx.message.delete() guild_id = ctx.guild.id check = await self.bot.db.execute( """ SELECT * FROM notification WHERE guild_id = %s AND user_id = %s AND keyword = %s """, guild_id, ctx.author.id, keyword, ) if not check: raise exceptions.Warning("You don't have such notification!") try: await util.send_success( ctx.author, f'The keyword notification for `"{keyword}"` that you set ' + ("globally" if dm else f"in **{ctx.guild.name}**") + " has been removed.", ) except discord.errors.Forbidden: raise exceptions.Warning( "I was unable to send you a DM. Please change your settings.") await self.bot.db.execute( """ DELETE FROM notification WHERE guild_id = %s AND user_id = %s AND keyword = %s """, guild_id, ctx.author.id, keyword, ) await self.create_cache() if not dm: await util.send_success( ctx, "Succesfully removed a notification!" + ("" if dm else f" Check your DM {emojis.VIVISMIRK}"), )
async def remove(self, ctx, *, keyword): """Remove notification.""" if ctx.guild is None: raise exceptions.Warning( "Please use this in the guild you want to remove notifications from." ) await ctx.message.delete() guild_id = ctx.guild.id keyword = keyword.lower().strip() check = await self.bot.db.execute( """ SELECT * FROM notification WHERE guild_id = %s AND user_id = %s AND keyword = %s """, guild_id, ctx.author.id, keyword, ) if not check: raise exceptions.Warning("You don't have such notification!") try: await util.send_success( ctx.author, f"The keyword notification for `{keyword}` that you set in **{ctx.guild.name}** has been removed.", ) except discord.errors.Forbidden: raise exceptions.Warning( "I was unable to send you a DM! Please change your settings.") await self.bot.db.execute( """ DELETE FROM notification WHERE guild_id = %s AND user_id = %s AND keyword = %s """, guild_id, ctx.author.id, keyword, ) # remake notification cache await self.create_cache() await util.send_success( ctx, f"Removed a notification! Check your DM {emojis.VIVISMIRK}")
async def big_emoji(self, ctx, emoji): """Get source image and stats of emoji. Will display additional info if Miso is in the server where the emoji is located in. Displaying who added the emoji requires Miso to have manage emojis permission! Usage: >emoji :emoji: """ if emoji[0] == "<": emoji = await util.get_emoji(ctx, emoji) if emoji is None: raise exceptions.Warning("I don't know this emoji!") emoji_url = emoji.url emoji_name = emoji.name else: # unicode emoji emoji_name = emoji_literals.UNICODE_TO_NAME.get(emoji) if emoji_name is None: raise exceptions.Warning("I don't know this emoji!") codepoint = "-".join( f"{ord(e):x}" for e in emoji_literals.NAME_TO_UNICODE.get(emoji_name)) emoji_name = emoji_name.strip(":") emoji_url = f"https://twemoji.maxcdn.com/v/13.0.1/72x72/{codepoint}.png" content = discord.Embed(title=f"`:{emoji_name}:`") content.set_image(url=emoji_url) stats = await util.image_info_from_url(emoji_url) content.set_footer(text=f"Type: {stats['filetype']}") if isinstance(emoji, discord.Emoji): content.description = ( f"Added {arrow.get(emoji.created_at).format('D/M/YYYY')}\n" f"**{emoji.guild}**") content.set_footer( text= f"{stats['filetype']} | {stats['filesize']} | {stats['dimensions']}" ) await ctx.send(embed=content)
async def blacklist_guild(self, ctx, guild_id: int, *, reason): """Blacklist a guild from adding or using Miso Bot.""" guild = self.bot.get_guild(guild_id) if guild is None: raise exceptions.Warning(f"Cannot find guild with id `{guild_id}`") await self.bot.db.execute( "INSERT IGNORE blacklisted_guild VALUES (%s, %s)", guild.id, reason ) self.bot.cache.blacklist["global"]["guild"].add(guild_id) await guild.leave() await util.send_success(ctx, f"**{guild}** can no longer use Miso Bot!")
async def whitelist_command(self, ctx, *, command): """Whitelist a command.""" cmd = self.bot.get_command(command) if cmd is None: raise exceptions.Warning(f"Command `{ctx.prefix}{command}` not found.") await self.bot.db.execute( "DELETE FROM blacklisted_command WHERE guild_id = %s AND command_name = %s", ctx.guild.id, cmd.qualified_name, ) self.bot.cache.blacklist[str(ctx.guild.id)]["command"].discard(cmd.qualified_name.lower()) await util.send_success(ctx, f"`{ctx.prefix}{cmd}` is no longer blacklisted.")
async def tz_now(self, ctx, member: discord.Member = None): """Get current time.""" if member is None: member = ctx.author tz_str = await self.bot.db.execute( "SELECT timezone FROM user_settings WHERE user_id = %s", member.id, one_value=True) if tz_str: dt = arrow.now(tz_str) await ctx.send(f":clock2: **{dt.format('MMM Do HH:mm')}**") else: raise exceptions.Warning( f"{member} has not set their timezone yet!")
async def ban(self, ctx, *discord_users): """Ban user(s).""" if not discord_users: return await util.send_command_help(ctx) for discord_user in discord_users: user = await util.get_member(ctx, discord_user) if user is None: try: user = await self.bot.fetch_user(int(discord_user)) except (ValueError, discord.NotFound): raise exceptions.Warning( f"Invalid user or id `{discord_user}`") if user.id == 133311691852218378: return await ctx.send("no.") # confirmation dialog for guild members if isinstance(user, discord.Member): await self.send_ban_confirmation(ctx, user) elif isinstance(user, discord.User): try: await ctx.guild.ban(user) except discord.errors.Forbidden: raise exceptions.Error( f"It seems I don't have the permission to ban **{user}**" ) else: await ctx.send(embed=discord.Embed( description=f":hammer: Banned `{user}`", color=int("f4900c", 16))) else: raise exceptions.Warning( f"There was an error finding discord user `{discord_user}`" )
async def statsgraph(self, ctx, stat, hours: int = 24): """Show various stat graphs.""" stat = stat.lower() available = [ "messages", "reactions", "commands_used", "guild_count", "member_count", "notifications_sent", "lastfm_api_requests", "html_rendered", ] if stat not in available: raise exceptions.Warning( f"Available stats: {', '.join(available)}") data = await self.bot.db.execute(f""" SELECT UNIX_TIMESTAMP(ts), DAY(ts), HOUR(ts), MINUTE(ts), {stat} FROM stats WHERE ts >= NOW() + INTERVAL -{hours} HOUR AND ts < NOW() + INTERVAL 0 DAY ORDER BY ts """) datadict = {} for row in data: datadict[str(row[0])] = row[-1] patched_data = [] frame = [] now = arrow.utcnow() first_data_ts = arrow.get(data[0][0]) start = now.shift(hours=-hours) if start < first_data_ts: start = first_data_ts for dt in arrow.Arrow.span_range("minute", start, now.shift(minutes=-1)): dt = dt[0] value = datadict.get(str(dt.timestamp), nan) frame.append(dt.datetime) patched_data.append(value) plotter.time_series_graph(frame, patched_data, str(discord.Color.random())), with open("downloads/graph.png", "rb") as img: await ctx.send(file=discord.File(img), )
async def creategif(self, ctx, media_url): """Create a gfycat gif from video url.""" starttimer = time() async with aiohttp.ClientSession() as session: auth_headers = await gfycat_oauth(session) url = "https://api.gfycat.com/v1/gfycats" params = {"fetchUrl": media_url.strip("`")} async with session.post(url, json=params, headers=auth_headers) as response: data = await response.json() try: gfyname = data["gfyname"] except KeyError: raise exceptions.Warning( "Unable to create gif from this link!") message = await ctx.send(f"Encoding {emojis.LOADING}") i = 1 url = f"https://api.gfycat.com/v1/gfycats/fetch/status/{gfyname}" await asyncio.sleep(5) while True: async with session.get(url, headers=auth_headers) as response: data = await response.json() task = data["task"] if task == "encoding": pass elif task == "complete": await message.edit( content= f"Gif created in **{util.stringfromtime(time() - starttimer, 2)}**" f"\nhttps://gfycat.com/{data['gfyname']}") break else: await message.edit( content="There was an error while creating your gif :(" ) break await asyncio.sleep(i) i += 1
async def blacklist_command(self, ctx, *, command): """Blacklist a command.""" cmd = self.bot.get_command(command) if cmd is None: raise exceptions.Warning(f"Command `{ctx.prefix}{command}` not found.") await self.bot.db.execute( "INSERT IGNORE blacklisted_command VALUES (%s, %s)", cmd.qualified_name, ctx.guild.id ) try: self.bot.cache.blacklist[str(ctx.guild.id)]["command"].add(cmd.qualified_name.lower()) except KeyError: self.bot.cache.blacklist[str(ctx.guild.id)] = { "member": set(), "command": set([cmd.qualified_name.lower()]), } await util.send_success( ctx, f"`{ctx.prefix}{cmd}` is now a blacklisted command on this server." )
async def emojify(self, ctx, *, text): """Emojify your message.""" request_data = { "density": 100, "input": text, "shouldFilterEmojis": False } async with aiohttp.ClientSession() as session: async with session.post( "https://api.emojify.net/convert", json=request_data, headers={"Content-Type": "application/json"}, ) as response: data = await response.json() result = data.get("result") try: await ctx.send(result) except discord.errors.HTTPException: raise exceptions.Warning( "Your text when emojified is too long to send!")
async def editprofile_description(self, ctx, *, text): """Change the description on your profile.""" if text.strip() == "": return await util.send_command_help(ctx) if len(text) > 500: raise exceptions.Warning( f"Description cannot be more than 500 characters ({len(text)})" ) await self.bot.db.execute( """ INSERT INTO user_profile (user_id, description) VALUES (%s, %s) ON DUPLICATE KEY UPDATE description = VALUES(description) """, ctx.author.id, text, ) await util.send_success(ctx, "Profile description updated!")
async def list(self, ctx): """List your current notifications.""" words = await self.bot.db.execute( """ SELECT guild_id, keyword, times_triggered FROM notification WHERE user_id = %s ORDER BY keyword """, ctx.author.id, ) if not words: raise exceptions.Info("You have not set any notifications yet!") content = discord.Embed( title=f":love_letter: You have {len(words)} notifications", color=int("dd2e44", 16)) rows = [] for guild_id, keyword, times_triggered in sorted(words): guild = self.bot.get_guild(guild_id) if guild is None: guild = f"[Unknown server `{guild_id}`]" rows.append( f"**{guild}** : `{keyword}` - Triggered **{times_triggered}** times" ) try: await util.send_as_pages(ctx.author, content, rows, maxpages=1, maxrows=50) except discord.errors.Forbidden: raise exceptions.Warning( "I was unable to send you a DM! Please change your settings.") if ctx.guild is not None: await util.send_success( ctx, f"Notification list sent to your DM {emojis.VIVISMIRK}")
async def test(self, ctx, message: discord.Message = None): """ Test if Miso can send you a notification. If supplied with a message id, will check if you would have been notified by it. """ if message is None: try: await self.send_notification(ctx.author, message or ctx.message, ["test"], test=True) await ctx.send(":ok_hand: Check your DM") except discord.errors.Forbidden: raise exceptions.Warning( "I was unable to send you a DM! Please check your privacy settings." ) else: if ctx.author not in message.channel.members: raise exceptions.Error("You cannot see this message.") keywords = await self.bot.db.execute( "SELECT keyword FROM notification WHERE user_id = %s", ctx.author.id, as_list=True) pattern = regex.compile(self.keyword_regex, words=keywords, flags=regex.IGNORECASE) finds = pattern.findall(message.content) if not finds: await ctx.send(":x: This message would not notify you") else: keywords = list(set(finds)) await self.send_notification(ctx.author, message, keywords, test=True) await ctx.send(":ok_hand: Check your DM")