Browse Source

Merge branch 'Interactions' of https://github.com/Discord-Net-Labs/Discord.Net-Labs into Interactions

pull/1923/head
quin lynch 4 years ago
parent
commit
7a44a8a6b7
11 changed files with 80 additions and 20 deletions
  1. +1
    -1
      README.md
  2. +4
    -4
      docs/guides/slash-commands/03-responding-to-slash-commands.md
  3. +6
    -6
      docs/guides/slash-commands/06-subcommands.md
  4. +3
    -3
      docs/guides/slash-commands/07-choice-slash-command.md
  5. +11
    -0
      docs/guides/slash-commands/README.md
  6. +9
    -0
      src/Discord.Net.Rest/Discord.Net.Rest.xml
  7. +2
    -1
      src/Discord.Net.Rest/DiscordRestClient.cs
  8. +10
    -0
      src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
  9. +13
    -3
      src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
  10. +9
    -0
      src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml
  11. +12
    -2
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs

+ 1
- 1
README.md View File

@@ -5,7 +5,7 @@
This repo is a custom fork of Discord.Net that introduces the newest features of discord for testing and experimenting. Nothing here is guaranteed to work but you are more than welcome to submit bugs in the issues tabs

## Known issues
Labs will not work with Playwo's [InteractivityAddon](https://github.com/Playwo/Discord.InteractivityAddon). The reason is that his package depends on the base discord.net lib, you can get around this by cloning his repo and building it with discord.net labs instead of discord.net.
Labs will not work with normal package of Playwo's [InteractivityAddon](https://www.nuget.org/packages/Discord.InteractivityAddon). The reason is that his package depends on the base discord.net lib. You can instead use the [InteractivityAddon.Labs](https://www.nuget.org/packages/Discord.InteractivityAddon.Labs) package which implements some of the features added in Discord.Net-Labs.

## How to use
Setting up labs in your project is really simple, here's how to do it:


+ 4
- 4
docs/guides/slash-commands/03-responding-to-slash-commands.md View File

@@ -1,6 +1,6 @@
# Responding to interactions.

Interactions are the base thing sent over by discord. Slash commands are one of the interaction types. In order to receive a slash command we have to listen to the `InteractionCreated` event. Let's add this to our code.
Interactions are the base thing sent over by Discord. Slash commands are one of the interaction types. In order to receive a slash command we have to listen to the `InteractionCreated` event. Let's add this to our code.

```cs
client.InteractionCreated += Client_InteractionCreated;
@@ -13,7 +13,7 @@ private async Task Client_InteractionCreated(SocketInteraction arg)
}
```

Now that we have the interaction event, Let's talk about the `SocketInteraction` argument. The interaction can be cast to either a `SocketSlashCommand` or a `SocketMessageComponent`. In our case we're trying to use slash commands so Let's cast it to a `SocketSlashCommand`.
Now that we have the interaction event, let's talk about the `SocketInteraction` argument. The interaction can be cast to either a `SocketSlashCommand` or a `SocketMessageComponent`. In our case, we're trying to use slash commands so let's cast it to a `SocketSlashCommand`.

```cs
private async Task Client_InteractionCreated(SocketInteraction arg)
@@ -25,7 +25,7 @@ private async Task Client_InteractionCreated(SocketInteraction arg)
}
```

With every type of interaction there is a `Data` field. this is where the relevant information lives about our command that was executed. In our case, `Data` is a `SocketSlashCommandData` class. In the data class, we can access the name of the command triggered as well as the options if there were any. For this example, we're just going to respond with the name of the command executed.
With every type of interaction there is a `Data` field. This is where the relevant information lives about our command that was executed. In our case, `Data` is a `SocketSlashCommandData` instance. In the data class, we can access the name of the command triggered as well as the options if there were any. For this example, we're just going to respond with the name of the command executed.

```cs
private async Task Client_InteractionCreated(SocketInteraction arg)
@@ -45,6 +45,6 @@ Let's try this out!

Let's go over the response types quickly, as you would only change them for style points :P

> After receiving an interaction, you must respond to acknowledge it. You can choose to respond with a message immediately using `ChannelMessageWithSource` or you can choose to send a deferred response with `DeferredChannelMessageWithSource`. If choosing a deferred response, the user will see a loading state for the interaction, and you'll have up to 15 minutes to edit the original deferred response using Edit Original Interaction Response. You can read more about Response types [here](https://discord.com/developers/docs/interactions/slash-commands#interaction-response)
> After receiving an interaction, you must respond to acknowledge it. You can choose to respond with a message immediately using `ChannelMessageWithSource` or you can choose to send a deferred response with `DeferredChannelMessageWithSource`. If choosing a deferred response, the user will see a loading state for the interaction, and you'll have up to 15 minutes to edit the original deferred response using Edit Original Interaction Response. You can read more about response types [here](https://discord.com/developers/docs/interactions/slash-commands#interaction-response)

This seems to be working! Next, we will look at parameters for slash commands.

+ 6
- 6
docs/guides/slash-commands/06-subcommands.md View File

@@ -1,6 +1,6 @@
# Subcommands

Sub commands allow you to have multiple commands available in a single command. They can be useful for representing sub options for a command. for example: a settings command. Let's first look at some limitations with sub commands set by discord.
Subcommands allow you to have multiple commands available in a single command. They can be useful for representing sub options for a command. For example: A settings command. Let's first look at some limitations with subcommands set by discord.

- An app can have up to 25 subcommand groups on a top-level command
- An app can have up to 25 subcommands within a subcommand group
@@ -59,7 +59,7 @@ command
|__ subcommand-group
```

Let's write a settings command that can change 2 fields in our bot.
Let's write a settings command that can change 3 fields in our bot.

```cs
public string FieldA { get; set; } = "test";
@@ -132,7 +132,7 @@ public async Task Client_Ready()
All that code generates a command that looks like this:
![settings](images/settings1.png)

Now that we have our command made, we need to handle the multiple options with this command. so lets add this into our handler
Now that we have our command made, we need to handle the multiple options with this command. So lets add this into our handler:

```cs
private async Task Client_InteractionCreated(SocketInteraction arg)
@@ -157,7 +157,7 @@ private async Task HandleSettingsCommand(SocketSlashCommand command)
// First lets extract our variables
var fieldName = command.Data.Options.First().Name;
var getOrSet = command.Data.Options.First().Options.First().Name;
// since there is no value on a get command, we use the ? operator because "Options" can be null.
// Since there is no value on a get command, we use the ? operator because "Options" can be null.
var value = command.Data.Options.First().Options.First().Options?.FirstOrDefault().Value;

switch (fieldName)
@@ -206,11 +206,11 @@ private async Task HandleSettingsCommand(SocketSlashCommand command)

```

Now, let't try this out! Running the 3 get commands seems to get the default values we set.
Now, let's try this out! Running the 3 get commands seems to get the default values we set.

![settings get](images/settings2.png)

Now lets try changing each to a different value.
Now let's try changing each to a different value.

![settings set](images/settings3.png)



+ 3
- 3
docs/guides/slash-commands/07-choice-slash-command.md View File

@@ -1,8 +1,8 @@
# Slash Command Choices.

With slash command options you can add choices, making the user select between some set values. Lets create a command that ask how much they like our bot!
With slash command options you can add choices, making the user select between some set values. Lets create a command that asks how much they like our bot!

Lets set up our slash command:
Let's set up our slash command:

```cs
private async Task Client_Ready()
@@ -78,6 +78,6 @@ private async Task HandleFeedbackCommand(SocketSlashCommand command)
}
```

And this is the result!
And this is the result:

![feedback working](images/feedback2.png)

+ 11
- 0
docs/guides/slash-commands/README.md View File

@@ -0,0 +1,11 @@
## Slash command guides
Here you can find some guides on how to use slash commands.
1. [Getting started](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/Interactions/docs/guides/slash-commands/01-getting-started.md)
2. [Creating a slash command](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/Interactions/docs/guides/slash-commands/02-creating-slash-commands.md)
3. [Responding to slash commands](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/Interactions/docs/guides/slash-commands/03-responding-to-slash-commands.md)
4. [Parameters in slash commands](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/Interactions/docs/guides/slash-commands/04-parameters.md)
5. [Responding ephemerally](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/Interactions/docs/guides/slash-commands/05-responding-ephemerally.md)
6. [Subcommands](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/Interactions/docs/guides/slash-commands/06-subcommands.md)
7. [Choices](https://github.com/Discord-Net-Labs/Discord.Net-Labs/blob/Interactions/docs/guides/slash-commands/07-choice-slash-command.md)

+ 9
- 0
src/Discord.Net.Rest/Discord.Net.Rest.xml View File

@@ -2740,6 +2740,15 @@
<member name="M:Discord.Rest.RestGuild.LeaveAsync(Discord.RequestOptions)">
<inheritdoc />
</member>
<member name="M:Discord.Rest.RestGuild.DeleteSlashCommandsAsync(Discord.RequestOptions)">
<summary>
Deletes all slash commands in the current guild.
</summary>
<param name="options">The options to be used when sending the request.</param>
<returns>
A task that represents the asynchronous delete operation.
</returns>
</member>
<member name="M:Discord.Rest.RestGuild.GetSlashCommandsAsync(Discord.RequestOptions)">
<summary>
Gets a collection of slash commands created by the current user in this guild.


+ 2
- 1
src/Discord.Net.Rest/DiscordRestClient.cs View File

@@ -125,7 +125,8 @@ namespace Discord.Rest
=> InteractionHelper.BulkOverwriteGuildCommands(this, guildId, commandProperties, options);
public Task<IReadOnlyCollection<GuildApplicationCommandPermission>> BatchEditGuildCommandPermissions(ulong guildId, IDictionary<ulong, ApplicationCommandPermission[]> permissions, RequestOptions options = null)
=> InteractionHelper.BatchEditGuildCommandPermissionsAsync(this, guildId, permissions, options);

public Task DeleteAllGlobalCommandsAsync(RequestOptions options = null)
=> InteractionHelper.DeleteAllGlobalCommandsAsync(this, options);

public Task AddRoleAsync(ulong guildId, ulong userId, ulong roleId)
=> ClientHelper.AddRoleAsync(this, guildId, userId, roleId);


+ 10
- 0
src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs View File

@@ -256,6 +256,16 @@ namespace Discord.Rest
=> GuildHelper.LeaveAsync(this, Discord, options);

//Interactions
/// <summary>
/// Deletes all slash commands in the current guild.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous delete operation.
/// </returns>
public Task DeleteSlashCommandsAsync(RequestOptions options = null)
=> InteractionHelper.DeleteAllGuildCommandsAsync(Discord, this.Id, options);

/// <summary>
/// Gets a collection of slash commands created by the current user in this guild.
/// </summary>


+ 13
- 3
src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs View File

@@ -11,6 +11,16 @@ namespace Discord.Rest
{
internal static class InteractionHelper
{
public static Task DeleteAllGuildCommandsAsync(BaseDiscordClient client, ulong guildId, RequestOptions options = null)
{
return client.ApiClient.BulkOverwriteGuildApplicationCommands(guildId, new CreateApplicationCommandParams[0], options);
}

public static Task DeleteAllGlobalCommandsAsync(BaseDiscordClient client, RequestOptions options = null)
{
return client.ApiClient.BulkOverwriteGlobalApplicationCommands(new CreateApplicationCommandParams[0], options);
}

public static Task SendInteractionResponse(BaseDiscordClient client, IMessageChannel channel, InteractionResponse response,
ulong interactionId, string interactionToken, RequestOptions options = null)
{
@@ -348,7 +358,7 @@ namespace Discord.Rest
return new GuildApplicationCommandPermission(model.Id, model.ApplicationId, guildId, model.Permissions.Select(
y => new ApplicationCommandPermission(y.Id, y.Type, y.Permission)).ToArray());
}
catch(HttpException x)
catch (HttpException x)
{
if (x.HttpCode == System.Net.HttpStatusCode.NotFound)
return null;
@@ -365,7 +375,7 @@ namespace Discord.Rest

List<ApplicationCommandPermissions> models = new List<ApplicationCommandPermissions>();

foreach(var arg in args)
foreach (var arg in args)
{
var model = new ApplicationCommandPermissions()
{
@@ -391,7 +401,7 @@ namespace Discord.Rest

List<ModifyGuildApplicationCommandPermissions> models = new List<ModifyGuildApplicationCommandPermissions>();

foreach(var arg in args)
foreach (var arg in args)
{
Preconditions.AtMost(arg.Value.Length, 10, nameof(args));



+ 9
- 0
src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml View File

@@ -2843,6 +2843,15 @@
voice regions the guild can access.
</returns>
</member>
<member name="M:Discord.WebSocket.SocketGuild.DeleteSlashCommandsAsync(Discord.RequestOptions)">
<summary>
Deletes all slash commands in the current guild.
</summary>
<param name="options">The options to be used when sending the request.</param>
<returns>
A task that represents the asynchronous delete operation.
</returns>
</member>
<member name="M:Discord.WebSocket.SocketGuild.GetSlashCommandsAsync(Discord.RequestOptions)">
<summary>
Gets a collection of slash commands created by the current user in this guild.


+ 12
- 2
src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs View File

@@ -724,6 +724,16 @@ namespace Discord.WebSocket
=> GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options);

//Interactions
/// <summary>
/// Deletes all slash commands in the current guild.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous delete operation.
/// </returns>
public Task DeleteSlashCommandsAsync(RequestOptions options = null)
=> InteractionHelper.DeleteAllGuildCommandsAsync(Discord, this.Id, options);

/// <summary>
/// Gets a collection of slash commands created by the current user in this guild.
/// </summary>
@@ -823,7 +833,7 @@ namespace Discord.WebSocket
if (_roles.TryGetValue(model.Id, out SocketRole role))
_roles[model.Id].Update(this.Discord.State, model);
else
role = AddRole(model);
role = AddRole(model);

return role;
}
@@ -1289,7 +1299,7 @@ namespace Discord.WebSocket
Task<IReadOnlyCollection<IVoiceChannel>> IGuild.GetVoiceChannelsAsync(CacheMode mode, RequestOptions options)
=> Task.FromResult<IReadOnlyCollection<IVoiceChannel>>(VoiceChannels);
/// <inheritdoc />
Task<IReadOnlyCollection<ICategoryChannel>> IGuild.GetCategoriesAsync(CacheMode mode , RequestOptions options)
Task<IReadOnlyCollection<ICategoryChannel>> IGuild.GetCategoriesAsync(CacheMode mode, RequestOptions options)
=> Task.FromResult<IReadOnlyCollection<ICategoryChannel>>(CategoryChannels);
/// <inheritdoc />
Task<IVoiceChannel> IGuild.GetVoiceChannelAsync(ulong id, CacheMode mode, RequestOptions options)


Loading…
Cancel
Save