コード例 #1
0
    async def role_joinable(self, ctx, *roles: RoleConv):
        """ Allows a moderator to add roles to the self-assignable group. """

        logger.info(
            "Adding joinable roles for guild '%s' (%d): [%s]",
            ctx.guild.name,
            ctx.guild.id,
            ", ".join(role.name for role in roles),
        )

        if not roles:
            raise CommandFailed()

        # Get special roles
        special_roles = self.bot.sql.settings.get_special_roles(ctx.guild)

        # Ensure none of the roles grant any permissions
        for role in roles:
            embed = permissions.elevated_role_embed(ctx.guild, role, "error")
            if embed is not None:
                raise ManualCheckFailure(embed=embed)

            for attr in ("member", "guest", "mute", "jail"):
                if role == getattr(special_roles, attr):
                    embed = discord.Embed(colour=discord.Colour.red())
                    embed.set_author(name="Cannot add role as assignable")
                    embed.description = (
                        f"{role.mention} cannot be self-assignable, "
                        f"it is already used as the **{attr}** role!")
                    raise ManualCheckFailure(embed=embed)

        # Get roles that are already assignable
        assignable_roles = self.bot.sql.roles.get_assignable_roles(ctx.guild)

        # Add roles to database
        with self.bot.sql.transaction():
            for role in roles:
                if role not in assignable_roles:
                    self.bot.sql.roles.add_assignable_role(ctx.guild, role)

        # Send response
        embed = discord.Embed(colour=discord.Colour.dark_teal())
        embed.set_author(name="Made roles joinable")
        descr = StringBuilder(sep=", ")
        for role in roles:
            descr.write(role.mention)
        embed.description = str(descr)
        await ctx.send(embed=embed)

        # Send journal event
        content = f"Roles were set as joinable: {self.str_roles(roles)}"
        self.journal.send("joinable/add",
                          ctx.guild,
                          content,
                          icon="role",
                          roles=roles)
コード例 #2
0
ファイル: alert.py プロジェクト: EllVEBIT/futaba-1
    async def alert_add(self, ctx, attribute: str, relationship: str, *,
                        amount: str):
        """
        Adds a join alert with the given condition.

        Possible attributes: id, created, name, discrim, avatar, status
        Possible relationships: > >= = != < <= ~
        """

        logging.info(
            "Got request to add new join alert for '%s' (%d)",
            ctx.guild.name,
            ctx.guild.id,
        )

        try:
            key = JoinAlertKey.parse(attribute)
        except ValueError:
            raise ManualCheckFailure(content=f"Invalid attribute: {attribute}")

        try:
            op = ValueRelationship(relationship)
        except ValueError:
            raise ManualCheckFailure(
                content=f"Invalid relationship: {relationship}")

        try:
            value = key.parse_value(amount)
        except ValueError as error:
            raise ManualCheckFailure(content=str(error))

        alert = JoinAlert(ctx.guild, None, key, op, value)
        logging.info("Adding join alert: %s", alert)

        with self.bot.sql.transaction():
            self.bot.sql.welcome.add_alert(ctx.guild, alert)

        self.alerts[alert.id] = alert

        # Notify the user
        embed = discord.Embed(colour=discord.Colour.dark_teal())
        embed.set_author(name="Successfully added join alert")
        descr = StringBuilder()
        descr.writeln(f"ID: #`{alert.id:05}`, Condition: `{alert}`")
        descr.writeln(
            "To get these notifications in a channel, add a logger for path `/welcome/alert`"
        )
        embed.description = str(descr)
        await ctx.send(embed=embed)
コード例 #3
0
ファイル: core.py プロジェクト: telugu-boy/futaba
    async def remove_other_roles_on_punish(self, ctx, value: bool = None):
        """
        Gets the current setting for whether punishment actions remove all other roles, or leaves them.
        If you're an administrator, you can change this value.
        """

        if value is None:
            remove_other_roles = self.bot.sql.settings.get_remove_other_roles(
                ctx.guild)
            embed = discord.Embed(colour=discord.Colour.dark_teal())
            state = "are removed" if remove_other_roles else "are kept"
            embed.description = (
                f"When punishment roles are added other roles **{state}**")
        elif not admin_perm(ctx):
            # Lacking authority to set remove other roles
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = "You do not have permissions to change the removal of non-punishment roles"
            raise ManualCheckFailure(embed=embed)
        else:
            with self.bot.sql.transaction():
                self.bot.sql.settings.set_remove_other_roles(ctx.guild, value)

            embed = discord.Embed(colour=discord.Colour.teal())
            embed.description = (
                f"Set removal of other non-punishment roles to `{value}`")

        await ctx.send(embed=embed)
コード例 #4
0
ファイル: core.py プロジェクト: telugu-boy/futaba
    async def reapply_auto(self, ctx, value: bool = None):
        """
        Tells whether automatic role reapplication is enabled.
        Only self-assignable and punishment roles are re-applied.
        If you're an administrator, you can change this value.
        """

        if value is None:
            # Get reapplication roles
            reapply = self.bot.sql.settings.get_auto_reapply(ctx.guild)
            embed = discord.Embed(colour=discord.Colour.dark_teal())
            enabled = "enabled" if reapply else "disabled"
            embed.description = (
                f"Automatic role reapplication is **{enabled}** on this server"
            )
        elif not admin_perm(ctx):
            # Lacking authority to set reapplication
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = (
                "You do not have permission to set automatic role reapplication"
            )
            raise ManualCheckFailure(embed=embed)
        else:
            # Set role reapplication
            with self.bot.sql.transaction():
                self.bot.sql.settings.set_auto_reapply(ctx.guild, value)

            embed = discord.Embed(colour=discord.Colour.dark_teal())
            embed.description = (
                f"{'Enabled' if value else 'Disabled'} automatic role reapplication"
            )

        await ctx.send(embed=embed)
コード例 #5
0
ファイル: core.py プロジェクト: EllVEBIT/futaba-1
    async def perform_jail(self, ctx, member, minutes, reason):
        roles = self.bot.sql.settings.get_special_roles(ctx.guild)
        if roles.jail is None:
            raise CommandFailed(content="No configured jail role")

        if member.top_role >= ctx.me.top_role:
            raise ManualCheckFailure(
                "I don't have permission to jail this user")

        if roles.jail_role in member.roles:
            raise CommandFailed(content="User is already jailed")

        # Check that users top role is not the same as the requesters top role.
        if member != ctx.author:
            if member.top_role == ctx.author.top_role:
                raise CommandFailed(
                    content="You can not jail a user with the same role as you"
                )

        minutes = max(minutes, 0)
        reason = self.build_reason(ctx, "Jailed", minutes, reason)

        await self.bot.punish.jail(ctx.guild, member, reason)

        # If a delayed event, schedule a Navi task
        if minutes:
            await self.remove_roles(ctx, member, minutes,
                                    PunishAction.RELIEVE_JAIL, reason)
コード例 #6
0
    async def filter_manage_messages(self, ctx, value: bool = None):
        """
        Gets the current setting for whether manage message members are filter immune.
        If you're an administrator, you can change this value.
        """

        if value is None:
            filter_settings = self.bot.sql.filter.get_settings(ctx.guild)
            if filter_settings.manage_messages_immune:
                result = "**are filter immune**"
            else:
                result = "are **not** filter immune"

            embed = discord.Embed(colour=discord.Colour.dark_teal())
            embed.description = f"Those with the `Manage Messages` permission {result}."
        elif not admin_perm(ctx):
            # Lacking authority to set warn manual mod action
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = "You do not have permission to enable or disable manage messages filter immunity"
            raise ManualCheckFailure(embed=embed)
        else:
            with self.bot.sql.transaction():
                self.bot.sql.filter.set_bot_filter_immunity(
                    ctx.guild, manage_messages_immune=value)

            embed = discord.Embed(colour=discord.Colour.teal())
            embed.description = (
                f"Set filter immunity for those with manage messages to `{value}`"
            )

        await ctx.send(embed=embed)
コード例 #7
0
ファイル: core.py プロジェクト: EllVEBIT/futaba-1
    async def unban(self, ctx, user: UserConv, *, reason: str):
        """
        Unbans the id from the guild with a reason.
        If guild has moderation logging enabled, it is logged
        """

        try:
            embed = discord.Embed(description="Done! User Unbanned")
            embed.add_field(name="Reason", value=reason)

            mod = user_discrim(ctx.author)
            unbanned = user_discrim(user)
            clean_reason = escape_backticks(reason)
            content = f"{mod} unbanned {user.mention} ({unbanned}) with reason: `{clean_reason}`"

            await ctx.guild.unban(user, reason=f"{reason} - {mod}")
            await ctx.send(embed=embed)

            self.journal.send("member/unban",
                              ctx.guild,
                              content,
                              icon="unban",
                              user=user)

        except discord.errors.Forbidden:
            raise ManualCheckFailure(
                content="I don't have permission to unban this user")
コード例 #8
0
ファイル: core.py プロジェクト: EllVEBIT/futaba-1
    async def perform_ban(self, ctx, user, delete_days, reason):
        if delete_days < 0 or delete_days > 7:
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = (
                f"Invalid specification for number of days to delete: `{delete_days}`. "
                "Must be between 0 and 7 inclusive.")
            await ctx.send(embed=embed)
            return

        try:
            embed = discord.Embed(colour=discord.Colour.teal())
            embed.description = (
                f"Done! {user.mention} ({user_discrim(user)}) was banned")
            embed.add_field(name="Reason", value=reason)
            embed.add_field(name="Deleted messages",
                            value=f"{delete_days} days")

            # Don't send a journal event, that is handled by the moderation journal listener

            await ctx.guild.ban(
                user,
                reason=f"{reason} - {user_discrim(ctx.author)}",
                delete_message_days=delete_days,
            )
            await ctx.send(embed=embed)

        except discord.errors.Forbidden:
            raise ManualCheckFailure(
                content="I don't have permission to ban this user")
コード例 #9
0
ファイル: core.py プロジェクト: telugu-boy/futaba
    async def warn_manual_mod_action(self, ctx, value: bool = None):
        """
        Gets the current setting for warning about manual mod actions.
        If you're an administrator, you can change this value.
        """

        if value is None:
            warn_manual_mod_action = self.bot.sql.settings.get_warn_manual_mod_action(
                ctx.guild)
            embed = discord.Embed(colour=discord.Colour.dark_teal())
            state = "enabled" if warn_manual_mod_action else "disabled"
            embed.description = f"Warning moderators about performing mod actions manually is **{state}**"
        elif not admin_perm(ctx):
            # Lacking authority to set warn manual mod action
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = "You do not have permission to enable or disable manual mod action warning"
            raise ManualCheckFailure(embed=embed)
        else:
            with self.bot.sql.transaction():
                self.bot.sql.settings.set_warn_manual_mod_action(
                    ctx.guild, value)

            embed = discord.Embed(colour=discord.Colour.teal())
            embed.description = f"Set warning moderators about performing mod actions manually to `{value}`"

        await ctx.send(embed=embed)
コード例 #10
0
    async def unmute(
        self, ctx, member: MemberConv, minutes: int = 0, *, reason: str = None
    ):
        """
        Unmutes the user, with an optional delay in minutes.
        Requires a mute role to be configured.
        Set 'minutes' to 0 to unmute immediately.
        """

        logger.info(
            "Unmuting user '%s' (%d) in %d minutes", member.name, member.id, minutes
        )

        roles = self.bot.sql.settings.get_special_roles(ctx.guild)
        if roles.mute is None:
            raise CommandFailed(content="No configured mute role")

        if member.top_role >= ctx.me.top_role:
            raise ManualCheckFailure("I don't have permission to unmute this user")

        minutes = max(minutes, 0)
        reason = self.build_reason(ctx, "Unmuted", minutes, reason, past=True)

        if minutes:
            await self.remove_roles(
                ctx, member, minutes, PunishAction.RELIEVE_MUTE, reason
            )
        else:
            await self.bot.punish.unjail(ctx.guild, member, reason)
コード例 #11
0
    async def perform_mute(self, ctx, member: MemberConv, minutes: int, reason: str = None):
        logger.info(
            "Muting user '%s' (%d) for %d minutes", member.name, member.id, minutes
        )

        if minutes <= 0:
            # Since muting prevents members from responding or petitioning staff,
            # a timed release is mandatory. Otherwise they might be forgotten
            # and muted forever.
            raise CommandFailed()

        roles = self.bot.sql.settings.get_special_roles(ctx.guild)
        if roles.mute is None:
            raise CommandFailed(content="No configured mute role")

        if member.top_role >= ctx.me.top_role:
            raise ManualCheckFailure("I don't have permission to mute this user")

        minutes = max(minutes, 0)
        reason = self.build_reason(ctx, "Muted", minutes, reason, past=True)

        await self.bot.punish.mute(ctx.guild, member, reason)

        # If a delayed event, schedule a Navi task
        if minutes:
            await self.remove_roles(
                ctx, member, minutes, PunishAction.RELIEVE_MUTE, reason
            )
コード例 #12
0
ファイル: core.py プロジェクト: EllVEBIT/futaba-1
    async def perform_unjail(self, ctx, member, minutes, reason):
        roles = self.bot.sql.settings.get_special_roles(ctx.guild)
        if roles.jail is None:
            raise CommandFailed(content="No configured jail role")

        if member.top_role >= ctx.me.top_role:
            raise ManualCheckFailure(
                "I don't have permission to unjail this user")

        if roles.jail_role not in member.roles:
            raise CommandFailed(content="User is not jailed")

        if member != ctx.author:
            if member.top_role == ctx.author.top_role:
                raise CommandFailed(
                    content=
                    "You can not unjail a user with the same role as you")

        minutes = max(minutes, 0)
        reason = self.build_reason(ctx, "Released", minutes, reason, past=True)

        if minutes:
            await self.remove_roles(ctx, member, minutes,
                                    PunishAction.RELIEVE_JAIL, reason)
        else:
            await self.bot.punish.unjail(ctx.guild, member, reason)
コード例 #13
0
ファイル: core.py プロジェクト: EllVEBIT/futaba-1
    async def nick(self, ctx, member: MemberConv, nick: str = None):
        """ Changes or reset a member's nickname. """

        logger.info("Setting the nickname of user '%s' (%d) to %r",
                    member.name, member.id, nick)

        if member.top_role >= ctx.me.top_role:
            raise ManualCheckFailure(
                "I don't have permission to nick this user")

        mod = user_discrim(ctx.author)
        await member.edit(
            nick=nick,
            reason=f"{mod} {'un' if nick is None else ''}set nickname")
コード例 #14
0
ファイル: core.py プロジェクト: EllVEBIT/futaba-1
    async def perform_focus(self, ctx, member, minutes, reason):
        roles = self.bot.sql.settings.get_special_roles(ctx.guild)
        if roles.focus is None:
            raise CommandFailed(content="No configured focus role")

        if member.top_role >= ctx.me.top_role:
            raise ManualCheckFailure(
                "I don't have permission to focus this user")

        if roles.focus_role in member.roles:
            raise CommandFailed(content="User is already focused")

        minutes = max(minutes, 0)
        reason = self.build_reason(ctx, "Focus", minutes, reason)

        await self.bot.punish.focus(ctx.guild, member, reason)
コード例 #15
0
    async def perform_jail(self, ctx, member, minutes, reason):
        roles = self.bot.sql.settings.get_special_roles(ctx.guild)
        if roles.jail is None:
            raise CommandFailed(content="No configured jail role")

        if member.top_role >= ctx.me.top_role:
            raise ManualCheckFailure("I don't have permission to jail this user")

        minutes = max(minutes, 0)
        reason = self.build_reason(ctx, "Jailed", minutes, reason)

        await self.bot.punish.jail(ctx.guild, member, reason)

        # If a delayed event, schedule a Navi task
        if minutes:
            await self.remove_roles(
                ctx, member, minutes, PunishAction.RELIEVE_JAIL, reason
            )
コード例 #16
0
    def check_roles(self, ctx, roles):
        if not roles:
            raise CommandFailed()

        assignable_roles = self.bot.sql.roles.get_assignable_roles(ctx.guild)
        for role in roles:
            if role not in assignable_roles:
                embed = discord.Embed(colour=discord.Colour.red())
                embed.set_author(name="Role not assignable")
                embed.description = f"The role {role.mention} cannot be self-assigned"
                raise CommandFailed(embed=embed)

            if role >= ctx.me.top_role:
                embed = discord.Embed(colour=discord.Colour.red())
                embed.set_author(name="Error assigning roles")
                embed.description = (
                    f"Cannot assign {role.mention}, which is above me in the hierarchy"
                )
                raise ManualCheckFailure(embed=embed)
コード例 #17
0
ファイル: core.py プロジェクト: EllVEBIT/futaba-1
    async def kick(self, ctx, user: UserConv, *, reason: str):
        """
        Kicks the user from the guild with a reason
        If guild has moderation logging enabled, it is logged
        """

        try:
            embed = discord.Embed(description="Done! User Kicked")
            embed.add_field(name="Reason", value=reason)

            # Don't send a journal event, that is handled by the moderation journal listener

            await ctx.guild.kick(
                user, reason=f"{reason} - {user_discrim(ctx.author)}")
            await ctx.send(embed=embed)

        except discord.errors.Forbidden:
            raise ManualCheckFailure(
                content="I don't have permission to kick this user")
コード例 #18
0
ファイル: core.py プロジェクト: Scrub000/futaba
    async def list_emojis(self, ctx, all_guilds=False):
        contents = []
        content = StringBuilder()

        if all_guilds:
            if not mod_perm(ctx):
                raise ManualCheckFailure(
                    content="Only moderators can do this.")

            guild_emojis = (guild.emojis for guild in self.bot.guilds)
            emojis = chain(*guild_emojis)
        else:
            emojis = ctx.guild.emojis

        logger.info("Listing all emojis within the guild")
        for emoji in emojis:
            managed = "M" if emoji.managed else ""
            content.writeln(
                f"- [{emoji}]({emoji.url}) id: `{emoji.id}`, name: `{emoji.name}` {managed}"
            )

            if len(content) > 1900:
                # Too long, break into new embed
                contents.append(str(content))

                # Start content over
                content.clear()

        if content:
            contents.append(str(content))

        for i, content in enumerate(contents):
            embed = discord.Embed(description=content,
                                  colour=discord.Colour.dark_teal())
            embed.set_footer(text=f"Page {i + 1}/{len(contents)}")

            if i == 0:
                if all_guilds:
                    embed.set_author(name="Emojis in all guilds")
                else:
                    embed.set_author(name=f"Emojis within {ctx.guild.name}")

            await ctx.send(embed=embed)
コード例 #19
0
ファイル: core.py プロジェクト: telugu-boy/futaba
    async def max_delete(self, ctx, count: int = None):
        """
        Gets the current setting for maximum messages to bulk delete.
        If you're an administrator, you can change this value.
        """

        if count is None:
            # Get max delete messages
            max_delete_messages = self.bot.sql.settings.get_max_delete_messages(
                ctx.guild)
            embed = discord.Embed(colour=discord.Colour.dark_teal())
            embed.description = f"Maximum number of messages that can be deleted in bulk is `{max_delete_messages}`"
        elif not admin_perm(ctx):
            # Lacking authority to set max delete messages
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = (
                "You do not have permission to set the maximum deletable messages"
            )
            raise ManualCheckFailure(embed=embed)
        elif count <= 0:
            # Negative value
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = "This value must be a positive, non-zero integer"
            raise CommandFailed(embed=embed)
        elif count >= 2**32 - 1:
            # Over a sane upper limit
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = (
                "This value is way too high. Try a more reasonable value.")
            raise CommandFailed(embed=embed)
        else:
            # Set max delete messages
            with self.bot.sql.transaction():
                self.bot.sql.settings.set_max_delete_messages(ctx.guild, count)

            embed = discord.Embed(colour=discord.Colour.dark_teal())
            embed.description = f"Set maximum deletable messages to `{count}`"

        await ctx.send(embed=embed)
コード例 #20
0
ファイル: core.py プロジェクト: telugu-boy/futaba
    async def mentionable_prefix(self, ctx, value: int = None):
        """
        Gets the current number of typeable characters required for your mention.
        If you're a moderator, you can change this value. (Set to 0 to disable)
        """

        if value is None:
            # Get prefix
            value = self.bot.sql.settings.get_mentionable_name_prefix(
                ctx.guild)
            embed = discord.Embed(colour=discord.Colour.dark_teal())
            embed.description = (
                f"Names must begin with at least {value} typeable character{plural(value)}"
                if value else "No guild requirement for mentionable names")
        elif not mod_perm(ctx):
            # Lacking authority to set mentionable prefix
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = (
                "You do not have permission to set the mentionable name prefix"
            )
            raise ManualCheckFailure(embed=embed)
        else:
            # Set prefix
            if value < 0 or value > 32:
                embed = discord.Embed()
                embed.colour = discord.Colour.red()
                embed.description = "Prefix lengths must be between `0` and `32`."
                raise CommandFailed(embed=embed)

            with self.bot.sql.transaction():
                self.bot.sql.settings.set_mentionable_name_prefix(
                    ctx.guild, value)

            embed = discord.Embed(colour=discord.Colour.dark_teal())
            embed.description = (
                f"Set mentionable prefix to {value} character{plural(value)}"
                if value else "Disabled mentionable prefix requirement")

        await ctx.send(embed=embed)
コード例 #21
0
ファイル: core.py プロジェクト: EllVEBIT/futaba-1
    async def softban(self, ctx, user: UserConv, *, reason: str):
        """
        Soft-bans the user from the guild with a reason.
        If guild has moderation logging enabled, it is logged

        Soft-ban is a kick that cleans up the chat
        """

        try:
            embed = discord.Embed(description="Done! User Soft-banned")
            embed.add_field(name="Reason", value=reason)

            mod = user_discrim(ctx.author)
            banned = user_discrim(user)
            clean_reason = escape_backticks(reason)
            content = f"{mod} soft-banned {user.mention} ({banned}) with reason: `{clean_reason}`"

            await ctx.guild.ban(user,
                                reason=f"{reason} - {mod}",
                                delete_message_days=1)
            await asyncio.sleep(0.1)
            await ctx.guild.unban(user, reason=f"{reason} - {mod}")
            await ctx.send(embed=embed)

            self.journal.send(
                "member/softban",
                ctx.guild,
                content,
                icon="soft",
                user=user,
                reason=reason,
                cause=ctx.author,
            )

        except discord.errors.Forbidden:
            raise ManualCheckFailure(
                content="I don't have permission to soft-ban this user")
コード例 #22
0
ファイル: core.py プロジェクト: telugu-boy/futaba
    async def prefix(self, ctx, *, prefix: str = None):
        """
        Gets the current prefix. If you're a moderator, you can set it too.
        A trailing underscore is converted into spaces. A single '_' unsets
        the bot's prefix, and uses the default one.
        """

        if prefix is None:
            # Get prefix
            bot_prefix = self.bot.prefix(ctx.guild)
            embed = discord.Embed(colour=discord.Colour.dark_teal())
            if ctx.guild is None:
                embed.description = "No command prefix, all messages are commands"
            else:
                embed.description = f"Prefix for {ctx.guild.name} is `{bot_prefix}`"
        elif ctx.guild is None and prefix is not None:
            # Attempt to set prefix outside of guild
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = "Cannot set a command prefix outside of a server!"
            raise CommandFailed(embed=embed)
        elif not mod_perm(ctx):
            # Lacking authority to set prefix
            embed = discord.Embed(colour=discord.Colour.red())
            embed.description = "You do not have permission to set the prefix"
            raise ManualCheckFailure(embed=embed)
        elif prefix == "_":
            # Unset prefix
            with self.bot.sql.transaction():
                self.bot.sql.settings.set_prefix(ctx.guild, None)
                bot_prefix = self.bot.prefix(ctx.guild)

            embed = discord.Embed(colour=discord.Colour.dark_teal())
            embed.description = (
                f"Unset prefix for {ctx.guild.name}. (Default prefix: `{bot_prefix}`)"
            )
            self.journal.send(
                "prefix",
                ctx.guild,
                "Unset bot command prefix",
                icon="settings",
                prefix=None,
                default_prefix=self.bot.config.default_prefix,
            )
        else:
            # Set prefix
            bot_prefix = re.sub(r"_$", " ", prefix)
            with self.bot.sql.transaction():
                self.bot.sql.settings.set_prefix(ctx.guild, bot_prefix)

            embed = discord.Embed(colour=discord.Colour.dark_teal())
            embed.description = f"Set prefix for {ctx.guild.name} to `{bot_prefix}`"
            self.journal.send(
                "prefix",
                ctx.guild,
                "Unset bot command prefix",
                icon="settings",
                prefix=bot_prefix,
                default_prefix=self.bot.config.default_prefix,
            )

        await ctx.send(embed=embed)