Add improved docs for slash commands (#77)
* Fix command checks actually working * Current progress on slash command docs * Improve docs for slash commands further
This commit is contained in:
parent
d16d2d856f
commit
3260ec6643
@ -1008,27 +1008,50 @@ class Greedy(List[T]):
|
|||||||
return cls(converter=converter)
|
return cls(converter=converter)
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
class Option(Generic[T, DT]): # type: ignore
|
||||||
|
"""A special 'converter' to apply a description to slash command options.
|
||||||
|
|
||||||
|
For example in the following code:
|
||||||
|
|
||||||
|
.. code-block:: python3
|
||||||
|
|
||||||
|
@bot.command()
|
||||||
|
async def ban(ctx,
|
||||||
|
member: discord.Member, *,
|
||||||
|
reason: str = commands.Option('no reason', description='the reason to ban this member')
|
||||||
|
):
|
||||||
|
await member.ban(reason=reason)
|
||||||
|
|
||||||
|
The description would be ``the reason to ban this member`` and the default would be ``no reason``
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
------------
|
||||||
|
default: Optional[Any]
|
||||||
|
The default for this option, overwrites Option during parsing.
|
||||||
|
description: :class:`str`
|
||||||
|
The description for this option, is unpacked to :attr:`.Command.option_descriptions`
|
||||||
|
"""
|
||||||
|
|
||||||
|
description: DT
|
||||||
|
default: Union[T, inspect._empty]
|
||||||
|
__slots__ = (
|
||||||
|
"default",
|
||||||
|
"description",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, default: T = inspect.Parameter.empty, *, description: DT) -> None:
|
||||||
|
self.description = description
|
||||||
|
self.default = default
|
||||||
|
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
# Terrible workaround for type checking reasons
|
||||||
def Option(default: T = inspect.Parameter.empty, *, description: str) -> T:
|
def Option(default: T = inspect.Parameter.empty, *, description: str) -> T:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
class Option(Generic[T, DT]):
|
|
||||||
description: DT
|
|
||||||
default: Union[T, inspect.Parameter.empty]
|
|
||||||
__slots__ = (
|
|
||||||
"default",
|
|
||||||
"description",
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, default: T = inspect.Parameter.empty, *, description: DT) -> None:
|
|
||||||
self.description = description
|
|
||||||
self.default = default
|
|
||||||
|
|
||||||
|
|
||||||
def _convert_to_bool(argument: str) -> bool:
|
def _convert_to_bool(argument: str) -> bool:
|
||||||
lowered = argument.lower()
|
lowered = argument.lower()
|
||||||
if lowered in ("yes", "y", "true", "t", "1", "enable", "on"):
|
if lowered in ("yes", "y", "true", "t", "1", "enable", "on"):
|
||||||
|
@ -132,7 +132,7 @@ application_option_type_lookup = {
|
|||||||
discord.Member,
|
discord.Member,
|
||||||
discord.User,
|
discord.User,
|
||||||
): 6, # Preferably discord.abc.User, but 'Protocols with non-method members don't support issubclass()'
|
): 6, # Preferably discord.abc.User, but 'Protocols with non-method members don't support issubclass()'
|
||||||
(discord.abc.GuildChannel, discord.DMChannel): 7,
|
(discord.abc.GuildChannel, discord.Thread): 7,
|
||||||
discord.Role: 8,
|
discord.Role: 8,
|
||||||
float: 10,
|
float: 10,
|
||||||
}
|
}
|
||||||
@ -330,11 +330,16 @@ class Command(_BaseCommand, Generic[CogT, P, T]):
|
|||||||
This overwrites the global ``slash_commands`` parameter of :class:`.Bot`.
|
This overwrites the global ``slash_commands`` parameter of :class:`.Bot`.
|
||||||
|
|
||||||
.. versionadded:: 2.0
|
.. versionadded:: 2.0
|
||||||
slash_command_guilds: Optional[:class:`List[int]`]
|
slash_command_guilds: Optional[List[:class:`int`]]
|
||||||
If this is set, only upload this slash command to these guild IDs.
|
If this is set, only upload this slash command to these guild IDs.
|
||||||
|
|
||||||
This overwrites the global ``slash_command_guilds`` parameter of :class:`.Bot`.
|
This overwrites the global ``slash_command_guilds`` parameter of :class:`.Bot`.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
option_descriptions: Dict[:class:`str`, :class:`str`]
|
||||||
|
The unpacked option descriptions from :class:`.Option`.
|
||||||
|
|
||||||
.. versionadded:: 2.0
|
.. versionadded:: 2.0
|
||||||
"""
|
"""
|
||||||
__original_kwargs__: Dict[str, Any]
|
__original_kwargs__: Dict[str, Any]
|
||||||
|
@ -429,6 +429,12 @@ Converters
|
|||||||
|
|
||||||
.. autofunction:: discord.ext.commands.run_converters
|
.. autofunction:: discord.ext.commands.run_converters
|
||||||
|
|
||||||
|
Option
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: discord.ext.commands.Option
|
||||||
|
:members:
|
||||||
|
|
||||||
Flag Converter
|
Flag Converter
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -61,12 +61,6 @@ the name to something other than the function would be as simple as doing this:
|
|||||||
async def _list(ctx, arg):
|
async def _list(ctx, arg):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
Slash Commands
|
|
||||||
--------------
|
|
||||||
Slash Commands can be enabled in the :class:`.Bot` constructor or :class:`.Command` constructor, using
|
|
||||||
``slash_commands=True`` or ``slash_command=True`` respectfully. All features of the commands extension
|
|
||||||
should work with these options enabled, however many will not have direct discord counterparts and therefore
|
|
||||||
will be subsituted for supported versions when uploaded to discord.
|
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
------------
|
------------
|
||||||
@ -140,6 +134,11 @@ at all:
|
|||||||
Since the ``args`` variable is a :class:`py:tuple`,
|
Since the ``args`` variable is a :class:`py:tuple`,
|
||||||
you can do anything you would usually do with one.
|
you can do anything you would usually do with one.
|
||||||
|
|
||||||
|
.. admonition:: Slash Command Only
|
||||||
|
|
||||||
|
This functionally is currently not supported by the slash command API, so is turned into
|
||||||
|
a single ``STRING`` parameter on discord's end which we do our own parsing on.
|
||||||
|
|
||||||
Keyword-Only Arguments
|
Keyword-Only Arguments
|
||||||
++++++++++++++++++++++++
|
++++++++++++++++++++++++
|
||||||
|
|
||||||
@ -186,7 +185,8 @@ know how the command was executed. It contains a lot of useful information:
|
|||||||
The context implements the :class:`abc.Messageable` interface, so anything you can do on a :class:`abc.Messageable` you
|
The context implements the :class:`abc.Messageable` interface, so anything you can do on a :class:`abc.Messageable` you
|
||||||
can do on the :class:`~ext.commands.Context`.
|
can do on the :class:`~ext.commands.Context`.
|
||||||
|
|
||||||
.. warning::
|
.. admonition:: Slash Command Only
|
||||||
|
|
||||||
:attr:`.Context.message` will be fake if in a slash command, it is not
|
:attr:`.Context.message` will be fake if in a slash command, it is not
|
||||||
recommended to access if :attr:`.Context.interaction` is not None as most
|
recommended to access if :attr:`.Context.interaction` is not None as most
|
||||||
methods will error due to the message not actually existing.
|
methods will error due to the message not actually existing.
|
||||||
@ -412,47 +412,55 @@ specify.
|
|||||||
Under the hood, these are implemented by the :ref:`ext_commands_adv_converters` interface. A table of the equivalent
|
Under the hood, these are implemented by the :ref:`ext_commands_adv_converters` interface. A table of the equivalent
|
||||||
converter is given below:
|
converter is given below:
|
||||||
|
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| Discord Class | Converter |
|
| Discord Class | Converter | Supported By Slash Commands |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`Object` | :class:`~ext.commands.ObjectConverter` |
|
| :class:`Object` | :class:`~ext.commands.ObjectConverter` | Not currently |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`Member` | :class:`~ext.commands.MemberConverter` |
|
| :class:`Member` | :class:`~ext.commands.MemberConverter` | Yes, as type 6 (USER) |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`User` | :class:`~ext.commands.UserConverter` |
|
| :class:`User` | :class:`~ext.commands.UserConverter` | Yes, as type 6 (USER) |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`Message` | :class:`~ext.commands.MessageConverter` |
|
| :class:`Message` | :class:`~ext.commands.MessageConverter` | Not currently |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`PartialMessage` | :class:`~ext.commands.PartialMessageConverter` |
|
| :class:`PartialMessage` | :class:`~ext.commands.PartialMessageConverter` | Not currently |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`.GuildChannel` | :class:`~ext.commands.GuildChannelConverter` |
|
| :class:`.GuildChannel` | :class:`~ext.commands.GuildChannelConverter` | Yes, as type 7 (CHANNEL) |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`TextChannel` | :class:`~ext.commands.TextChannelConverter` |
|
| :class:`TextChannel` | :class:`~ext.commands.TextChannelConverter` | Yes, as type 7 (CHANNEL) |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`VoiceChannel` | :class:`~ext.commands.VoiceChannelConverter` |
|
| :class:`VoiceChannel` | :class:`~ext.commands.VoiceChannelConverter` | Yes, as type 7 (CHANNEL) |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`StageChannel` | :class:`~ext.commands.StageChannelConverter` |
|
| :class:`StageChannel` | :class:`~ext.commands.StageChannelConverter` | Yes, as type 7 (CHANNEL) |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`StoreChannel` | :class:`~ext.commands.StoreChannelConverter` |
|
| :class:`StoreChannel` | :class:`~ext.commands.StoreChannelConverter` | Yes, as type 7 (CHANNEL) |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`CategoryChannel` | :class:`~ext.commands.CategoryChannelConverter` |
|
| :class:`CategoryChannel` | :class:`~ext.commands.CategoryChannelConverter` | Yes, as type 7 (CHANNEL) |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`Invite` | :class:`~ext.commands.InviteConverter` |
|
| :class:`Thread` | :class:`~ext.commands.ThreadConverter` | Yes, as type 7 (CHANNEL) |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`Guild` | :class:`~ext.commands.GuildConverter` |
|
| :class:`Invite` | :class:`~ext.commands.InviteConverter` | Not currently |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`Role` | :class:`~ext.commands.RoleConverter` |
|
| :class:`Guild` | :class:`~ext.commands.GuildConverter` | Not currently |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`Game` | :class:`~ext.commands.GameConverter` |
|
| :class:`Role` | :class:`~ext.commands.RoleConverter` | Yes, as type 8 (ROLE) |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`Colour` | :class:`~ext.commands.ColourConverter` |
|
| :class:`Game` | :class:`~ext.commands.GameConverter` | Not currently |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`Emoji` | :class:`~ext.commands.EmojiConverter` |
|
| :class:`Colour` | :class:`~ext.commands.ColourConverter` | Not currently |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`PartialEmoji` | :class:`~ext.commands.PartialEmojiConverter` |
|
| :class:`Emoji` | :class:`~ext.commands.EmojiConverter` | Not currently |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
| :class:`Thread` | :class:`~ext.commands.ThreadConverter` |
|
| :class:`PartialEmoji` | :class:`~ext.commands.PartialEmojiConverter` | Not currently |
|
||||||
+--------------------------+-------------------------------------------------+
|
+--------------------------+-------------------------------------------------+-----------------------------+
|
||||||
|
|
||||||
|
.. admonition:: Slash Command Only
|
||||||
|
|
||||||
|
If a slash command is not marked on the table above as supported, it will be sent as type 3 (STRING)
|
||||||
|
and parsed by normal content parsing, see
|
||||||
|
`the discord documentation <https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-type>`_
|
||||||
|
for all supported types by the API.
|
||||||
|
|
||||||
|
|
||||||
By providing the converter it allows us to use them as building blocks for another converter:
|
By providing the converter it allows us to use them as building blocks for another converter:
|
||||||
|
|
||||||
@ -499,6 +507,10 @@ then a special error is raised, :exc:`~ext.commands.BadUnionArgument`.
|
|||||||
|
|
||||||
Note that any valid converter discussed above can be passed in to the argument list of a :data:`typing.Union`.
|
Note that any valid converter discussed above can be passed in to the argument list of a :data:`typing.Union`.
|
||||||
|
|
||||||
|
.. admonition:: Slash Command Only
|
||||||
|
|
||||||
|
These are not currently supported by the Discord API and will be sent as type 3 (STRING)
|
||||||
|
|
||||||
typing.Optional
|
typing.Optional
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@ -692,6 +704,11 @@ In order to customise the flag syntax we also have a few options that can be pas
|
|||||||
a command line parser. The syntax is mainly inspired by Discord's search bar input and as a result
|
a command line parser. The syntax is mainly inspired by Discord's search bar input and as a result
|
||||||
all flags need a corresponding value.
|
all flags need a corresponding value.
|
||||||
|
|
||||||
|
.. admonition:: Slash Command Only
|
||||||
|
|
||||||
|
As these are built very similar to slash command options, they are converted into options and parsed
|
||||||
|
back into flags when the slash command is executed.
|
||||||
|
|
||||||
The flag converter is similar to regular commands and allows you to use most types of converters
|
The flag converter is similar to regular commands and allows you to use most types of converters
|
||||||
(with the exception of :class:`~ext.commands.Greedy`) as the type annotation. Some extra support is added for specific
|
(with the exception of :class:`~ext.commands.Greedy`) as the type annotation. Some extra support is added for specific
|
||||||
annotations as described below.
|
annotations as described below.
|
||||||
|
@ -15,4 +15,5 @@ extension library that handles this for you.
|
|||||||
commands
|
commands
|
||||||
cogs
|
cogs
|
||||||
extensions
|
extensions
|
||||||
|
slash-commands
|
||||||
api
|
api
|
||||||
|
23
docs/ext/commands/slash-commands.rst
Normal file
23
docs/ext/commands/slash-commands.rst
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
.. currentmodule:: discord
|
||||||
|
|
||||||
|
.. _ext_commands_slash_commands:
|
||||||
|
|
||||||
|
Slash Commands
|
||||||
|
==============
|
||||||
|
|
||||||
|
Slash Commands are currently supported in enhanced-discord.py using a system on top of ext.commands.
|
||||||
|
|
||||||
|
This system is very simple to use, and can be enabled via :attr:`.Bot.slash_commands` globally,
|
||||||
|
or only for specific commands via :attr:`.Command.slash_command`.
|
||||||
|
|
||||||
|
There is also the parameter ``slash_command_guilds`` which can be passed to either :class:`.Bot` or the command
|
||||||
|
decorator in order to only upload the commands as guild commands to these specific guild IDs, however this
|
||||||
|
should only be used for testing or small (<10 guilds) bots.
|
||||||
|
|
||||||
|
If you want to add option descriptions to your commands, you should use :class:`.Option`
|
||||||
|
|
||||||
|
For troubleshooting, see the :ref:`FAQ <ext_commands_slash_command_troubleshooting>`
|
||||||
|
|
||||||
|
.. admonition:: Slash Command Only
|
||||||
|
|
||||||
|
For parts of the docs specific to slash commands, look for this box!
|
31
docs/faq.rst
31
docs/faq.rst
@ -410,3 +410,34 @@ Example: ::
|
|||||||
await ctx.send(f'Pushing to {remote} {branch}')
|
await ctx.send(f'Pushing to {remote} {branch}')
|
||||||
|
|
||||||
This could then be used as ``?git push origin master``.
|
This could then be used as ``?git push origin master``.
|
||||||
|
|
||||||
|
How do I make slash commands?
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
See :doc:`/ext/commands/slash-commands`
|
||||||
|
|
||||||
|
My slash commands aren't showing up!
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. _ext_commands_slash_command_troubleshooting:
|
||||||
|
|
||||||
|
You need to invite your bot with the ``application.commands`` scope on each guild and
|
||||||
|
you need the :attr:`Permissions.use_slash_commands` permission in order to see slash commands.
|
||||||
|
|
||||||
|
.. image:: /images/discord_oauth2_slash_scope.png
|
||||||
|
:alt: The scopes checkbox with "bot" and "applications.commands" ticked.
|
||||||
|
|
||||||
|
Global slash commands (created by not specifying :attr:`~ext.commands.Bot.slash_command_guilds`) will also take up an
|
||||||
|
hour to refresh on discord's end, so it is recommended to set :attr:`~ext.commands.Bot.slash_command_guilds` for development.
|
||||||
|
|
||||||
|
If none of this works, make sure you are actually running enhanced-discord.py by doing ``print(bot.slash_commands)``
|
||||||
|
|
||||||
|
My bot won't start after enabling slash commands!
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This means some of your command metadata is invalid for slash commands.
|
||||||
|
Make sure your command names and option names are lowercase, and they have to match the regex ``^[\w-]{1,32}$``
|
||||||
|
|
||||||
|
If you cannot figure out the problem, you should disable slash commands globally (:attr:`~ext.commands.Bot.slash_commands`\=False)
|
||||||
|
then go through commands, enabling them specifically with :attr:`~.commands.Command.slash_command`\=True until it
|
||||||
|
errors, then you can debug the problem with that command specifically.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user