diff --git a/.gitea/workflows/build_develop.yml b/.gitea/workflows/build_develop.yml index a9f721a..b83d756 100644 --- a/.gitea/workflows/build_develop.yml +++ b/.gitea/workflows/build_develop.yml @@ -12,6 +12,12 @@ jobs: fetch-depth: 0 - name: Install Docker uses: https://github.com/papodaca/install-docker-action@v1 + - name: Log into container registry + uses: docker/login-action@v2 + with: + registry: gitea.cheezers.org + username: imcompiling + password: ${{ secrets.PASSWORD }} - name: Build Docker Image run: docker build -t gitea.cheezers.org/imcompiling/dakiny-bot:develop . - name: Push Docker Image diff --git a/.gitea/workflows/build_latest.yml b/.gitea/workflows/build_latest.yml index a04a2fc..0a7dc01 100644 --- a/.gitea/workflows/build_latest.yml +++ b/.gitea/workflows/build_latest.yml @@ -14,6 +14,12 @@ jobs: fetch-depth: 0 - name: Install Docker uses: https://github.com/papodaca/install-docker-action@v1 + - name: Log into container registry + uses: docker/login-action@v2 + with: + registry: gitea.cheezers.org + username: imcompiling + password: ${{ secrets.PASSWORD }} - name: Build Docker Image run: docker build -t gitea.cheezers.org/imcompiling/dakiny-bot:latest . - name: Push Docker Image diff --git a/cogs/commands/__init__.py b/cogs/commands/__init__.py index 6f55dc7..9ebd402 100644 --- a/cogs/commands/__init__.py +++ b/cogs/commands/__init__.py @@ -4,6 +4,7 @@ Cog loader. Adds all command cogs to the bot. from nextcord.ext import commands +from cogs.commands.request import RequestCog from cogs.commands.test import TestCog @@ -13,4 +14,5 @@ def setup(bot: commands.Bot): """ Adds all command classes to bot. """ + bot.add_cog(RequestCog(bot)) bot.add_cog(TestCog(bot)) diff --git a/cogs/commands/request.py b/cogs/commands/request.py new file mode 100644 index 0000000..7a4f69f --- /dev/null +++ b/cogs/commands/request.py @@ -0,0 +1,103 @@ +""" +Contains commands and views for request commands. +""" + +import nextcord +from nextcord.ext import commands + +from config import DakinyConfig + + +class RequestCog(commands.Cog, name="Request Commands"): + """ + Class holds request commands. + """ + + def __init__(self, bot) -> None: + """ + Default constructor for RequestCog class. Does nothing. + """ + self.bot: commands.Bot = bot + + @nextcord.slash_command() + async def request(self, interaction: nextcord.Interaction): + """ + Parent slash command for help. Never called. + """ + + @request.subcommand(description="Request to change your Dakiny nickname") + async def change_nickname( + self, + interaction: nextcord.Interaction, + new_nickname: str = nextcord.SlashOption( + required=True, min_length=2, max_length=32, description="Your requested new nickname." + ), + ): + """ + Sends a message to admins to request a nickname change. + + Args: + interaction (nextcord.Interaction): Interaction that invoked the command. + new_username(str): The username to change to. + """ + + config: DakinyConfig = self.bot.config + content = f'<@{interaction.user.id}> would like to change their username to "{new_nickname}."' + view = UsernameRequest(interaction.user.id, new_nickname) + await self.bot.get_channel(config.params.admin_channel_id).send(content=content, view=view) + await interaction.response.send_message("Request sent to admins.", ephemeral=True) + + +class UsernameRequest(nextcord.ui.View): + """ + View provides approve and deny buttons and action for a username change request. + """ + + def __init__(self, user_id: int, new_nickname: str, *, timeout: float | None = 180, auto_defer: bool = True): + super().__init__(timeout=timeout, auto_defer=auto_defer) + self.user_id = user_id + self.new_nickname = new_nickname + + @nextcord.ui.button(label="Approve", style=nextcord.ButtonStyle.green) + async def approve(self, button: nextcord.ui.Button, interaction: nextcord.Interaction): + """ + Approve button for a nickname change request. Changes the target's nickname to self.new_nickname. + Catches an error if the target as a higher role than the bot. + Removes the view from the interaction message. + + Args: + button (nextcord.ui.Button): Unused. + interaction (nextcord.Interaction): The interaction of the user clicking the button. + """ + user = interaction.guild.get_member(self.user_id) + if user is not None: + try: + await user.edit(nick=self.new_nickname) + content = interaction.message.content + f"\nApproved by <@{interaction.user.id}>." + await interaction.response.edit_message(content=content, view=None) + except nextcord.errors.Forbidden: + await interaction.response.send_message( + content="Please change manually.", + ephemeral=True, + ) + content = ( + interaction.message.content + + "\n\nFailed. User has too high permissions for bot to change nickname." + ) + await interaction.followup.edit_message(interaction.message.id, content=content, view=None) + else: + await interaction.response.edit_message( + content="An error occured while changing the user's nickname.", view=None + ) + + @nextcord.ui.button(label="Deny", style=nextcord.ButtonStyle.red) + async def deny(self, button: nextcord.ui.Button, interaction: nextcord.Interaction): + """ + Deny button for a nickname request. Just removes the view and logs who denied the request. + + Args: + button (nextcord.ui.Button): Unused. + interaction (nextcord.Interaction): The interaction of the user clicking the button. + """ + content = interaction.message.content + f"\nDenied by <@{interaction.user.id}.>" + await interaction.response.edit_message(content=content, view=None) diff --git a/config.py b/config.py index 979ac75..d2715ec 100644 --- a/config.py +++ b/config.py @@ -11,6 +11,7 @@ class Params: """ active_category_id: int + admin_channel_id: int annoucement_category_id: int archive_channel_group_id: int clan_council_elect_role_id: int diff --git a/dakiny_bot.py b/dakiny_bot.py index 1cf8a18..fb7bba8 100644 --- a/dakiny_bot.py +++ b/dakiny_bot.py @@ -26,7 +26,7 @@ def main(cfg: DakinyConfig): # intents.guilds = True # To enable the members priveleged intent: - # intents.members = True + intents.members = True bot = commands.Bot(intents=intents) bot.config = cfg diff --git a/permissions_required.txt b/permissions_required.txt index bc1e455..0f473fe 100644 --- a/permissions_required.txt +++ b/permissions_required.txt @@ -1,4 +1,6 @@ Discord permissions required for bot to operate: manage channels -manage roles \ No newline at end of file +manage roles +manage nicknames +need member intent \ No newline at end of file