diff --git a/docs/gettingstarted.rst b/docs/gettingstarted.rst index 49e4d6a58..40a9c0a8a 100644 --- a/docs/gettingstarted.rst +++ b/docs/gettingstarted.rst @@ -1,39 +1,39 @@ Getting Started =============== -Now that things have been explained through the `quickstart`_ page for you -to begin making slash commands for your bot, now it is time to discuss some -of the much more rather advanced or complicated aspects of slash commands. -Our first discussion will be covering over the implementation of options in -your commands. +Where do we start? +****************** + +Before we begin getting started on everything else, it is recommended to +check out the `quickstart`_ page first to get a basic grip on making +slash commands for your bot. + +Making a slash command. +*********************** + +The basics. +----------- First, let's explain by how commands are parsed through the Discord Bot API. + As you may know, Discord relies a lot on the interaction of HTTP Requests and JSON tables. As is with the case here, commands are the exact same way with having JSON tables to structure the design of it for Discord to understand. We -can apply this information likewise with how options are to be designed in the -Python code. Below attached is from the *Discord Developer Portal* on Slash -Commands for showing how options are designed. - -+-------------+--------------------------------------------+----------------------------------------------------------------------------------------------------+ -| **Field** | **Type** | **Description** | -+-------------+--------------------------------------------+----------------------------------------------------------------------------------------------------+ -| type | int | value of ApplicationCommandOptionType | -+-------------+--------------------------------------------+----------------------------------------------------------------------------------------------------+ -| name | string | 1-32 character name matching ``^[\w-]{1,32}$`` | -+-------------+--------------------------------------------+----------------------------------------------------------------------------------------------------+ -| description | string | 1-100 character description | -+-------------+--------------------------------------------+----------------------------------------------------------------------------------------------------+ -| default? | bool | the first required option for the user to complete--only one option can be default | -+-------------+--------------------------------------------+----------------------------------------------------------------------------------------------------+ -| required? | bool | if the parameter is required or optional--default ``false`` | -+-------------+--------------------------------------------+----------------------------------------------------------------------------------------------------+ -| choices? | array of `ApplicationCommandOptionChoice`_ | choices for ``string`` and ``int`` types for the user to pick from | -+-------------+--------------------------------------------+----------------------------------------------------------------------------------------------------+ -| options? | array of `ApplicationCommandOption`_ | if the option is a subcommand or subcommand group type, this nested options will be the parameters | -+-------------+--------------------------------------------+----------------------------------------------------------------------------------------------------+ - -This table shows us the way that Discord handles the structure of options for +can apply this information likewise with how slash commands are to be designed +in the Python code. Below attached is from the *Discord Developer Portal* on Slash +Commands for showing how they are designed. + ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| **Field** | **Type** | **Description** | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| name | string | 1-32 character name matching ``^[\w-]{1,32}$``. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| description | string | 1-100 character description. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| options? | array of `ApplicationCommandOption`_ | if the option is a subcommand or subcommand group type, this nested options will be the parameters. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ + +This table shows us the way that Discord handles the structure of commands for slash commands through their Bot API. For visualization purposes, we'll quickly make a JSON example (although we won't be using it) in order to explain how this works: @@ -41,53 +41,202 @@ works: .. code-block:: python { - "name": "argone", - "description": "description of first argument", - "type": 3, # STRING type, - "required": True + "name": "test", + "description": "This is just a test command, nothing more.", } -With this very basic understanding in mind, now we are able to begin programming -a simple Python script that will allow us to utilize this ability through one of -the many subclasses offered in *discord-py-slash-command*. +Now that we have a basic understanding of how the JSON table works, we can +take this knowledge and convert it into a decorator method for the Python +code as shown below: + +.. code-block:: python + + @slash.slash(name="test", + description="This is just a test command, nothing more.") + async def test(ctx): + await ctx.respond() + await ctx.send(content="Hello World!") + +Now that we've gone over how Discord handles the declaration of slash commands +through their Bot API, let's go over what some of the other things mean within +the *logical* part of our code, the command function: + +- ``ctx.respond()``: This is a way for us to handle responses. In short, the API +requires some way to "acknowledge" an interaction response that we want to send off. + +(An alias of this would be ``ctx.ack()``) + +Giving some options for variety. +-------------------------------- + +The next thing that we will begin to talk about is the implementation of options, +otherwise well-known as "arguments" in discord.py commands. + +The JSON structure of options are designed up to be similar to the same premise +of how a slash command is declared. Below is the given table of how an option +JSON would appear as: + ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| **Field** | **Type** | **Description** | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| type | int | value of `ApplicationCommandOptionType`_. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| name | string | 1-32 character name matching ``^[\w-]{1,32}$``. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| description | string | 1-100 character description. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| default? | bool | the first required option for the user to complete--only one option can be default. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| required? | bool | if the parameter is required or optional--default ``false``. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| choices? | array of `ApplicationCommandOptionChoice`_ | choices for ``string`` and ``int`` types for the user to pick from. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| options? | array of `ApplicationCommandOption`_ | if the option is a subcommand or subcommand group type, this nested options will be the parameters. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ + +Now we have an idea of how options are declared. With this in mind, let's quickly make a JSON +example in order to visualize this concept even further: + +.. code-block:: python + + { + "name": "test", + "description": "This is just a test command, nothing more.", + "options": [ + { + "name": "optone", + "description": "This is the first option we have.", + "type": 3, + "required": "false" + } + ] + } + +While the table in the basics mentions an array in particular called ``ApplicationCommandOptionType``, +there isn't that much of an explanation on how this works. Let's put this into better laymen +terms on what this means with a table below showing all of these values: + ++-------------------+-----------+ +| **Name** | **Value** | ++-------------------+-----------+ +| SUB_COMMAND | 1 | ++-------------------+-----------+ +| SUB_COMMAND_GROUP | 2 | ++-------------------+-----------+ +| STRING | 3 | ++-------------------+-----------+ +| INTEGER | 4 | ++-------------------+-----------+ +| BOOLEAN | 5 | ++-------------------+-----------+ +| USER | 6 | ++-------------------+-----------+ +| CHANNEL | 7 | ++-------------------+-----------+ +| ROLE | 8 | ++-------------------+-----------+ + +The purpose of having the ``ApplicationCommandOptionType`` value passed into our option JSON structure +is so that we can help the Discord UI understand what kind of value we're inputting here. For instance, +if we're wanting to put in a string response, we'll pass the ID 3 so that the UI of Discord chat bar +knows to format it visually this way. If we're looking for a user, then we'll pass ID 6 so that it presents +us with a list of users in our server instead, making it easier on our lives. + +This is not to be confused, however, with formatting the response type itself. This is merely a method so +that the API wrapper can help us with passing the correct type or instance variable with the arguments of the +command function's code. + +Now, we can finally visualize this by coding an example of this being used in the Python code shown below. + +.. code-block:: python + + from discord_slash.manage_commands import create_option + + @slash.slash(name="test", + description="This is just a test command, nothing more.", + options=[ + create_option( + name="optone", + description="This is the first option we have.", + option_type=3, + required=False + ) + ]) + async def test(ctx, optone: str): + await ctx.respond() + await ctx.send(content=f"I got you, you said {optone}!") + +Additionally, we could also declare the type of our command's option through this method shown here: + +.. code-block:: python + + from discord_slash.model import SubCommandOptionType + + (...) + + option_type=SubCommandOptionType.STRING + +More in the option? Give them a choice. +--------------------------------------- + +Alas, there is also a way to give even more information to options with Discord's Slash Commands: +a choice. Not like something that you're given at birth of when you become of legal age as an adult, +we're not here to give you *that* kind of life advice, but the choice of what value you want your +option to rather pass. Below is a table that shows the JSON structure of how choices are represented +for an option: + ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| **Field** | **Type** | **Description** | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| name | string | 1-32 character choice name. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ +| value | string or int | value of the choice, up to 100 characters if string. | ++-------------+--------------------------------------------+-----------------------------------------------------------------------------------------------------+ + +This time, only 2 fields are able to be passed for this. Below is a JSON example of how this would +be designed: + +.. code-block:: python + + { + "name": "ChoiceOne", + "value": "Hello command, this is my value!" + } + +To make it really simple, the ``name`` field is only to be used for how you want the choice to be presented +through Discord's UI. It's the "appearance" of how you want your choice shown, not the actual returned value +of it. Hence, this is why ``value`` is the second field passed for that, which can be either in the form of +a string or integer. Below is an implementation of this design in the Python code: .. code-block:: python - import discord - from discord_slash import SlashCommand - from discord_slash.utils import manage_commands # Allows us to manage the command settings. - - client = discord.Client(intents=discord.Intents.all()) - slash = SlashCommand(client, sync_commands=True) - - guild_ids = [789032594456576001] - - @client.event - async def on_ready(): - print("Ready!") - - @slash.slash( - name="test", - description="this returns the bot latency", - options=[manage_commands.create_option( - name = "argone", - description = "description of first argument", - option_type = 3, - required = True - )], - guild_ids=guild_ids - ) - async def _test(ctx, argone: str): - await ctx.respond() - await ctx.send(f"You responded with {argone}.") - - client.run("your_bot_token_here") + from discord_slash.manage_commands import create_option, create_choice -The main changes that you need to know about are with the lines calling the import -of ``manage_commands``, as well as the ``options = [] ...`` code within the ``@slash.slash()`` -context coroutine. This will now create a new option called "argone" when shown for -the slash command. + @slash.slash(name="test", + description="This is just a test command, nothing more.", + options=[ + create_option( + name="optone", + description="This is the first option we have.", + option_type=3, + required=False, + choices=[ + create_choice( + name="ChoiceOne", + value="DOGE!" + ), + create_choice( + name="ChoiceTwo", + value="NO DOGE" + ) + ] + ) + ]) + async def test(ctx, optone: str): + await ctx.respond() + await ctx.send(content=f"Wow, you actually chose {optone}? :(") .. _quickstart: https://discord-py-slash-command.readthedocs.io/en/latest/quickstart.html +.. _ApplicationCommandOptionType: https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptiontype .. _ApplicationCommandOptionChoice: https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptionchoice .. _ApplicationCommandOption: https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoption diff --git a/docs/index.rst b/docs/index.rst index 8b300bf54..4b2d4a995 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,14 +3,13 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to discord-py-slash-command's official documentation! -============================================================= +Welcome +======= -discord-py-slash-command is a simple discord.py library extension -for using Discord's new Slash Command feature. +Hello there! Welcome to the official documentation of our library +extension made for discord.py: being able to use Discord Slash Commands. -Before going into the advanced sections that guide you through -added more complex stuff documentation-wise, it is highly recommended +Before we start going into the advanced stuff, it is highly recommended to check out the `quickstart`_ page first from here or below in the contents. If there are any questions that you have about the documentation diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 9b7689b2d..e843115ca 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -2,7 +2,7 @@ Quickstart ========== Before doing anything, it is highly recommended to read discord.py's quickstart. -You can find it by clicking :ref:`this `. +You can find it by clicking :ref:`this here `. Firstly, we will begin by installing the python library extension for discord.py: @@ -38,38 +38,32 @@ For this example, ``main.py`` will be used. Let's give this a run. When you run this code, you'll see... nothing but ``Ready!``. -That's completely normal, because we haven't defined any slash commands yet. -We can do so by adding this code shown here: +That's completely normal. Why is that? Well, it's because we haven't defined any actual +slash commands just yet. We can do that by adding this code shown here: .. code-block:: python - import discord - from discord_slash import SlashCommand # Importing the newly installed library. - - client = discord.Client(intents=discord.Intents.all()) - slash = SlashCommand(client, sync_commands=True) # Declares slash commands through the client. - + """ + Make sure this code is added before the client.run() call! + It also needs to be under on_ready, otherwise, this will not work. + """ + guild_ids = [789032594456576001] # Put your server ID in this array. - @client.event - async def on_ready(): - print("Ready!") - @slash.slash(name="ping", guild_ids=guild_ids) async def _ping(ctx): # Defines a new "context" (ctx) command called "ping." await ctx.respond() await ctx.send(f"Pong! ({client.latency*1000}ms)") - client.run("your_bot_token_here") - -Let's explain some of the major code differences between the prior examples shown -here to give a better understanding of what is going on: +Let's compare some of the major code differences between the prior examples in order +to explain what's going on here: - ``guild_ids = [789032594456576001]``: This is for adding your command as a guild command. -Otherwise, you need to wait for an hour to wait until your command is added. This is due -to the code recognizing the new slash command as a **global** command instead of what we -originally want, a *guild* slash command. +It is very important for us to make sure that we're declaring this cpart of the ``@slash.slash`` +decorator if we're wanting to declare a guild command and not a **global** one. The reason as for +why this is needed is because the Discord Bot API can take up to 1 hour to register a global +command that is called via. the code here when this key-word argument is not passed. - ``@slash.slash(name="ping", ...`` ~ ``await ctx.send(...)``: This adds a new slash command.