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
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