async def info(self, ctx: interactions.CommandContext): embed = interactions.Embed( title="Info", footer=interactions.EmbedFooter( text="This bot is maintained by the interactions.py ext team." ), fields=[ interactions.EmbedField( name="What is this for?", value="".join([ "Astro is the main bot powering moderation and other utilities in the interactions.py support server.", " The goal of Astro is to make searching simple, and automate our moderation process. Whether that's creating tags with", " autocompleted suggestions, code examples, or interactive tutorials: Astro has you covered. Interactions should be simple to understand,", " and coding them is no different.", ]), ), interactions.EmbedField( name="What does this bot run on?", value="".join([ f"This project is built with interactions.py `{interactions.base.__version__}`, the no. 1 leading Python interactions library that", " empowers bots with the ability to implement slash commands and components with ease. The codebase of this bot reflects how simple,", " modular and scalable the library is---staying true to the motto of what it does.", ]), ), interactions.EmbedField( name="How can I contribute to this bot?", value= "Please check out the official GitHub repository which holds the source code of this bot here: https://github.com/interactions-py/Astro", ), ], ) await ctx.send(embeds=embed)
async def on_guild_member_remove(self, member: interactions.GuildMember): embed = interactions.Embed( title="User left", color=0xED4245, thumbnail=interactions.EmbedImageStruct(url=member.user.avatar_url, height=256, width=256)._json, author=interactions.EmbedAuthor( name=f"{member.user.username}#{member.user.discriminator}", icon_url=member.user.avatar_url, ), fields=[ interactions.EmbedField(name="ID", value=str(member.user.id)), interactions.EmbedField( name="Timestamps", value="\n".join( [ f"Joined: <t:{round(member.joined_at.timestamp())}:R>.", f"Created: <t:{round(member.id.timestamp.timestamp())}:R>.", ] ), ), ] ) _channel: dict = await self.bot._http.get_channel(src.const.METADATA["channels"]["mod-logs"]) channel = interactions.Channel(**_channel, _client=self.bot._http) await channel.send(embeds=embed)
async def _list_tag(self, ctx: interactions.CommandContext): """Lists all the tags existing in the database.""" db = self._tags log.debug("Matched for list. Returning result...") embed = interactions.Embed( title="Tags list", description="This is the current list of existing tags.", color=0x5865F2, fields=[ interactions.EmbedField( name="Names", value=" ", inline=True, ), interactions.EmbedField( name="(cont.)", value=" ", inline=True, ), ], ) _last_name: str = "" _id: int = 0 for tag in db: if (len(tag) + len(embed.fields[0].value)) < 900: embed.fields[0].value += f"` {_id} ` {tag}" else: break _last_name = tag _id += 1 if _id < len(db): ... paginator = interactions.ActionRow( components=[ interactions.Button( style=interactions.ButtonStyle.PRIMARY, label="Previous", emoji=interactions.Emoji(id=None, name="⬅️", animated=False), custom_id="list_navigate_left", ), interactions.Button( style=interactions.ButtonStyle.PRIMARY, label="Next", emoji=interactions.Emoji(id=None, name="➡️", animated=False), custom_id="list_navigate_right", disabled=True if len(embed.fields[0].value) <= 900 else False, ), ] ) await ctx.send(embeds=embed, components=paginator)
async def on_message_create(self, message: interactions.Message): tags = [ tag.strip("#") for tag in message.content.split() if tag.startswith("#") ] with contextlib.suppress(IndexError): if message.author.id == self.bot.me.id or message.author.bot or tags[ 0] == "" or not tags[0].isnumeric(): return async with aiohttp.ClientSession() as session: async with session.get(self.url + tags[0], headers=self.headers) as resp: response: dict = await resp.json() if len(response.keys()) == 2: return print(response.keys()) created_at, merged_at, closed_at = self._timestamps(response) body, tasks, checklist = self._create_fields(response) description = self._description(response, created_at, merged_at, closed_at) message._client = self.bot._http if checklist and tasks: fields = [ interactions.EmbedField(name="**About**", value=body), interactions.EmbedField(name="**Tasks**", value=tasks, inline=True), interactions.EmbedField(name="**Checklist**", value=checklist, inline=True) ] else: value = re.sub( "\[[^\s]]", "✔️", "\n".join(body.split("\n")[:7]).replace( "[ ]", "❌")) + "\n**...**" fields = [ interactions.EmbedField(name="*Description:*", value=value) ] await message.reply(embeds=interactions.Embed( title=response['title'], url=response['html_url'], description=description, color=self._color(response), footer=interactions.EmbedFooter( text=response["user"]["login"], icon_url=response["user"]["avatar_url"]), fields=fields))
async def _untimeout_member(self, ctx: interactions.CommandContext, member: interactions.Member, reason: str = "N/A"): """Untimeouts a member in the server and logs into the database.""" await ctx.defer(ephemeral=True) db = self._actions id = len(list(db.items())) + 1 action = src.model.Action( id=id, type=src.model.ActionType.TIMEOUT, moderator=ctx.author, user=member.user, reason=reason ) db.update({str(id): action._json}) self.actions.find_one_and_update({"id": MOD_ID}, {"$set": {"actions": db}}) await self.get_actions() embed = interactions.Embed( title="User untimed out", color=0xFEE75C, author=interactions.EmbedAuthor( name=f"{member.user.username}#{member.user.discriminator}", icon_url=member.user.avatar_url, ), fields=[ interactions.EmbedField( name="Moderator", value=f"{ctx.author.mention} ({ctx.author.user.username}#{ctx.author.user.discriminator})", inline=True, ), interactions.EmbedField( name="Timestamps", value="\n".join( [ f"Joined: <t:{round(member.joined_at.timestamp())}:R>.", f"Created: <t:{round(member.id.timestamp.timestamp())}:R>.", ] ), ), interactions.EmbedField(name="Reason", value="N/A" if reason is None else reason), ] ) _channel: dict = await self.bot._http.get_channel(src.const.METADATA["channels"]["action-logs"]) channel = interactions.Channel(**_channel, _client=self.bot._http) if member.communication_disabled_until is None: return await ctx.send(f":x: {member.mention} is not timed out.", ephemeral=True) await member.modify(guild_id=ctx.guild_id, communication_disabled_until=None) await channel.send(embeds=embed) await ctx.send(f":heavy_check_mark: {member.mention} has been untimed out.", ephemeral=True)
async def _kick_member(self, ctx: interactions.CommandContext, member: interactions.Member, reason: str = "N/A"): """Bans a member from the server and logs into the database.""" await ctx.defer(ephemeral=True) db = self._actions id = len(list(db.items())) + 1 action = src.model.Action( id=id, type=src.model.ActionType.KICK, moderator=ctx.author, user=member.user, reason=reason ) db.update({str(id): action._json}) self.actions.find_one_and_update({"id": MOD_ID}, {"$set": {"actions": db}}) await self.get_actions() embed = interactions.Embed( title="User kicked", color=0xED4245, author=interactions.EmbedAuthor( name=f"{member.user.username}#{member.user.discriminator}", icon_url=member.user.avatar_url, ), fields=[ interactions.EmbedField( name="Moderator", value=f"{ctx.author.mention} ({ctx.author.user.username}#{ctx.author.user.discriminator})", inline=True, ), interactions.EmbedField( name="Timestamps", value="\n".join( [ f"Joined: <t:{round(member.joined_at.timestamp())}:R>.", f"Created: <t:{round(member.id.timestamp.timestamp())}:R>.", ] ), ), interactions.EmbedField(name="Reason", value=reason), ] ) _channel: dict = await self.bot._http.get_channel(src.const.METADATA["channels"]["action-logs"]) channel = interactions.Channel(**_channel, _client=self.bot._http) await member.kick(guild_id=src.const.METADATA["guild"], reason=reason) await channel.send(embeds=embed) await ctx.send(f":heavy_check_mark: {member.mention} has been kicked.", ephemeral=True)
async def _info_tag(self, ctx: interactions.CommandContext, name: str): """Gathers information about a tag that currently exists within the database.""" db = self._tags log.debug("Matched for info. Returning result...") if db.get(name): _author: dict = await self.bot._http.get_user(db[name]["author"]) author = interactions.User(**_author) embed = interactions.Embed( title="\"" + name + "\"" if "\"" not in name else name, color=0x5865F2, footer=interactions.EmbedFooter(text=" ".join([ "Tags are made and maintained by the Helpers here in the support server.", "Please contact one if you believe one is incorrect." ])), fields=[ interactions.EmbedField( name="Author", value=author.mention, inline=True, ), interactions.EmbedField( name="ID", value=db[name]["id"], inline=True, ), interactions.EmbedField( name="Timestamps", value="\n".join([ f"Created: <t:{round(db[name]['created_at'])}:R>.", "Last edited: " + ( f"<t:{round(db[name]['last_edited_at'])}:R>." if db[name].get("last_edited_at") else "N/A" ) ]), inline=True ), interactions.EmbedField(name="Content", value="Please use `/tag view`."), ], ) await ctx.send(embeds=embed)
async def on_message_delete(self, message: interactions.Message): embed = interactions.Embed( title="Message deleted", color=0xED4245, author=interactions.EmbedAuthor( name=f"{message.author.username}#{message.author.discriminator}", icon_url=message.author.avatar_url ), fields=[ interactions.EmbedField(name="ID", value=str(message.author.id), inline=True), interactions.EmbedField( name="Message", value=message.content if message.content else "**Message could not be retrieved.**" ), ], ) _channel: dict = await self.bot._http.get_channel(src.const.METADATA["channels"]["mod-logs"]) channel = interactions.Channel(**_channel, _client=self.bot._http) await channel.send(embeds=embed)
async def _unban_member(self, ctx: interactions.CommandContext, id: int, reason: str = "N/A"): """Unbans a user from the server and logs into the database.""" await ctx.defer(ephemeral=True) db = self._actions _id = len(list(db.items())) + 1 _user: dict = await self.bot._http.get_user(id=id) user = interactions.User(**_user) action = src.model.Action( id=_id, type=src.model.ActionType.KICK, moderator=ctx.author, user=user, reason=reason ) db.update({str(_id): action._json}) self.actions.find_one_and_update({"id": MOD_ID}, {"$set": {"actions": db}}) await self.get_actions() embed = interactions.Embed( title="User unbanned", color=0x57F287, author=interactions.EmbedAuthor( name=f"{user.username}#{user.discriminator}", icon_url=user.avatar_url, ), fields=[ interactions.EmbedField( name="Moderator", value=f"{ctx.author.mention} ({ctx.author.user.username}#{ctx.author.user.discriminator})", inline=True, ), interactions.EmbedField(name="Reason", value=reason), ] ) _guild: dict = await self.bot._http.get_guild(src.const.METADATA["guild"]) guild = interactions.Guild(**_guild, _client=self.bot._http) _channel: dict = await self.bot._http.get_channel(src.const.METADATA["channels"]["action-logs"]) channel = interactions.Channel(**_channel, _client=self.bot._http) await guild.remove_ban(user_id=id, reason=reason) await channel.send(embeds=embed) await ctx.send(f":heavy_check_mark: {user.mention} has been unbanned.", ephemeral=True)
async def get_user_info(self, ctx: interactions.CommandContext): embed = interactions.Embed( title="User Information", description="This is the retrieved information on the user.", thumbnail=interactions.EmbedImageStruct( url=ctx.target.user.avatar_url, height=256, width=256)._json, author=interactions.EmbedAuthor( name=f"{ctx.target.user.username}", url=f"https://discord.com/users/{ctx.target.user.id}", icon_url=ctx.target.user.avatar_url, ), fields=[ interactions.EmbedField( name="Username", value= f"{ctx.target.user.username}#{ctx.target.user.discriminator}", inline=True, ), interactions.EmbedField(name="ID", value=str(ctx.target.user.id), inline=True), interactions.EmbedField( name="Timestamps", value="\n".join([ f"Joined: <t:{round(ctx.target.joined_at.timestamp())}:R>.", f"Created: <t:{round(ctx.target.id.timestamp.timestamp())}:R>.", ]), inline=True, ), interactions.EmbedField( name="Roles", value=(", ".join([ f"<@&{role}>" for role in ctx.target.roles ]) if isinstance(ctx.target, interactions.Member) and ctx.target.roles else "`N/A`"), ), ], ) await ctx.send(embeds=embed, ephemeral=True)
async def _help_thread_modal( self, ctx: interactions.CommandContext, thread_name: str, content: str, extra_content: str | None = None, ): target: interactions.Message = self.targets.pop(int(ctx.author.id)) target._json["content"] = content attachments = False if target._json["attachments"]: del target._json["attachments"] attachments = True _thread: dict = await self.bot._http.create_forum_thread( self=self.bot._http, auto_archive_duration=1440, name=thread_name, channel_id=src.const.METADATA["channels"]["help"], applied_tags=["996215708595794071"], message_payload=target._json, reason="Auto help thread creation" ) ch = await interactions.get(self.bot, interactions.Channel, object_id=src.const.METADATA["channels"]["help"]) _tags = ch._extras["available_tags"] _options: list[interactions.SelectOption] = [ interactions.SelectOption( label=tag["name"], value=tag["id"], emoji=interactions.Emoji( name=tag["emoji_name"], ) if tag["emoji_name"] else None ) for tag in _tags ] select = interactions.SelectMenu( custom_id="TAG_SELECTION", placeholder="Select the tags you want", options=_options, min_values=0, max_values=len(_options), ) thread = interactions.Channel(**_thread, _client=self.bot._http) await thread.add_member(int(ctx.author.id)) await thread.add_member(int(target.author.id)) embed = None if extra_content: embed = interactions.Embed( title="Additional Information:", color=0xFEE75C, timestamp=target.timestamp, description=extra_content ) embed.set_footer(text="Please create a thread in #help to ask questions!") button = interactions.Button( style=interactions.ButtonStyle.LINK, label="Original message", url=target.url ) _ars = [interactions.ActionRow.new(button), interactions.ActionRow.new(select)] await thread.send( "This help thread was automatically generated. Read the message above for more information.", embeds=embed, components=_ars ) if attachments: await thread.send( f"Hey {target.author.mention}! We detected an attachment on your message! Due to discord being buggy, " f"we could not automatically transfer it to this thread. Please re-upload it here!" ) await ctx.send( f"Hey, {target.author.mention}! At this time, we only help with support-related questions in our help " f"channel. Please redirect to {thread.mention} in order to receive help." ) await ctx.send(":white_check_mark: Thread created.", ephemeral=True)