add basic discord support
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
\page components-menu Message Components
|
||||
|
||||
Components are anything that can be attached to a message or a \ref modal-dialog-interactions "modal" and interacted with, for example buttons and select menus. Due to being \ref interactions-and-components "interactions", they benefit from a low rate limit and are much more efficient than the old ways of using reactions for this purpose.
|
||||
|
||||
* \subpage components
|
||||
* \subpage components2
|
||||
* \subpage components3
|
||||
* \subpage default_select_value
|
||||
* \subpage editing_message_after_click
|
||||
@@ -0,0 +1,9 @@
|
||||
\page components Using Button Components
|
||||
|
||||
Discord's newest features support sending buttons alongside messages, which when clicked by the user trigger an interaction which is routed by D++ as an `on_button_click` event. To make use of this, use this code as in this example.
|
||||
|
||||
\include{cpp} components.cpp
|
||||
|
||||
When the feature is functioning, the code below will produce buttons on the reply message like in the image below:
|
||||
|
||||
\image html button.png
|
||||
@@ -0,0 +1,9 @@
|
||||
\page components2 Advanced Button Components
|
||||
|
||||
This example demonstrates adding multiple buttons, receiving button clicks, and sending response messages.
|
||||
|
||||
\include{cpp} components2.cpp
|
||||
|
||||
This code will send a different message for correct and incorrect answers.
|
||||
|
||||
\image html button_2.png
|
||||
@@ -0,0 +1,17 @@
|
||||
\page components3 Using Select Menu Components
|
||||
|
||||
This tutorial will cover creating two types of select menus:
|
||||
- A generic select menu with just text
|
||||
- An auto-populated role select menu.
|
||||
|
||||
This first example demonstrates creating a select menu, receiving select menu clicks, and sending a response message.
|
||||
|
||||
\include{cpp} components3.cpp
|
||||
|
||||
This second example demonstrates:
|
||||
- Creating a role select menu that is auto-populated by Discord
|
||||
- Allowing users to select two options!
|
||||
|
||||
\note This type of select menu, along with other types (these types being: user, role, mentionable, and channel), always auto-fill. You never need to define the data in these types of select menus. All select menu types allow you to select multiple options.
|
||||
|
||||
\include{cpp} components3_rolemenu.cpp
|
||||
@@ -0,0 +1,13 @@
|
||||
\page default_select_value Setting Default Values on Select Menus.
|
||||
|
||||
This tutorial will cover how to set the default value for a select menu (that isn't a text select menu)!
|
||||
|
||||
\note **This only works for the following types of select menus: user, role, mentionable, and channel.** The default type of a select menu (as shown in \ref components3 "this page") does not work for this, as that supports a "placeholder".
|
||||
|
||||
\include{cpp} default_select_value.cpp
|
||||
|
||||
If all went well, you should have something like this!
|
||||
|
||||
\image html default_select_value.png
|
||||
|
||||
\image html default_select_value_2.png
|
||||
@@ -0,0 +1,19 @@
|
||||
\page editing_message_after_click Editing The Message From a Button Click
|
||||
|
||||
\note This page expects you to be familiar with Button Clicks and extends from the \ref components page. Please visit the \ref components page if you are not already familiar with Button Clicks.
|
||||
|
||||
Editing messages where you had a button click can be done in a couple ways.
|
||||
|
||||
If you want to edit the message that had the buttons on, instead of doing `event.reply("message");`, you would do `event.reply(dpp::ir_update_message, "message");`, like so:
|
||||
|
||||
\note You are still limited to the default interaction time (3 seconds) this way. Read on if you need more time!
|
||||
|
||||
\include{cpp} editing_message_after_click.cpp
|
||||
|
||||
However, if you're going to take longer than 3 seconds to respond, you need to tell Discord to wait. The usual method is `event.thinking(true);` and then `event.edit_response("I have thought long and hard about my actions.");`, however, `event.thinking()` will create a new response if called from `on_button_click`, meaning you can no longer respond to the original response as you already did a response!
|
||||
|
||||
Instead, you want to do `event.reply(dpp::ir_deferred_channel_message_with_source, "");` to tell Discord that you intend on editing the message that the button click came from, but you need time. The user will be informed that you've processed the button click (as required) via a loading state and then you have 15 minutes to do everything you need. To then edit the message, you need to do `event.edit_response("new message!");`, like so:
|
||||
|
||||
\note If you want to silently acknowledge the button click (no thinking message), replace dpp::ir_deferred_channel_message_with_source with dpp::ir_deferred_update_message. You will still have 15 minutes to make a response.
|
||||
|
||||
\include{cpp} editing_message_after_click2.cpp
|
||||
@@ -0,0 +1,15 @@
|
||||
\page context-menu Context Menus
|
||||
|
||||
Context menus are application commands that appear on the context menu (right click or tap) of users or messages to perform context-specific actions. They can be created using dpp::slashcommand. Once you create a context menu, try right-clicking either a user or message to see it in your server!
|
||||
|
||||
\image html context_menu_user_command.png
|
||||
|
||||
\note This example sets the command as the type dpp::ctxm_user which can only be used by right clicking on a user. To make it appear on a message, you'll want to switch the type to dpp::ctxm_message and listen for the `on_message_context_menu` (dpp::message_context_menu_t) event.
|
||||
|
||||
The following example shows how to create and handle **user context menus** for message context menus, read the notice above.
|
||||
|
||||
\include{cpp} context_menus.cpp
|
||||
|
||||
It registers a guild command that can be called by right-clicking a user and clicking on the created menu.
|
||||
|
||||
\image html context_menu_user_command_showcase.png
|
||||
@@ -0,0 +1,12 @@
|
||||
\page modal-dialog-interactions Modals
|
||||
|
||||
Modal dialog interactions are a new Discord API feature that allow you to have pop-up windows which prompt the user to input information. Once the user has filled in this information, your program will receive an `on_form_submit` event which will contain the data which was input. You must use a slash command interaction response to submit your modal form data to Discord, via the `on_slashcommand` event. From here calling the `dialog` method of the `interaction_create_t` event object will trigger the dialog to appear.
|
||||
|
||||
Each dialog box may have up to five rows of input fields. The example below demonstrates a simple setup with just one text input:
|
||||
|
||||
\include{cpp} modal_dialog_interactions.cpp
|
||||
|
||||
If you compile and run this program and wait for the global command to register, typing `/dialog` will present you with a dialog box like the one below:
|
||||
|
||||
\image html modal_dialog.png
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
\page resolved-objects Using Resolved Objects
|
||||
|
||||
If your slash command accepts options like user, channel, or role you can get their value, as specified by the user in the command, from parameters. Though parameter gives you only the snowflake id of the passed value.
|
||||
|
||||
If you need object of that snowflake, you can get that from the resolved set using its snowflake id.
|
||||
|
||||
Below is an example showing how to get a member, passed in command options, using resolved set.
|
||||
|
||||
\include{cpp} resolved_objects.cpp
|
||||
@@ -0,0 +1,12 @@
|
||||
\page slashcommands-menu Slash commands
|
||||
|
||||
Here, you will find examples on how to use slash commands, subcommands, and different types or parameters.
|
||||
|
||||
* \subpage slashcommands "Using Slash Commands"
|
||||
* \subpage clearing_slashcommands
|
||||
* \subpage subcommands "Slash command sub-commands"
|
||||
* \subpage application-command-autocomplete "Slash command auto completion"
|
||||
* \subpage discord-application-command-file-upload "Using file parameters in slash commands"
|
||||
* \subpage commandhandler "Unified message/slash command handler"
|
||||
|
||||
\note Keep in mind, a slash command when sent to your bot is <b>NOT SENT AS A MESSAGE</b>! It is not a string but an interaction structure with its own data, and \ref resolved-objects "command parameters are objects".
|
||||
@@ -0,0 +1,5 @@
|
||||
\page application-command-autocomplete Slash Command Autocompletion
|
||||
|
||||
Discord now supports sending auto completion lists for slash command choices. To use this feature you can use code such as the example below:
|
||||
|
||||
\include{cpp} autocomplete.cpp
|
||||
@@ -0,0 +1,7 @@
|
||||
\page clearing_slashcommands Clearing Registered Commands
|
||||
|
||||
After a while of creating commands, you may start to wonder "hm, how can I clear these?". Well, this tutorial covers it! All you have to do is simply call dpp::cluster::global_bulk_command_delete or dpp::cluster::guild_bulk_command_delete.
|
||||
|
||||
\note Clearing **global commands** will only clear commands that were **made globally**, same goes for the opposite way round. The example will demonstrate using both functions.
|
||||
|
||||
\include{cpp} clearing_slashcommands.cpp
|
||||
@@ -0,0 +1,15 @@
|
||||
\page commandhandler Using a Command Handler Object
|
||||
|
||||
If you have many commands in your bot, and want to handle commands from multiple sources, you should consider instantiating a dpp::commandhandler object. This object can be used to automatically route
|
||||
commands and their parameters to functions in your program. A simple example of using this object to route commands is shown below, and will
|
||||
route both the /ping (global slash command) and .ping (prefixed channel message command) to a lambda where a reply can be generated.
|
||||
|
||||
\note This example automatically hooks the dpp::cluster::on_message_create and dpp::cluster::on_slashcommand events. This can be overridden if needed to allow you to still make use of these functions for your own code, if you need to do this please see the constructor documentation for dpp::commandhandler.
|
||||
|
||||
Note that because the dpp::commandhandler::add_command method accepts a `std::function` as the command handler, you may point a command handler
|
||||
at a simple lambda (as shown in this example), a function pointer, or an instantiated class method of an object. This is extremely flexible
|
||||
and allows you to decide how and where commands should be routed, either to an object oriented system or to a lambda based system.
|
||||
|
||||
\warning As of [August 30th, 2022](https://support-dev.discord.com/hc/en-us/articles/6025578854295-Why-We-Moved-to-Slash-Commands), you are advised to only be using slash commands, not messages for commands. To prevent the command handler from handling commands with messages, you should only use the "/" prefix. If you wish to still use messages for commands, this tutorial will still cover it but, again, it is discouraged by Discord.
|
||||
|
||||
\include{cpp} commandhandler.cpp
|
||||
@@ -0,0 +1,29 @@
|
||||
\page slashcommands Using Slash Commands and Interactions
|
||||
|
||||
Slash commands and interactions are a newer feature of Discord which allow a bot's commands to be registered centrally within the system and for users to easily explore and get help with available commands through the client itself.
|
||||
|
||||
To add a slash command you should use the dpp::cluster::global_command_create method for global commands (available to all guilds) or dpp::cluster::guild_command_create to create a local command (available only to one guild). If you want to add many commands, it is advised to use the dpp::cluster::global_bulk_command_create method for global commands or the dpp::cluster::guild_bulk_command_create method for local commands.
|
||||
|
||||
\note dpp::cluster::global_bulk_command_create and dpp::cluster::guild_bulk_command_create will delete any previous commands that were registered. For example, if you call dpp::cluster::global_bulk_command_create twice with two different sets then the first set of commands will be created, then when the second set is called, the first set will be deleted, leaving only the second set.
|
||||
|
||||
When a user issues these commands the reply will arrive via the `on_slashcommand` event which you can hook into, and take action when you see your commands. It is possible to reply to an interaction by using either the dpp::interaction_create_t::reply method, or by manually instantiating an object of type dpp::interaction_response and attaching a dpp::message object to it.
|
||||
|
||||
dpp::interaction_create_t::reply has two overloaded versions of the method, one of which accepts simple `std::string` replies, for basic text-only messages (if your message is 'ephemeral' you must use this) and one which accepts a dpp::message for more advanced replies. Please note that at present, Discord only supports a small subset of message and embed features within an interaction response object.
|
||||
|
||||
This first example goes over creating a single command globally.
|
||||
|
||||
\include{cpp} slashcommands1.cpp
|
||||
|
||||
This second example goes over creating a single command but only for a guild, this means that the command can not be accessed anywhere else but the guild specified.
|
||||
|
||||
\include{cpp} slashcommands2.cpp
|
||||
|
||||
This third example goes over creating four commands globally, using the bulk create method.
|
||||
|
||||
\include{cpp} slashcommands3.cpp
|
||||
|
||||
This fourth example goes over creating four commands but only for a guild.
|
||||
|
||||
\include{cpp} slashcommands4.cpp
|
||||
|
||||
\note For demonstration purposes, and small bots, this code is OK, but in the real world once your bot gets big, it's not recommended to create slash commands in the `on_ready` event even when it's inside dpp::run_once as, if you re-run your bot multiple times or start multiple clusters, you will quickly get rate-limited! You could, for example, add a commandline parameter to your bot (`argc`, `argv`) so that if you want the bot to register commands it must be launched with a specific command line argument.
|
||||
@@ -0,0 +1,5 @@
|
||||
\page subcommands Using Sub-Commands in Slash Commands
|
||||
|
||||
This demonstrates how to use sub-commands within slash commands. Also shown below is an example of how to get a "resolved" parameter without having to use the cache or an extra API call.
|
||||
|
||||
\include{cpp} subcommands.cpp
|
||||
@@ -0,0 +1,10 @@
|
||||
\page discord-application-command-file-upload Using File Parameters for Application Commands (Slash Commands)
|
||||
|
||||
The program below demonstrates how to use the 'file' type parameter to an application command (slash command).
|
||||
You must first get the `file_id` via `std::get`, and then you can find the attachment details in the 'resolved'
|
||||
section, `event.command.resolved`.
|
||||
|
||||
The file is uploaded to Discord's CDN so if you need it locally you should fetch the `.url` value, e.g. by using
|
||||
something like dpp::cluster::request().
|
||||
|
||||
\include{cpp} upload_parameter.cpp
|
||||
@@ -0,0 +1,9 @@
|
||||
\page thinking Thinking
|
||||
|
||||
A common mistake people do is use `event.thinking` with `event.reply`, however, they always run into the `Interaction has already been acknowledged.` error! The reason for this is because `event.thinking` is a response to the interaction, meaning you have acknowledged it! You should use dpp::interaction_create_t::edit_original_response instead.
|
||||
|
||||
Below is an example, showing how you should properly use the thinking method.
|
||||
|
||||
\include{cpp} thinking.cpp
|
||||
|
||||
This will make the bot think briefly, then change the response to "thonk"!
|
||||
@@ -0,0 +1,11 @@
|
||||
\page user-only-messages Ephemeral Replies ('Only You Can See This' Replies)
|
||||
|
||||
If you've used a Discord bot, there's a chance that you've encountered a message from one that said "Only you can see this" after you interacted with it (or executed a command). These messages are pretty helpful and can be used in many instances where you'd only like the user that's interacting to see what's going on.
|
||||
|
||||
Here's how you can do exactly that!
|
||||
|
||||
\include{cpp} ephemeral.cpp
|
||||
|
||||
That's it! If everything went well, it should look like this:
|
||||
|
||||
\image html user_only_messages_image.png
|
||||
@@ -0,0 +1,68 @@
|
||||
\page user-applications Creating User Apps
|
||||
|
||||
# What are User Apps?
|
||||
|
||||
A user app is a bot (application) which can be attached to a user's profile via oauth, rather than being invited to a guild via oauth. This is a relatively new feature
|
||||
on Discord, and will allow you to have your bot to act like a utility for the user, so regardless of what guild they are in, or if they are in a DM with someone else,
|
||||
they have access to your bot's commands and can issue them, potentially letting all users in that guild, or all users in the DM, see the replies from your slash commands.
|
||||
|
||||
\warning Do not confuse User Apps with **User Bots**. User Apps are a new and very well supported feature, whereas **User Bots** means connecting a user's token as a bot,
|
||||
and is prohibited by the Discord TOS!
|
||||
|
||||
# Building the invite
|
||||
|
||||
To get started, you will need to configure your bot so that it will accept a user app invite. This is done via the [discord developer portal](https://discord.com/developers).
|
||||
|
||||
Click on your bot in the list of bots, and then choose **Installation** from the left hand menu. You must enable **User Install** if it is not already enabled.
|
||||
|
||||
Drop down the choices for **Install link** and change this to **Discord Provided Link**. The second box should auto-fill with an invite link. Note that this invite link
|
||||
will likely only show the **client_id** value. For default install settings for **User Install**, choose the only possible option, **applications.commands** and for the
|
||||
**Guild Install** section, choose the scopes **applications.commands** and **bot** as at least the bare minimum. You should also set the permissions your bot will use if it
|
||||
is invited to a guild.
|
||||
|
||||
\note The permissions you pick in the Guild Install box only apply if your bot is invited to a guild, not for a user app!
|
||||
|
||||
If you have entered all the settings correctly the screen should look like the one below (except the **Administrator** permission - don't use this, enter actual permissions!):
|
||||
|
||||
\image html user_apps_1.png
|
||||
|
||||
# Inviting the application
|
||||
|
||||
You can now invite your bot to your profile. Follow the invite link at the top of the screen by clicking **copy** and pasting it into a web browser. You will be prompted
|
||||
to either add the bot to your profile, or to a guild, as shown below. Choose to add the bot to your profile:
|
||||
|
||||
\image html user_apps_2.png
|
||||
|
||||
You may be prompted to prove you are not a robot (you aren't a robot, right? 🤖). Afterwards, the bot will be successfully added to your profile:
|
||||
|
||||
\image html user_apps_3.png
|
||||
|
||||
# Creating the program
|
||||
|
||||
From this point on, right now, your bot will do nothing as you haven't added any code yet to make it operate as a user app. This comes next. Below is an example bot
|
||||
with one user application command.
|
||||
|
||||
There are several important things to note in this program:
|
||||
|
||||
* When adding a new slash command, you must use the dpp::slashcommand::set_interaction_contexts function to set where this command is visible. You can specify any
|
||||
one of three possible values to be added to the vector:
|
||||
* dpp::itc_guild: A standard slash command, visible in guild channels
|
||||
* dpp::itc_bot_dm: A standard slash command, accessible in DMs with the bot (this replaces the functionality of dpp::slashcommand::set_dm_permission)
|
||||
* dpp::itc_private_channel: A user application command, visible anywhere to the user who added it to their profile.
|
||||
* When responding to the slash command, most things remain the same, except of course if you reply to a user app command most things relating to the guild
|
||||
will be uninitialised default values. This is because there is no guild to reference.
|
||||
* You can use dpp::interaction::is_user_app_interaction() to determine if the interaction is initiated from a user app command, or a guild command.
|
||||
dpp::interaction::is_guild_interaction() does the inverse.
|
||||
* Calling dpp::interaction::get_authorizing_integration_owner() with the parameter value dpp::ait_user_install will give you the dpp::snowflake ID of the
|
||||
user who has the app added to their profile, if a user is currently executing a user app command. If you call this function when not in a user app context,
|
||||
you will get an uninitialised snowflake value instead.
|
||||
|
||||
## Example Program
|
||||
|
||||
\include{cpp} user_apps.cpp
|
||||
|
||||
# Testing
|
||||
|
||||
If all goes to plan, your new command will be accessible everywhere!
|
||||
|
||||
\image html user_apps_4.png
|
||||
Reference in New Issue
Block a user