Example #1
0
 def __init__(self):
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
     self.category = "Administration"
     self.arguments = [{
         "prompt":
         "Would you like to alter/disable the join messages for **verified** or **unverified** users?",
         "type":
         "choice",
         "components": [
             discord.ui.Select(
                 max_values=1,
                 options=[
                     discord.SelectOption(
                         label="Verified users",
                         description="Change the message for verified users."
                     ),
                     discord.SelectOption(
                         label="Unverified users",
                         description=
                         "Change the message for unverified users."),
                 ])
         ],
         "choices": ("Verified users", "Unverified users"),
         "name":
         "subcommand"
     }]
     self.hidden = True
     self.aliases = ["join-channel"]
Example #2
0
 def __init__(self):
     self.category = "Administration"
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
     self.arguments = [
         {
             "prompt": "Bloxlink supports advanced nicknaming of users. I'll show you "
                       "the different types of nicknames and how to change them.\n\n"
                       f"``Bind Nickname`` {ARROW} when you link groups, you're given the "
                       "option to change nicknames of group members. Bloxlink will choose the "
                       "person's **highest role** which has an available Bind Nickname. Bind "
                       "Nicknames can be applied from ``{prefix}bind``. If no bind nicknames "
                       "apply to the user, then the **Global Nickname** is used instead.\n"
                       f"``Global Nickname`` {ARROW} the default nickname used if someone has **NO** "
                       "available Bind Nicknames. This can be applied from this command and "
                       "``{prefix}settings change`` (look for \"Nickname Template\").",
             "name": "_",
             "type": "choice",
             "choices": ("next",),
             "footer": "Say **next** to change your Global Nickname."
         },
         {
             "prompt": "What would you like your Global Nickname to be? Remember, this nickname "
                       "will be used if someone has no available Bind Nickname from the ``{prefix}bind`` "
                       "command. You may combine templates. Templates: ```" + ESCAPED_NICKNAME_TEMPLATES + "```",
             "footer": "Say **skip** to leave this as the default nickname.",
             "name": "global_nickname"
         }
     ]
Example #3
0
    def __init__(self):
        permission = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        permission.allow_bypass = True

        self.permissions = permission
        self.category = "Administration"
        self.aliases = ["config"]
Example #4
0
    def __init__(self):
        self.arguments = [{
            "prompt":
            "Would you like to **change** your log channels (add/delete), or **view** your "
            "current log channels?",
            "name":
            "choice",
            "type":
            "choice",
            "components": [
                discord.ui.Select(
                    max_values=1,
                    options=[
                        discord.SelectOption(
                            label="Change log channels",
                            description="Add/delete a log channel."),
                        discord.SelectOption(
                            label="View log channels",
                            description="View your log channels.")
                    ])
            ],
            "choices":
            ["change log channels", "add", "delete", "view log channels"]
        }]

        self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        self.category = "Administration"
        self.aliases = ["logchannels", "log-channel", "log-channels"]
        self.slash_enabled = True
Example #5
0
 def __init__(self):
     self.type = 2
     self.name = "Update User"
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_UPDATER")
     self.slash_defer = True
     self.slash_ephemeral = True
     self.premium_bypass_channel_perms = True
Example #6
0
 def __init__(self):
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
     self.category = "Administration"
     self.aliases = ["restriction"]
     self.slash_enabled = True
     self.slash_only = True
     self._remove_data_regex = re.compile("(.*)-(.*)")
Example #7
0
    def __init__(self):
        permissions = Bloxlink.Permissions().build("BLOXLINK_UPDATER")
        permissions.allow_bypass = True

        self.permissions = permissions
        self.aliases = ["update", "updateroles", "update-user"]
        self.arguments = [{
            "prompt":
            "Please specify user(s) or role(s) to update. For example: `@user1 @user2 @user3` or `@role`",
            "type": ["user", "role"],
            "name": "users",
            "multiple": True,
            "optional": True,
            "create_missing_role": False
        }]
        self.slash_args = [{
            "prompt": "Please select the user to update.",
            "name": "user",
            "type": "user",
            "optional": True
        }, {
            "prompt": "Please select the role of members to update.",
            "name": "role",
            "type": "role",
            "optional": True
        }]
        self.category = "Administration"
        self.cooldown = 2
        self.REDIS_COOLDOWN_KEY = "guild_scan:{id}"
        self.slash_enabled = True
        self.slash_ack = True
Example #8
0
    def __init__(self):
        self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        self.category = "Administration"
        self.aliases = ["restriction"]
        self.slash_enabled = True

        self._roblox_group_regex = re.compile(r"roblox.com/groups/(\d+)/")
Example #9
0
    def __init__(self):
        self.arguments = [{
            "prompt":
            "Please specify the **Group ID** to integrate with. The group ID is the rightmost numbers on your Group URL.",
            "slash_desc": "Please enter your Group ID.",
            "name": "groupID",
            "type": "number",
        }, {
            "prompt":
            "Please specify the **role name** to bind non-group members. A role will be created if it doesn't already exist.",
            "slash_desc":
            "Please choose the role to bind to non-group members.",
            "name": "role",
            "type": "role"
        }, {
            "prompt":
            "Should these members be given a nickname different from the server-wide `!nickname`? Please specify a nickname, or "
            "say `skip` to skip this option and default to the server-wide nickname `!nickname` template.\n\nYou may use these templates:"
            f"```{NICKNAME_TEMPLATES}```",
            "slash_desc":
            "Please enter a nickname to give to these members.  Say skip to skip this option.",
            "name":
            "nickname",
            "type":
            "string",
            "max":
            100,
            "formatting":
            False
        }]

        self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        self.category = "Binds"
        self.aliases = ["guestbind", "guest-role", "guest-bind"]
        self.slash_enabled = True
Example #10
0
    def __init__(self):
        self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        self.category = "Administration"
        self.aliases = ["addon"]
        self.hidden = True

        self.addons = {}

        self.load_addons()
Example #11
0
    def __init__(self):
        self.arguments = [{
            "prompt":
            "Please specify the **Group ID** to integrate with. The group ID is the rightmost numbers on your Group URL.",
            "slash_desc": "Please enter your Group ID.",
            "name": "group_id",
            "type": "number",
        }, {
            "prompt":
            "Please specify the **role name** to bind non-group members. A role will be created if it doesn't already exist.",
            "slash_desc":
            "Please choose the role to bind to non-group members.",
            "name": "role",
            "type": "role"
        }, {
            "prompt":
            "Should these members be given a nickname different from the server-wide `!nickname`? Please specify a nickname, or "
            "say `skip` to skip this option and default to the server-wide nickname `!nickname` template.\n\nYou may use these templates:"
            f"```{NICKNAME_TEMPLATES}```",
            "slash_desc":
            "Please enter a nickname to give to these members.",
            "slash_optional":
            True,
            "name":
            "nickname",
            "type":
            "string",
            "max":
            100,
            "formatting":
            False
        }, {
            "prompt":
            "Should any roles be **removed from the user** if they aren't in the group? You can specify multiple roles.\n\n"
            "Note that this is an **advanced option**, so you most likely should `skip` this.",
            "slash_desc":
            "Should any roles be removed from the user?",
            "name":
            "remove_roles",
            "slash_optional":
            True,
            "multiple":
            True,
            "type":
            "role",
            "max":
            10,
            "exceptions": ("skip", ),
            "footer":
            "Say **skip** to skip this option."
        }]

        self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        self.category = "Binds"
        self.aliases = ["guestbind", "guest-role", "guest-bind"]
        self.slash_enabled = True
Example #12
0
    def __init__(self):
        self.arguments = [{
            "prompt": "Please specify the group ID that this bind resides in. If this is not a group, " \
             "specify the bind type found on ``{prefix}viewbinds``(e.g. \"assets\").",
            "name": "bind_id"
        }]

        self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        self.category = "Binds"
        self.aliases = ["delbind", "delbinds"]
Example #13
0
 def __init__(self):
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
     self.category = "Administration"
     self.arguments = [{
         "prompt": "Would you like to alter/disable the DM messages for **verified** or **unverified** users?",
         "type": "choice",
         "choices": ("verified", "unverified"),
         "name": "subcommand"
     }]
     self.hidden = True
Example #14
0
 def __init__(self):
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
     self.category = "Premium"
     self.arguments = [
         {
             "prompt": "Would you like to **backup** your Server Data, or "
                       "**restore** your Data from a backup?",
             "name": "subcommand_choice",
             "type": "choice",
             "choices": ("backup", "restore")
         }
     ]
Example #15
0
    def __init__(self):
        self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        self.category = "Administration"
        self.aliases = ["addon"]

        self.arguments = [{
            "prompt":
            "Would you like to **view** the available add-ons, or **change** (enable/disable) an add-on?",
            "name": "subcommand",
            "type": "choice",
            "choices": ["view", "change", "enable", "disable"]
        }]
Example #16
0
 def __init__(self):
     self.examples = ["1", "569422833", "blox_link"]
     self.arguments = [{
         "prompt":
         "Please specify either a username or Roblox ID. If the person's name is all numbers, "
         "then attach a ``--username`` flag to this command. Example: ``!getinfo 1234 --username`` will "
         "search for a user with a Roblox username of '1234' instead of a Roblox ID.",
         "name":
         "target"
     }]
     self.category = "Administration"
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
Example #17
0
    def __init__(self):
        self.arguments = [
            {
                "prompt": "This command will kick people who join your server and aren't in these groups. They must be in __ALL__ of these groups.\n"
                          "Would you like to **add** a new group, **delete** a group, or **view** your current groups?",
                "name": "choice",
                "type": "choice",
                "choices": ["add", "delete", "view"]
            }
        ]

        self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        self.category = "Administration"
Example #18
0
 def __init__(self):
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MODERATOR")
     self.arguments = [
         {
             "prompt": "This command will scan your server members for members with Roblox accounts which correspond to banned members of your server.\n\n"
                       "Would you like to **ban** ban-evaders, **kick** them, or do **nothing**?\n\nI will provide a list of members if you choose the `nothing` option.",
             "type": "choice",
             "name": "action",
             "choices": ("kick", "ban", "nothing")
         }
     ]
     self.category = "Premium"
     self.REDIS_COOLDOWN_KEY = "guild_scan:{id}"
     self.aliases = ["bansearch"]
Example #19
0
    def __init__(self):
        self.arguments = [{
            "prompt": "Please specify a new prefix.",
            "name": "new_prefix",
            "max": 10,
            "optional": True
        }]
        self.examples = ["?"]

        permission = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        permission.allow_bypass = True

        self.permissions = permission
        self.category = "Administration"
Example #20
0
    def __init__(self):
        self.arguments = [{
            "prompt":
            "Would you like to **change** your log channels (add/delete), or **view** your "
            "current log channels?",
            "name":
            "choice",
            "type":
            "choice",
            "choices": ["change", "add", "delete", "view"]
        }]

        self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        self.category = "Administration"
        self.aliases = ["logchannels"]
Example #21
0
    def __init__(self):
        self.arguments = [{
            "prompt":
            "Please choose the type of bind to delete.",
            "components": [
                discord.ui.Select(
                    max_values=1,
                    options=[
                        discord.SelectOption(
                            label="Group", description="Remove a Group bind."),
                        discord.SelectOption(
                            label="Asset",
                            description="Remove a Catalog Asset bind."),
                        discord.SelectOption(
                            label="Badge", description="Remove a Badge bind."),
                        discord.SelectOption(
                            label="GamePass",
                            description="Remove a GamePass bind."),
                        discord.SelectOption(
                            label="DevForum Members",
                            description="Remove a DevForum bind."),
                        discord.SelectOption(
                            label="Roblox Staff",
                            description="Remove a Roblox Staff bind."),
                    ])
            ],
            "type":
            "choice",
            "choices": ("group", "asset", "badge", "gamepass",
                        "devforum members", "roblox staff"),
            "name":
            "bind_category"
        }, {
            "prompt":
            "Please specify the **{bind_category[0]} ID** to delete.",
            "type":
            "number",
            "name":
            "bind_id",
            "show_if":
            lambda c: c["bind_category"][0] not in
            ("roblox staff", "devforum members")
        }]

        self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        self.category = "Binds"
        self.aliases = ["delbind", "delbinds", "un-bind", "del-bind"]
        self.slash_enabled = True
Example #22
0
 def __init__(self):
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
     self.category = "Premium"
     self.arguments = [{
         "prompt": "Magic Roles allow you to create roles that have special abilities within Bloxlink.\n\n"
                   "Would you like to **add** a new magic role, **view** your existing magic roles, or "
                   "**delete** an existing magic role?",
         "type": "choice",
         "components": [discord.ui.Select(max_values=1, options=[
                 discord.SelectOption(label="Add a new Magic Role"),
                 discord.SelectOption(label="View Magic Roles"),
                 discord.SelectOption(label="Delete a Magic Role"),
             ])],
         "choices": ("add a new magic role", "view magic roles", "delete a magic role"),
         "name": "subcommand"
     }]
     self.hidden = True
     self.aliases = ["magicrole", "magicroles", "magic-roles"]
     self.free_to_use = True
Example #23
0
    def __init__(self):
        self.arguments = [
            {
                "prompt": "This command will kick people who join your server and aren't in these groups. They must be in __ALL__ of these groups.\n"
                          "Would you like to **add** a new group, **delete** a group, or **view** your current groups?",
                "name": "choice",
                "type": "choice",
                "components": [discord.ui.Select(max_values=1, options=[
                        discord.SelectOption(label="Add a new group", description="Add a new group to your group-lock."),
                        discord.SelectOption(label="Delete a group", description="Delete a group from your group-lock."),
                        discord.SelectOption(label="View groups", description="View your group-lock."),
                    ])],
                "choices": ["add a new group", "delete a group", "view groups"]
            }
        ]

        self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
        self.category = "Administration"
        self.aliases = ["group-lock", "serverlock", "server-lock"]
        self._range_search = re.compile(r"([0-9]+)\-([0-9]+)")
Example #24
0
 def __init__(self):
     self.aliases = ["enable"]
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
     self.category = "Administration"
     self.arguments = [{
         "prompt":
         "Please specify the **command name** to be enabled/disabled.",
         "type": "choice",
         "choices": commands.keys(),
         "name": "command_name"
     }, {
         "prompt":
         "Should this command be enabled/disabled **globally** or **for a channel?**\n"
         "You may either say `globally` or mention a `channel`.",
         "type": ["channel", "choice"],
         "create_missing_channel":
         False,
         "name":
         "disable_type",
         "choices": ["globally", "global"]
     }]
Example #25
0
    def __init__(self):
        permissions = Bloxlink.Permissions().build("BLOXLINK_UPDATER")
        permissions.allow_bypass = True

        self.permissions = permissions
        self.aliases = ["update", "updateroles", "update-user"]
        self.arguments = [{
            "prompt": "Please select the user to update.",
            "name": "user",
            "type": "user",
            "optional": True
        }, {
            "prompt": "Please select the role of members to update.",
            "name": "role",
            "type": "role",
            "optional": True
        }]
        self.category = "Administration"
        self.cooldown = 2
        self.REDIS_COOLDOWN_KEY = "guild_scan:{id}"
        self.slash_enabled = True
        self.slash_defer = True
        self.slash_only = True
Example #26
0
 def __init__(self):
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
     self.aliases = ["verificationchannel"]
     self.category = "Administration"
Example #27
0
 def __init__(self):
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
     self.category = "Premium"
     self.hidden = True
     self.aliases = ["magicrole", "magicroles", "magic-roles"]
     self.free_to_use = True
Example #28
0
 def __init__(self):
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
     self.category = "Administration"
Example #29
0
 def __init__(self):
     self.aliases = ["newbind"]
     self.permissions = Bloxlink.Permissions().build("BLOXLINK_MANAGER")
     self.category = "Binds"
     self.slash_enabled = True
Example #30
0
class VerifyCommand(Bloxlink.Module):
    """link your Roblox account to your Discord account and get your server roles"""
    def __init__(self):
        self.examples = ["add", "unlink", "view", "blox_link"]
        self.category = "Account"
        self.cooldown = 5
        self.dm_allowed = True
        self.slash_enabled = True

    @staticmethod
    async def validate_username(message, content):
        try:
            roblox_id, username = await get_roblox_id(content)
        except RobloxNotFound:
            return None, "There was no Roblox account found with that username. Please try again."

        return username

    @Bloxlink.flags
    async def __main__(self, CommandArgs):
        trello_board = CommandArgs.trello_board
        guild_data = CommandArgs.guild_data
        guild = CommandArgs.guild
        author = CommandArgs.author
        response = CommandArgs.response
        prefix = CommandArgs.prefix

        if not guild:
            return await self.add(CommandArgs)

        if CommandArgs.flags.get("add") or CommandArgs.flags.get(
                "verify") or CommandArgs.flags.get("force"):
            await CommandArgs.response.error(
                f"`{CommandArgs.prefix}verify --force` is deprecated and will be removed in a future version of Bloxlink. "
                f"Please use `{prefix}verify add` instead.")

            return await self.add(CommandArgs)

        if CommandArgs.real_command_name in ("getrole", "getroles"):
            CommandArgs.string_args = []

        trello_options = {}

        if trello_board:
            trello_options, _ = await get_options(trello_board)
            guild_data.update(trello_options)

        try:
            old_nickname = author.display_name

            added, removed, nickname, errors, roblox_user = await guild_obligations(
                CommandArgs.author,
                guild=guild,
                guild_data=guild_data,
                roles=True,
                nickname=True,
                trello_board=CommandArgs.trello_board,
                given_trello_options=True,
                cache=False,
                response=response,
                dm=False,
                exceptions=("BloxlinkBypass", "Blacklisted", "UserNotVerified",
                            "PermissionError"))

        except BloxlinkBypass:
            raise Message(
                "Since you have the `Bloxlink Bypass` role, I was unable to update your roles/nickname.",
                type="info")

        except Blacklisted as b:
            if isinstance(b.message, str):
                raise Error(
                    f"{author.mention} has an active restriction for: `{b}`")
            else:
                raise Error(
                    f"{author.mention} has an active restriction from Bloxlink."
                )

        except UserNotVerified:
            await self.add(CommandArgs)

        except PermissionError as e:
            raise Error(e.message)

        else:
            welcome_message, embed = await format_update_embed(
                roblox_user,
                author,
                added=added,
                removed=removed,
                errors=errors,
                nickname=nickname
                if old_nickname != author.display_name else None,
                prefix=prefix,
                guild_data=guild_data)

            if embed:
                await post_event(
                    guild, guild_data, "verification",
                    f"{author.mention} ({author.id}) has **verified** as `{roblox_user.username}`.",
                    GREEN_COLOR)
            else:
                embed = Embed(
                    description=
                    "This user is all up-to-date; no changes were made.")

            await response.send(content=welcome_message, embed=embed)

    @Bloxlink.subcommand()
    async def add(self, CommandArgs):
        """link a new account to Bloxlink"""

        author = CommandArgs.author

        if CommandArgs.guild:
            guild_data = CommandArgs.guild_data

            if not guild_data.get("hasBot"):
                guild_data["hasBot"] = True

                await self.r.table("guilds").insert(guild_data,
                                                    conflict="update").run()

            response_text = f"{author.mention}, to verify with Bloxlink, please visit our website at " \
                            f"<{VERIFY_URL}>. It won't take long!\nStuck? See this video: <https://www.youtube.com/watch?v=hq496NmQ9GU>"
        else:
            response_text = "To verify with Bloxlink, please visit our website at " \
                            f"<{VERIFY_URL}>. It won't take long!\nStuck? See this video: <https://www.youtube.com/watch?v=hq496NmQ9GU>"

        await CommandArgs.response.send(response_text)

    @Bloxlink.subcommand(
        permissions=Bloxlink.Permissions().build("BLOXLINK_MANAGER"))
    async def customize(self, CommandArgs):
        """customize the behavior of !verify"""

        # TODO: able to set: "forced groups"

        prefix = CommandArgs.prefix
        response = CommandArgs.response

        author = CommandArgs.author

        guild = CommandArgs.guild
        guild_data = CommandArgs.guild_data

        if not guild:
            return await response.send(
                "This sub-command can only be used in a server!")

        choice = (await CommandArgs.prompt([{
            "prompt":
            "Which option would you like to change?\nOptions: `(welcomeMessage)`",
            "name": "choice",
            "type": "choice",
            "choices": ("welcomeMessage", )
        }]))["choice"]

        trello_board = CommandArgs.trello_board
        card = None

        if trello_board:
            options_trello_data, trello_binds_list = await get_options(
                trello_board, return_cards=True)
            options_trello_find = options_trello_data.get(choice)

            if options_trello_find:
                card = options_trello_find[1]

        if choice == "welcomeMessage":
            welcome_message = (await CommandArgs.prompt([{
                "prompt":
                f"What would you like your welcome message to be? This will be shown in `{prefix}verify` messages.\nYou may "
                f"use these templates: ```{NICKNAME_TEMPLATES}```",
                "name":
                "welcome_message",
                "formatting":
                False,
                "max":
                1500
            }],
                                                        last=True)
                               )["welcome_message"]

            if trello_board and trello_binds_list:
                try:
                    if card:
                        if card.name == choice:
                            await card.edit(name="welcomeMessage",
                                            desc=welcome_message)
                    else:
                        trello_settings_list = await trello_board.get_list(lambda L: L.name == "Bloxlink Settings") \
                                            or await trello_board.create_list(name="Bloxlink Settings")

                        await trello_settings_list.create_card(
                            name="welcomeMessage", desc=welcome_message)

                    await trello_binds_list.sync(
                        card_limit=TRELLO["CARD_LIMIT"])

                except TrelloUnauthorized:
                    await response.error(
                        "In order for me to edit your Trello settings, please add `@bloxlink` to your "
                        "Trello board.")

                except (TrelloNotFound, TrelloBadRequest):
                    pass

            await self.r.table("guilds").insert(
                {
                    "id": str(guild.id),
                    "welcomeMessage": welcome_message
                },
                conflict="update").run()

        await post_event(
            guild, guild_data, "configuration",
            f"{author.mention} ({author.id}) has **changed** the `{choice}`.",
            BROWN_COLOR)

        raise Message(f"Successfully saved your new `{choice}`!",
                      type="success")

    @staticmethod
    @Bloxlink.subcommand()
    async def view(CommandArgs):
        """view your linked account(s)"""

        author = CommandArgs.author
        response = CommandArgs.response

        try:
            primary_account, accounts = await get_user("username",
                                                       author=author,
                                                       everything=False,
                                                       basic_details=True)
        except UserNotVerified:
            raise Message("You have no accounts linked to Bloxlink!",
                          type="silly")
        else:
            accounts = list(accounts)

            parsed_accounts = await parse_accounts(accounts,
                                                   reverse_search=True)
            parsed_accounts_str = []
            primary_account_str = "No primary account set"

            for roblox_username, roblox_data in parsed_accounts.items():
                if roblox_data[1]:
                    username_str = []

                    for discord_account in roblox_data[1]:
                        username_str.append(
                            f"{discord_account} ({discord_account.id})")

                    username_str = ", ".join(username_str)

                    if primary_account and roblox_username == primary_account.username:
                        primary_account_str = f"**{roblox_username}** {ARROW} {username_str}"
                    else:
                        parsed_accounts_str.append(
                            f"**{roblox_username}** {ARROW} {username_str}")

                else:
                    parsed_accounts_str.append(f"**{roblox_username}**")

            parsed_accounts_str = "\n".join(parsed_accounts_str)

            embed = Embed(title="Linked Roblox Accounts")
            embed.add_field(name="Primary Account", value=primary_account_str)
            embed.add_field(name="Secondary Accounts",
                            value=parsed_accounts_str
                            or "No secondary account saved")
            embed.set_author(name=author, icon_url=author.avatar_url)

            await response.send(embed=embed, dm=True, strict_post=True)

    @staticmethod
    @Bloxlink.subcommand()
    async def unlink(CommandArgs):
        """unlink an account from Bloxlink"""

        if CommandArgs.guild:
            await CommandArgs.response.reply(
                f"to manage your accounts, please visit our website: <{ACCOUNT_SETTINGS_URL}>"
            )
        else:
            await CommandArgs.response.send(
                f"To manage your accounts, please visit our website: <{ACCOUNT_SETTINGS_URL}>"
            )