Skip to content

Editing Commands

Editing commands require an already initialized Dispike instance and are available as a method provided by Dispike.

Bulk editing is available by setting the bulk parameter to True and passing a list of DiscordCommand to the new_command parameter.

Editing a single command can be done by passing a DiscordCommand to new_command and specifying the target command ID.

Guild-level editing command is available by configuring parameters

  • guild_only -> True
  • guild_id_passed -> GUILD ID
Info

Follow this Discord guide to find your server/guild ID


from dispike import Dispike
from dispike.creating import (
    DiscordCommand
)


bot = Dispike(...)

bot.edit_command(
    new_command=DiscordCommand(...),
    command_id=12345
)
from dispike import Dispike
from dispike.creating.models import DiscordCommand


bot = Dispike(...)

edit_bulk_commands = [DiscordCommand(...), DiscordCommand(...)]

bot.edit_command(
    new_command=edit_bulk_commands,
    bulk=True
)

API Reference


Edits a command provided with a command_id and a valid new command.

Parameters:

Name Type Description Default
command_id Union[int, dispike.incoming.incoming_interactions.IncomingApplicationCommand]

Command ID

None
new_command Union[List[dispike.creating.models.options.DiscordCommand], dispike.creating.models.options.DiscordCommand]

A valid DiscordCommand object (or a dict with proper syntax, if a dict is passed no verification will be made and discord will return the syntax error)

required
guild_only bool

whether to target a guild. Defaults to False.

False
guild_id_passed bool

guild id if guild_only is set to True. Defaults to None.

False
bulk bool

Whether to specifiy if this action will be a bulk action.

False

Returns:

Type Description
DiscordCommand

DiscordCommand: Returns the DiscordCommand object created. (Will return a DiscordCommand irregardless of new_command)

Exceptions:

Type Description
TypeError

Invalid types passed.

DiscordAPIError

any Discord returned errors.

Source code in dispike/main.py
@logger.catch(reraise=True, message="Issue with editing commands from Discord")
def edit_command(
    self,
    new_command: typing.Union[typing.List[DiscordCommand], DiscordCommand],
    command_id: typing.Union[int, IncomingApplicationCommand] = None,
    bulk=False,
    guild_only=False,
    guild_id_passed=False,
) -> DiscordCommand:
    """Edits a command provided with a command_id and a valid new command.

    Args:
        command_id (int): Command ID
        new_command ([DiscordCommand, List[DiscordCommand]]): A valid DiscordCommand object (or a dict with proper syntax, if a dict is passed no verification will be made and discord will return the syntax error)
        guild_only (bool, optional): whether to target a guild. Defaults to False.
        guild_id_passed (bool, optional): guild id if guild_only is set to True. Defaults to None.
        bulk (bool, optional): Whether to specifiy if this action will be a bulk action.

    Returns:
        DiscordCommand: Returns the DiscordCommand object created. (Will return a DiscordCommand irregardless of new_command)

    Raises:
        TypeError: Invalid types passed.
        DiscordAPIError: any Discord returned errors.
    """


    if command_id:
        if isinstance(command_id, IncomingApplicationCommand):
            command_id = command_id.id
        elif isinstance(command_id, (str, int)):
            command_id = int(command_id)
        else:
            raise TypeError("The command ID must be either an interger or an IncomingApplicationCommand object.")

    if not isinstance(new_command, (DiscordCommand, dict, list)):
        raise TypeError("New command must be a DiscordCommand or a valid dict.")

    if guild_only:
        if not guild_id_passed:
            raise TypeError(
                "You cannot have guild_only set to True and NOT pass any guild id."
            )
        if bulk:
            _url = f"/guilds/{guild_id_passed}/commands"
        else:
            _url = f"/guilds/{guild_id_passed}/commands/{command_id}"
    else:
        _url = "/commands"
    if bulk == True and isinstance(new_command, list):
        _new_command = [command.dict() for command in new_command]
        _selected_request_method = "PUT"
    else:
        _new_command = new_command.dict()
        _selected_request_method = "PATCH"
    try:
        _send_request = self._registrator._client.request(
            method=_selected_request_method,
            url=_url,
            headers=self._registrator.request_headers,
            json=_new_command,
        )
        if _send_request.status_code != 200:
            raise DiscordAPIError(_send_request.status_code, _send_request.text)

        if bulk:
            return [DiscordCommand(**x) for x in _send_request.json()]
        else:
            return DiscordCommand(**_send_request.json())
    except DiscordAPIError:
        # TODO: Maybe don't return false and just raise it?
        logger.exception("Discord API Failure.")
        return False

Handling Permissions

Permissions are a new feature in Discord that allow bot developers to add permissions for a command.

Dispike can help you - View permissions for a command in a guild. - Craft the correct syntax for setting a permission (or multiple) for a command.

Preface

It's helpful that you read the documentation for Discord to understand how to craft permissions.. Not reading the documentation may result in you creating dangerous commands for a server!

Getting Started

Import the following:

from dispike.creating.models.permissions import (
    ApplicationCommandPermissions,
    NewApplicationPermission,
    ApplicationCommandPermissionType,
)

Sample Code

new_permission = NewApplicationPermission(
    permissions=[
        ApplicationCommandPermissions(
            id="<Discord User Id>",
            type=ApplicationCommandPermissionType.USER,
            permission=True, # Whether to determine if the user has permission.
        )
    ]
)

get_commands = bot.get_commands(guild_only=True, guild_id_passed="<Guild ID>")
selected_command = get_commands[0]


update_permission_for_command = bot.set_command_permission(
        command_id=selected_command.id # also can be passed manually
    guild_id="<Guild ID>",
    new_permission
)

print(update_permission_for_command)
>> True

The example above starts out with creating a new command using NewApplicationPermission. If you read the documentation, it should look familiar to the example provided by Discord -- except for the type that is passed.

You can manually use a normal int value for type parameter, otherwise you can use a helper class called ApplicationCommandPermissionType.

The permission type of the Application Command.

Info

​ Remember -- You are able to have multiple permissions as the permissions parameter is a List. However you should note Discord's docs about how certain permissions may conflict and throw an error. In a future version dispike may alert you of offending permissions, but for now keep in mind.

Afterwards, we need a command to edit, we check this by gathering every command in a guild. If you are not familiar with this, you can read more here.

There is a function available in the bot instance that will allow you to update a commands permission. This function is also available in sync & async.

Set a permissions for a command in a specific guild. This function is sync!

Parameters:

Name Type Description Default
command_id Union[int, dispike.incoming.incoming_interactions.IncomingApplicationCommand]

Either a command id int or a IncomingApplicationCommand (obtained from .get_command)

required
guild_id int

The guild to be targeted.

required
new_permissions NewApplicationPermission

Permissions for this command.

required

Returns:

Type Description
bool

bool: True, if the command has been successfully edited.

Source code in dispike/main.py
def set_command_permission(
    self, command_id: typing.Union[int, IncomingApplicationCommand], guild_id: int, new_permissions: "NewApplicationPermission"
) -> bool:
    """Set a permissions for a command in a specific guild. This function is sync!

    Args:
        command_id (typing.Union[int, IncomingApplicationCommand]): Either a command id int or a IncomingApplicationCommand (obtained from .get_command)
        guild_id (int): The guild to be targeted.
        new_permissions (NewApplicationPermission): Permissions for this command.

    Returns:
        bool: True, if the command has been successfully edited.
    """

    if isinstance(command_id, IncomingApplicationCommand):
        command_id = command_id.id
    elif isinstance(command_id, (str, int)):
        command_id = int(command_id)
    else:
        raise TypeError("The command ID must be either an interger or an IncomingApplicationCommand object.")

    with httpx.Client() as client:
        try:

            _set_command_permissions = client.put(
                f"https://discord.com/api/v8/applications/{self._application_id}/guilds/{guild_id}/commands/{command_id}/permissions",
                json=new_permissions.dict(),
                headers=self.return_bot_token_headers(),
            )
            _set_command_permissions.raise_for_status()
            return True
        except httpx.HTTPError:
            logger.exception(
                f"Unable to set permission for command {command_id} for guild {guild_id}"
            )
            logger.debug(
                f"request: {_set_command_permissions.status_code}: {_set_command_permissions.text}"
            )
            return False

Overwriting Commands

If you prefer to overwrite an existing commands, you can