async def change_status(self): amount = len(self.bot.guilds) log.info(f"I saw {amount} of servers") await self.bot.change_presence(activity=discord.Activity( type=discord.ActivityType.watching, name=f"{amount} servers", ))
async def get_last_message_from( context: Union[SlashContext, Context] # author: discord.Member, channel: discord.TextChannel ) -> Optional[str]: log.info("Getting last message") try: output = None if isinstance(context, SlashContext): output = await asyncio.wait_for( context.channel.history(limit=None).get( author__id=context.author.id), timeout=10.0, ) # Timeout after 10 seconds else: async for message in context.channel.history(limit=None): if message.id == context.message.id: continue if message.author.id == context.author.id: output = message break except asyncio.TimeoutError: log.info("Timed out") raise else: if output is None: log.info("Not found") else: log.info("Found") return output
def get_emoji_for(thing: int) -> str: log.info(f"Getting emoji {thing}") emoji_dict = { 1: "1️⃣", 2: "2️⃣", 3: "3️⃣", 4: "4️⃣", 5: "5️⃣", 6: "6️⃣", 7: "7️⃣", 8: "8️⃣", 9: "9️⃣", 10: "🔟", } log.debug(emoji_dict) log.info(f"Got {emoji_dict[thing]}") return emoji_dict[thing]
async def make_list(stuff: List[str]) -> str: log.info("Making list") log.debug(stuff) output = "" for item in stuff: output += f" - [**Jump to message**]({item})\n" log.info("Success!") log.debug(repr(output)) log.info("END OF `make_list`") return output
async def get_last_message_from( author: discord.Member, channel: discord.TextChannel ) -> Optional[str]: log.info("Getting last message") async for message in channel.history(oldest_first=False, limit=None): if message.author == author: log.info("Success") return message log.info("Not found") return None
async def invite(ctx): log.info("Sending invite links...") await ctx.send(embed=discord.Embed( title="Invite links", description="Here are some invite links you can use to invite the bot", color=discord.Color.green(), ).add_field( name="Top.gg", value="[**Link**](https://top.gg/bot/828341132865437737)" ).add_field( name="Discord Bot List", value="[**Link**](https://discordbotlist.com/bots/slashtilities)", ).add_field( name="Direct invite link", value= "[**Link**](http://thatxliner.github.io/discord/bots/slashtilities.html)", ).set_footer(text="You are an epic person :)")) log.info("Done!") log.info("END OF `invite`")
async def vote(ctx): log.info("Sending vote links...") await ctx.send(embed=discord.Embed( title="Vote links", description= "Want to help support us and show your thankfulness? Just vote for our bot!", color=discord.Color.green(), ).add_field( name="Top.gg", value="[**Vote here!**](https://top.gg/bot/828341132865437737/vote)", ).add_field( name="Discord Bot List", value= "[**Upvote Here!**](https://discordbotlist.com/bots/slashtilities/upvote)", ).add_field( name="GitHub", value="[**Star Here!**](https://github.com/ThatXliner/slashtilities)", ).set_footer(text="You are an epic person :)")) log.info("Done!") log.info("END OF `vote`")
async def basically_today(msg_format: str) -> str: log.info(f"Sending today's time to format {msg_format!r}") return msg_format.format( datetime.datetime.today().strftime("%B, %d, %Y (%m/%d/%Y)"))
async def yesno(ctx: commands.Context, question: str) -> None: log.info("START OF `yesno`") log.info("Sending response") try: msg = await ctx.send( embed=discord.Embed( title=await utils.quote(question), description="React with :+1: to agree and with :-1: to disagree.", color=discord.Color.blue(), ) .set_author(name=f"{ctx.author} asks:", icon_url=str(ctx.author.avatar_url)) .set_footer(text=await utils.basically_today("Poll made at {}")), ) except discord.errors.HTTPException: log.info("Spam?") msg = await ctx.send( f"**{ctx.author.mention} asks:**\n" + (await utils.quote(question)), allowed_mentions=utils.NO_MENTIONS, ) else: log.info("Success!") try: log.info("Trying to add reactions...") await msg.add_reaction("\N{THUMBS UP SIGN}") await msg.add_reaction("\N{THUMBS DOWN SIGN}") except discord.errors.Forbidden: ctx.channel.send( embed=( await utils.errorize( "I could not add the nessecary reactions to the poll above" ) ).set_footer(text="Gimmei perms now") ) else: log.info("Added reactions!") log.info("END OF `yesno`")
async def poll( ctx: commands.Context, question: str, *choices: str, **choices_dict: Dict[str, str] ) -> None: log.info("START OF `poll`") log.info("Making poll") log.debug({question: choices}) log.info("Poll made; sending response...") choices = list(choices) choices.extend(choices_dict.values()) try: msg = await ctx.send( embed=discord.Embed( title=await utils.quote(question), description=await make_numbered_list(choices), color=discord.Color.blue(), ) .set_author(name=f"{ctx.author} asks:", icon_url=str(ctx.author.avatar_url)) .set_footer(text=await utils.basically_today("Poll made at {}")), allowed_mentions=discord.AllowedMentions().none(), ) except discord.errors.HTTPException: log.info("Spam?") await ctx.send( f"**{ctx.author.mention} asks:**\n" + (await utils.quote(question)), allowed_mentions=utils.NO_MENTIONS, ) try: msg = await ctx.channel.send( embed=discord.Embed( title="Choices:", description=await make_numbered_list(choices), color=discord.Color.blue(), ).set_footer(text=await utils.basically_today("Poll made at {}")) ) except discord.errors.HTTPException: log.info("yes, it's spam") msg = await ctx.channel.send( "**Choices:**\n" + (await make_numbered_list(choices)), allowed_mentions=discord.AllowedMentions.none(), ) else: log.info("Success!") try: log.info("Trying to add reactions...") for emoji in map(get_emoji_for, range(1, len(choices) + 1)): await msg.add_reaction(emoji) except discord.errors.Forbidden: ctx.channel.send( embed=( await utils.errorize( "I could not add the nessecary reactions to the poll above" ) ).set_footer(text="Gimmei perms now") ) else: log.info("Add reactions!") log.info("END OF `poll`")
async def yesno(self, ctx: Union[SlashContext, commands.Context], question: Optional[str] = None) -> None: """Send a yes-or-no question (options mutually exclusive)""" log.info("START OF `yesno`") log.info("Sending response") if question is None: log.info("No question specified, using last message") # It'll take some time try: await ctx.defer(hidden=True) except AttributeError: pass try: question = await utils.get_last_message_from(ctx) except asyncio.TimeoutError: await utils.send_hidden_message( ctx, "You didn't specify a question, and I tried to find your last message but it took too long", ) else: if question is None: await utils.send_hidden_message( ctx, "Could not find your last message") else: await question.add_reaction("\N{THUMBS UP SIGN}") await question.add_reaction("\N{THUMBS DOWN SIGN}") await utils.send_hidden_message( ctx, "Done. Added the proper reactions to it") else: try: msg = await ctx.send(embed=discord.Embed( title=await utils.quote(question), description= "React with :+1: to agree and with :-1: to disagree.", color=discord.Color.blue(), ).set_author( name=f"{ctx.author} asks:", icon_url=str(ctx.author.avatar_url)).set_footer( text=await utils.basically_today("Poll made at {}")), ) except discord.errors.HTTPException: log.info("Spam?") msg = await ctx.send( f"**{ctx.author.mention} asks:**\n" + (await utils.quote(question)), allowed_mentions=utils.NO_MENTIONS, ) else: log.info("Success!") try: log.info("Trying to add reactions...") await msg.add_reaction("\N{THUMBS UP SIGN}") await msg.add_reaction("\N{THUMBS DOWN SIGN}") except discord.errors.Forbidden: ctx.channel.send(embed=(await utils.errorize( "I could not add the nessecary reactions to the poll above") ).set_footer(text="Gimmei perms now")) else: log.info("Added reactions!") log.info("END OF `yesno`")
async def on_ready(): log.info("\N{WHITE HEAVY CHECK MARK} I am ready!")
async def igotpinged(self, ctx: commands.Context) -> None: """Get the person who pinged you ever since your last message""" log.info("START OF `igotpinged`") try: await ctx.defer() except AttributeError: pass log.info("Deffered.") try: last_msg = await utils.get_last_message_from(ctx) except discord.errors.Forbidden: log.info("Sending response (errored)") await ctx.send(embed=(await utils.errorize( "How do you expect me to find your last message if " "I don't even have access to this channel???", )).set_footer( text="What an idiot")) log.info("Success!") return except asyncio.TimeoutError: log.info("Sending response (timed out)") await ctx.send(embed=( # TODO: Don't get impatient and quit await utils.errorize( "Ayo, getting your last message took too long (more than *10 seconds*). So I got impatient and quit." )).set_footer(text="Maybe you didn't send any messages")) log.info("Success!") else: if last_msg is None: log.info("Sending response") await ctx.send(embed=(await utils.errorize( "Couldn't find your last message (maybe you didn't send any messages)" ))) log.info("Success!") log.info("END OF `igotpinged`") return ping_msgs = [ # TODO: Seperate to function and add timeout message async for message in ctx.channel.history( after=last_msg, limit=None, # or 9000? ) if ctx.author.mentioned_in(message) ] log.info("Ping status:") if len(ping_msgs) > 0: if len(ping_msgs) > 1: log.info("Found pings") to_paginate = [ discord.Embed( title=":mag: Found!", description="Click on the pagination buttons to see\n" "who pinged you (times out *after 100 seconds*)", color=discord.Color.green(), ).add_field( name="Your last message", value=f"[**Jump to message**]({last_msg.jump_url})", inline=False, ) ] log.info("Made initial stuff to paginate") log.debug(to_paginate) log.info("Making `author_and_pings` dictionary") author_and_pings: DefaultDict[discord.Member, List[str]] = defaultdict(list) for message in ping_msgs: author_and_pings[message.author].append(message.jump_url) log.info("Done") log.debug(author_and_pings) # Should be allowed # See: https://discord.com/channels/264445053596991498/714045415707770900/830117545422880809 to_paginate.extend([ discord.Embed( title="", description=await make_list(msgs), color=discord.Color.green(), ).set_author( name=f"{author} pinged you in these messages:", icon_url=str(author.avatar_url), ) for author, msgs in author_and_pings.items() ]) log.info("Final `to_paginate` made") log.debug(to_paginate) # Should also be allowed log.info("Creating paginator") paginator = BotEmbedPaginator(ctx, to_paginate) log.info("Running paginator") try: await paginator.run( channel= ctx # Very hacky. It'll think ctx.send == channel.send ) # But it works except discord.errors.Forbidden: ctx.channel.send(embed=await utils.errorize( "Oi, I cannot remove your reactions.\n" "Gimmei `Manage Messages` permission." ).set_footer( text= "If you need to re-invite the bot, use the `/invite` command" )) log.info("Success!") else: log.info("Found ping") log.info("Sending response") await ctx.send(embed=(discord.Embed( title=":mag: Found!", description= f"{ping_msgs[0].author.mention} pinged you [**here**]({ping_msgs[0].jump_url})\n\n[**Your last message**]({last_msg.jump_url})", color=discord.Color.green(), ))) log.info("Success!") else: log.info("Ghost pinged") log.info("Sending response") await ctx.send(embed=discord.Embed( title=":ghost: Not found!", description= f"I didn't find anyone. You probably got ***ghost pinged***\n\n[**Your last message**]({last_msg.jump_url})", color=discord.Color.red(), ).set_footer(text="Imagine ghost pinging")) log.info("Success!") log.info("END OF `igotpinged`")