Browse Source

Refactor interaction methods and some changes (#58)

* Refactor emojis/emotes & SelectMenu

* Update Emoji.cs

* Continue emoji refactor

* Remove WithLabel from example of SelectMenuBuilder

* Remove EmojiUtils and move it stuff to Emoji

* Revert 0fbf1000da

* Revert "Update Emoji.cs" and add Parse method

This reverts commit f297dcfc43.

* Partial revert 3c27ab36c9

* Builders docs improve and add/rename methods/ctors

* Update Discord.Net.Core.xml

* Add SelectMenuBuilder.AddOption overload

* Docs fix

* Update Discord.Net.Core.xml

* corrections of unnecessary docs

* corrections of unnecessary docs!

* Fix docs and exceptions

* remove necessary things and some fix/changes

- Rename InteractionApplicationCommanCallbackData -> InteractionCallbackData
- Fix wrong creating instances of InteractionCallbackData

* Add SelectMenuOptionBuilder ctor overload

* Refactor interaction methods and some changes

* Remove deprecated methods

* remove necessary check

* remove necessary? line drops and using

* remove unused imports

* fix!

* some changes

- switched places arguments
- removed necessary accessor in SocketSlashCommand

* mini doc fix

* return AcknowledgeAsync method with Obsolete attribute

* Clarification in UpdateAsync doc

* Makes customId argument optional

* UpdateAsync doc correction

* makes button label argument optional

* doc fix and add emote argument to static createbutton methods
pull/1923/head
Nikon GitHub 3 years ago
parent
commit
180322177d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 243 additions and 218 deletions
  1. +3
    -3
      src/Discord.Net.Core/Discord.Net.Core.xml
  2. +21
    -15
      src/Discord.Net.Core/Entities/Interactions/Message Components/ComponentBuilder.cs
  3. +4
    -3
      src/Discord.Net.Core/Entities/Messages/MessageProperties.cs
  4. +1
    -1
      src/Discord.Net.Rest/API/Common/InteractionCallbackData.cs
  5. +1
    -6
      src/Discord.Net.Rest/API/Rest/CreateWebhookMessageParams.cs
  6. +2
    -2
      src/Discord.Net.Rest/API/Rest/ModifyMessageParams.cs
  7. +8
    -14
      src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
  8. +9
    -8
      src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
  9. +1
    -4
      src/Discord.Net.Rest/Entities/Messages/RestInteractionMessage.cs
  10. +36
    -52
      src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml
  11. +1
    -1
      src/Discord.Net.WebSocket/DiscordSocketClient.cs
  12. +85
    -24
      src/Discord.Net.WebSocket/Entities/Interaction/Message Components/SocketMessageComponent.cs
  13. +34
    -29
      src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommand.cs
  14. +30
    -54
      src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs
  15. +7
    -2
      src/Discord.Net.Webhook/WebhookClientHelper.cs

+ 3
- 3
src/Discord.Net.Core/Discord.Net.Core.xml View File

@@ -7129,7 +7129,7 @@
Properties that are used to modify an <see cref="T:Discord.IUserMessage" /> with the specified changes.
</summary>
<remarks>
The content of a message can be cleared with <see cref="F:System.String.Empty"/> if and only if an
The content of a message can be cleared with <see cref="F:System.String.Empty"/> if and only if an
<see cref="T:Discord.Embed"/> is present.
</remarks>
<seealso cref="M:Discord.IUserMessage.ModifyAsync(System.Action{Discord.MessageProperties},Discord.RequestOptions)"/>
@@ -7142,9 +7142,9 @@
This must be less than the constant defined by <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.
</remarks>
</member>
<member name="P:Discord.MessageProperties.Embed">
<member name="P:Discord.MessageProperties.Embeds">
<summary>
Gets or sets the embed the message should display.
Gets or sets the embeds of the message.
</summary>
</member>
<member name="P:Discord.MessageProperties.Components">


+ 21
- 15
src/Discord.Net.Core/Entities/Interactions/Message Components/ComponentBuilder.cs View File

@@ -120,7 +120,8 @@ namespace Discord
}

/// <summary>
/// Adds a button to the specified row.
/// Adds a <see cref="ButtonBuilder"/> with specified parameters to the <see cref="ComponentBuilder"/> at the specific row.
/// If the row cannot accept the component then it will add it to a row that can.
/// </summary>
/// <param name="label">The label text for the newly added button.</param>
/// <param name="style">The style of this newly added button.</param>
@@ -131,8 +132,8 @@ namespace Discord
/// <param name="row">The row the button should be placed on.</param>
/// <returns>The current builder.</returns>
public ComponentBuilder WithButton(
string label,
string customId,
string label = null,
string customId = null,
ButtonStyle style = ButtonStyle.Primary,
IEmote emote = null,
string url = null,
@@ -374,7 +375,7 @@ namespace Discord
/// <param name="style">The custom ID of this button</param>
/// <param name="emote">The emote of this button</param>
/// <param name="disabled">Disabled this button or not</param>
public ButtonBuilder(string label, string customId, ButtonStyle style = ButtonStyle.Primary, string url = null, IEmote emote = null, bool disabled = false)
public ButtonBuilder(string label = null, string customId = null, ButtonStyle style = ButtonStyle.Primary, string url = null, IEmote emote = null, bool disabled = false)
{
this.CustomId = customId;
this.Style = style;
@@ -400,47 +401,52 @@ namespace Discord
/// <summary>
/// Creates a button with the <see cref="ButtonStyle.Link"/> style.
/// </summary>
/// <param name="label">The label to use on the newly created link button.</param>
/// <param name="label">The label for this link button.</param>
/// <param name="url">The url for this link button to go to.</param>
/// <param name="emote">The emote for this link button</param>
/// <returns>A builder with the newly created button.</returns>
public static ButtonBuilder CreateLinkButton(string label, string url)
=> new ButtonBuilder(label, null, ButtonStyle.Link, url);
public static ButtonBuilder CreateLinkButton(string label, string url, IEmote emote = null)
=> new ButtonBuilder(label, null, ButtonStyle.Link, url, emote: emote);

/// <summary>
/// Creates a button with the <see cref="ButtonStyle.Danger"/> style.
/// </summary>
/// <param name="label">The label for this danger button.</param>
/// <param name="customId">The custom id for this danger button.</param>
/// <param name="emote">The emote for this danger button</param>
/// <returns>A builder with the newly created button.</returns>
public static ButtonBuilder CreateDangerButton(string label, string customId)
=> new ButtonBuilder(label, customId, ButtonStyle.Danger);
public static ButtonBuilder CreateDangerButton(string label, string customId, IEmote emote = null)
=> new ButtonBuilder(label, customId, ButtonStyle.Danger, emote: emote);

/// <summary>
/// Creates a button with the <see cref="ButtonStyle.Primary"/> style.
/// </summary>
/// <param name="label">The label for this primary button.</param>
/// <param name="customId">The custom id for this primary button.</param>
/// <param name="emote">The emote for this primary button</param>
/// <returns>A builder with the newly created button.</returns>
public static ButtonBuilder CreatePrimaryButton(string label, string customId)
=> new ButtonBuilder(label, customId);
public static ButtonBuilder CreatePrimaryButton(string label, string customId, IEmote emote = null)
=> new ButtonBuilder(label, customId, emote: emote);

/// <summary>
/// Creates a button with the <see cref="ButtonStyle.Secondary"/> style.
/// </summary>
/// <param name="label">The label for this secondary button.</param>
/// <param name="customId">The custom id for this secondary button.</param>
/// <param name="emote">The emote for this secondary button</param>
/// <returns>A builder with the newly created button.</returns>
public static ButtonBuilder CreateSecondaryButton(string label, string customId)
=> new ButtonBuilder(label, customId, ButtonStyle.Secondary);
public static ButtonBuilder CreateSecondaryButton(string label, string customId, IEmote emote = null)
=> new ButtonBuilder(label, customId, ButtonStyle.Secondary, emote: emote);

/// <summary>
/// Creates a button with the <see cref="ButtonStyle.Success"/> style.
/// </summary>
/// <param name="label">The label for this success button.</param>
/// <param name="customId">The custom id for this success button.</param>
/// <param name="emote">The emote for this success button</param>
/// <returns>A builder with the newly created button.</returns>
public static ButtonBuilder CreateSuccessButton(string label, string customId)
=> new ButtonBuilder(label, customId, ButtonStyle.Success);
public static ButtonBuilder CreateSuccessButton(string label, string customId, IEmote emote = null)
=> new ButtonBuilder(label, customId, ButtonStyle.Success, emote: emote);

/// <summary>
/// Sets the current buttons label to the specified text.


+ 4
- 3
src/Discord.Net.Core/Entities/Messages/MessageProperties.cs View File

@@ -4,7 +4,7 @@ namespace Discord
/// Properties that are used to modify an <see cref="IUserMessage" /> with the specified changes.
/// </summary>
/// <remarks>
/// The content of a message can be cleared with <see cref="System.String.Empty"/> if and only if an
/// The content of a message can be cleared with <see cref="System.String.Empty"/> if and only if an
/// <see cref="Discord.Embed"/> is present.
/// </remarks>
/// <seealso cref="IUserMessage.ModifyAsync"/>
@@ -17,10 +17,11 @@ namespace Discord
/// This must be less than the constant defined by <see cref="DiscordConfig.MaxMessageSize"/>.
/// </remarks>
public Optional<string> Content { get; set; }

/// <summary>
/// Gets or sets the embed the message should display.
/// Gets or sets the embeds of the message.
/// </summary>
public Optional<Embed> Embed { get; set; }
public Optional<Embed[]> Embeds { get; set; }

/// <summary>
/// Gets or sets the components for this message.


+ 1
- 1
src/Discord.Net.Rest/API/Common/InteractionCallbackData.cs View File

@@ -11,7 +11,7 @@ namespace Discord.API
public Optional<string> Content { get; set; }

[JsonProperty("embeds")]
public Optional<Embed[]> Embeds { get; set; }
public Optional<API.Embed[]> Embeds { get; set; }

[JsonProperty("allowed_mentions")]
public Optional<AllowedMentions> AllowedMentions { get; set; }


+ 1
- 6
src/Discord.Net.Rest/API/Rest/CreateWebhookMessageParams.cs View File

@@ -7,7 +7,7 @@ namespace Discord.API.Rest
internal class CreateWebhookMessageParams
{
[JsonProperty("content")]
public string Content { get; }
public string Content { get; set; }

[JsonProperty("nonce")]
public Optional<string> Nonce { get; set; }
@@ -32,10 +32,5 @@ namespace Discord.API.Rest

[JsonProperty("components")]
public Optional<API.ActionRowComponent[]> Components { get; set; }

public CreateWebhookMessageParams(string content)
{
Content = content;
}
}
}

+ 2
- 2
src/Discord.Net.Rest/API/Rest/ModifyMessageParams.cs View File

@@ -8,8 +8,8 @@ namespace Discord.API.Rest
{
[JsonProperty("content")]
public Optional<string> Content { get; set; }
[JsonProperty("embed")]
public Optional<Embed> Embed { get; set; }
[JsonProperty("embeds")]
public Optional<API.Embed[]> Embeds { get; set; }
[JsonProperty("components")]
public Optional<API.ActionRowComponent[]> Components { get; set; }
[JsonProperty("flags")]


+ 8
- 14
src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs View File

@@ -4,7 +4,6 @@ using Discord.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord.Rest
@@ -21,7 +20,7 @@ namespace Discord.Rest
return client.ApiClient.BulkOverwriteGlobalApplicationCommands(new CreateApplicationCommandParams[0], options);
}

public static Task SendInteractionResponse(BaseDiscordClient client, IMessageChannel channel, InteractionResponse response,
public static Task SendInteractionResponse(BaseDiscordClient client, InteractionResponse response,
ulong interactionId, string interactionToken, RequestOptions options = null)
{
return client.ApiClient.CreateInteractionResponse(response, interactionId, interactionToken, options);
@@ -298,14 +297,14 @@ namespace Discord.Rest
func(args);

bool hasText = args.Content.IsSpecified ? !string.IsNullOrEmpty(args.Content.Value) : !string.IsNullOrEmpty(message.Content);
bool hasEmbed = args.Embed.IsSpecified ? args.Embed.Value != null : message.Embeds.Any();
bool hasEmbed = args.Embeds.IsSpecified ? args.Embeds.Value != null : message.Embeds.Any();
if (!hasText && !hasEmbed)
Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content));

var apiArgs = new API.Rest.ModifyInteractionResponseParams
{
Content = args.Content,
Embeds = args.Embed.IsSpecified ? new API.Embed[] { args.Embed.Value.ToModel() } : Optional.Create<API.Embed[]>(),
Embeds = args.Embeds.IsSpecified ? args.Embeds.Value.Select(x => x.ToModel()).ToArray() : Optional.Create<API.Embed[]>(),
AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional<API.AllowedMentions>.Unspecified,
Components = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional<API.ActionRowComponent[]>.Unspecified,
};
@@ -316,26 +315,21 @@ namespace Discord.Rest
public static async Task DeleteFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, RequestOptions options = null)
=> await client.ApiClient.DeleteInteractionFollowupMessage(message.Id, message.Token, options);

public static async Task<Discord.API.Message> ModifyInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, Action<MessageProperties> func,
public static async Task<Message> ModifyInteractionResponse(BaseDiscordClient client, string token, Action<MessageProperties> func,
RequestOptions options = null)
{
var args = new MessageProperties();
func(args);

bool hasText = args.Content.IsSpecified ? !string.IsNullOrEmpty(args.Content.Value) : !string.IsNullOrEmpty(message.Content);
bool hasEmbed = args.Embed.IsSpecified ? args.Embed.Value != null : message.Embeds.Any();
if (!hasText && !hasEmbed)
Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content));

var apiArgs = new API.Rest.ModifyInteractionResponseParams
var apiArgs = new ModifyInteractionResponseParams
{
Content = args.Content,
Embeds = args.Embed.IsSpecified ? new API.Embed[] { args.Embed.Value.ToModel() } : Optional.Create<API.Embed[]>(),
AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional<API.AllowedMentions>.Unspecified,
Embeds = args.Embeds.IsSpecified ? args.Embeds.Value?.Select(x => x.ToModel()).ToArray() : Optional<API.Embed[]>.Unspecified,
AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value?.ToModel() : Optional<API.AllowedMentions>.Unspecified,
Components = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional<API.ActionRowComponent[]>.Unspecified,
};

return await client.ApiClient.ModifyInteractionResponse(apiArgs, message.Token, options).ConfigureAwait(false);
return await client.ApiClient.ModifyInteractionResponse(apiArgs, token, options).ConfigureAwait(false);
}

public static async Task DeletedInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null)


+ 9
- 8
src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs View File

@@ -30,11 +30,11 @@ namespace Discord.Rest
var args = new MessageProperties();
func(args);

if (msg.Author.Id != client.CurrentUser.Id && (args.Content.IsSpecified || args.Embed.IsSpecified || args.AllowedMentions.IsSpecified))
if (msg.Author.Id != client.CurrentUser.Id && (args.Content.IsSpecified || args.Embeds.IsSpecified || args.AllowedMentions.IsSpecified))
throw new InvalidOperationException("Only the author of a message may modify the message content, embed, or allowed mentions.");

bool hasText = args.Content.IsSpecified ? !string.IsNullOrEmpty(args.Content.Value) : !string.IsNullOrEmpty(msg.Content);
bool hasEmbed = args.Embed.IsSpecified ? args.Embed.Value != null : msg.Embeds.Any();
bool hasEmbed = args.Embeds.IsSpecified ? args.Embeds.Value != null : msg.Embeds.Any();
if (!hasText && !hasEmbed)
Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content));

@@ -61,13 +61,13 @@ namespace Discord.Rest
}
}

var apiArgs = new API.Rest.ModifyMessageParams
var apiArgs = new ModifyMessageParams
{
Content = args.Content,
Embed = args.Embed.IsSpecified ? args.Embed.Value.ToModel() : Optional.Create<API.Embed>(),
Embeds = args.Embeds.IsSpecified ? args.Embeds.Value.Select(x => x.ToModel()).ToArray() : Optional<API.Embed[]>.Unspecified,
Components = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional<API.ActionRowComponent[]>.Unspecified,
Flags = args.Flags.IsSpecified ? args.Flags.Value : Optional.Create<MessageFlags?>(),
AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional.Create<API.AllowedMentions>(),
Flags = args.Flags,
AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional<API.AllowedMentions>.Unspecified,
};
return await client.ApiClient.ModifyMessageAsync(msg.Channel.Id, msg.Id, apiArgs, options).ConfigureAwait(false);
}
@@ -78,7 +78,7 @@ namespace Discord.Rest
var args = new MessageProperties();
func(args);

if ((args.Content.IsSpecified && string.IsNullOrEmpty(args.Content.Value)) && (args.Embed.IsSpecified && args.Embed.Value == null))
if (args.Content.IsSpecified && string.IsNullOrEmpty(args.Content.Value) && args.Embeds.IsSpecified && args.Embeds.Value == null)
Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content));

if (args.AllowedMentions.IsSpecified)
@@ -86,6 +86,7 @@ namespace Discord.Rest
AllowedMentions allowedMentions = args.AllowedMentions.Value;
Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed.");
Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed.");
Preconditions.AtMost(args.Embeds.Value?.Length ?? 0, 10, nameof(args.Embeds), "A max of 10 embeds are allowed.");

// check that user flag and user Id list are exclusive, same with role flag and role Id list
if (allowedMentions != null && allowedMentions.AllowedTypes.HasValue)
@@ -107,7 +108,7 @@ namespace Discord.Rest
var apiArgs = new API.Rest.ModifyMessageParams
{
Content = args.Content,
Embed = args.Embed.IsSpecified ? args.Embed.Value.ToModel() : Optional.Create<API.Embed>(),
Embeds = args.Embeds.IsSpecified ? args.Embeds.Value.Select(x => x.ToModel()).ToArray() : Optional.Create<API.Embed[]>(),
Flags = args.Flags.IsSpecified ? args.Flags.Value : Optional.Create<MessageFlags?>(),
AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional.Create<API.AllowedMentions>(),
};


+ 1
- 4
src/Discord.Net.Rest/Entities/Messages/RestInteractionMessage.cs View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model = Discord.API.Message;

@@ -64,7 +61,7 @@ namespace Discord.Rest
{
try
{
var model = await InteractionHelper.ModifyInteractionResponse(Discord, this, func, options).ConfigureAwait(false);
var model = await InteractionHelper.ModifyInteractionResponse(Discord, this.Token, func, options).ConfigureAwait(false);
this.Update(model);
}
catch (Discord.Net.HttpException x)


+ 36
- 52
src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml View File

@@ -3223,16 +3223,24 @@
The message that contained the trigger for this interaction.
</summary>
</member>
<member name="M:Discord.WebSocket.SocketMessageComponent.RespondAsync(Discord.Embed[],System.String,System.Boolean,Discord.InteractionResponseType,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketMessageComponent.RespondAsync(System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<inheritdoc/>
</member>
<member name="M:Discord.WebSocket.SocketMessageComponent.FollowupAsync(Discord.Embed[],System.String,System.Boolean,System.Boolean,Discord.InteractionResponseType,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketMessageComponent.UpdateAsync(System.Action{Discord.MessageProperties},Discord.RequestOptions)">
<summary>
Updates the original message of the component on which the interaction was received on.
</summary>
<param name="func">A delegate containing the properties to modify the message with.</param>
<param name="options">The request options for this async request.</param>
</member>
<member name="M:Discord.WebSocket.SocketMessageComponent.FollowupAsync(System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<inheritdoc/>
</member>
<member name="M:Discord.WebSocket.SocketMessageComponent.AcknowledgeAsync(Discord.RequestOptions)">
<member name="M:Discord.WebSocket.SocketMessageComponent.DeferAsync(Discord.RequestOptions)">
<summary>
Acknowledges this interaction with the <see cref="F:Discord.InteractionResponseType.DeferredUpdateMessage"/>.
</summary>
<param name="options">The request options for this async request.</param>
<returns>
A task that represents the asynchronous operation of acknowledging the interaction.
</returns>
@@ -3341,14 +3349,19 @@
The data associated with this interaction.
</summary>
</member>
<member name="M:Discord.WebSocket.SocketSlashCommand.RespondAsync(Discord.Embed[],System.String,System.Boolean,Discord.InteractionResponseType,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketSlashCommand.RespondAsync(System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<inheritdoc/>
</member>
<member name="M:Discord.WebSocket.SocketSlashCommand.FollowupAsync(Discord.Embed[],System.String,System.Boolean,System.Boolean,Discord.InteractionResponseType,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketSlashCommand.FollowupAsync(System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<inheritdoc/>
</member>
<member name="M:Discord.WebSocket.SocketSlashCommand.AcknowledgeAsync(Discord.RequestOptions)">
<inheritdoc/>
<member name="M:Discord.WebSocket.SocketSlashCommand.DeferAsync(Discord.RequestOptions)">
<summary>
Acknowledges this interaction with the <see cref="F:Discord.InteractionResponseType.DeferredChannelMessageWithSource"/>.
</summary>
<returns>
A task that represents the asynchronous operation of acknowledging the interaction.
</returns>
</member>
<member name="T:Discord.WebSocket.SocketSlashCommandData">
<summary>
@@ -3425,18 +3438,17 @@
<see langword="true"/> if the token is valid for replying to, otherwise <see langword="false"/>.
</summary>
</member>
<member name="M:Discord.WebSocket.SocketInteraction.RespondAsync(System.String,System.Boolean,Discord.Embed,Discord.InteractionResponseType,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketInteraction.RespondAsync(System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<summary>
Responds to an Interaction.
Responds to an Interaction with type <see cref="F:Discord.InteractionResponseType.ChannelMessageWithSource"/>.
<para>
If you have <see cref="P:Discord.WebSocket.DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use
<see cref="M:Discord.WebSocket.SocketInteraction.FollowupAsync(Discord.Embed[],System.String,System.Boolean,System.Boolean,Discord.InteractionResponseType,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)"/> instead.
<see cref="!:FollowupAsync(Discord.Embed[],string,bool,bool,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)"/> instead.
</para>
</summary>
<param name="text">The text of the message to be sent.</param>
<param name="embeds">A array of embeds to send with this response. Max 10</param>
<param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/>.</param>
<param name="embed">A <see cref="T:Discord.Embed"/> to send with this response.</param>
<param name="type">The type of response to this Interaction.</param>
<param name="ephemeral"><see langword="true"/> if the response should be hidden to everyone besides the invoker of the command, otherwise <see langword="false"/>.</param>
<param name="allowedMentions">The allowed mentions for this response.</param>
<param name="options">The request options for this response.</param>
@@ -3444,49 +3456,13 @@
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
<exception cref="T:System.InvalidOperationException">The parameters provided were invalid or the token was invalid.</exception>
</member>
<member name="M:Discord.WebSocket.SocketInteraction.FollowupAsync(System.String,System.Boolean,Discord.Embed,Discord.InteractionResponseType,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketInteraction.FollowupAsync(System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<summary>
Sends a followup message for this interaction.
</summary>
<param name="text">The text of the message to be sent</param>
<param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/>.</param>
<param name="embed">A <see cref="T:Discord.Embed"/> to send with this response</param>
<param name="type">The type of response to this Interaction.</param>
<param name="ephemeral"><see langword="true"/> if the response should be hidden to everyone besides the invoker of the command, otherwise <see langword="false"/>.</param>
<param name="allowedMentions">The allowed mentions for this response.</param>
<param name="options">The request options for this response.</param>
<param name="component">A <see cref="T:Discord.MessageComponent"/> to be sent with this response</param>
<returns>
The sent message.
</returns>
</member>
<member name="M:Discord.WebSocket.SocketInteraction.RespondAsync(Discord.Embed[],System.String,System.Boolean,Discord.InteractionResponseType,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<summary>
Responds to an Interaction.
<para>
If you have <see cref="P:Discord.WebSocket.DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use
<see cref="M:Discord.WebSocket.SocketInteraction.FollowupAsync(Discord.Embed[],System.String,System.Boolean,System.Boolean,Discord.InteractionResponseType,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)"/> instead.
</para>
</summary>
<param name="text">The text of the message to be sent.</param>
<param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/>.</param>
<param name="embeds">A array of embeds to send with this response. Max 10</param>
<param name="type">The type of response to this Interaction.</param>
<param name="ephemeral"><see langword="true"/> if the response should be hidden to everyone besides the invoker of the command, otherwise <see langword="false"/>.</param>
<param name="allowedMentions">The allowed mentions for this response.</param>
<param name="options">The request options for this response.</param>
<param name="component">A <see cref="T:Discord.MessageComponent"/> to be sent with this response</param>
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
<exception cref="T:System.InvalidOperationException">The parameters provided were invalid or the token was invalid.</exception>
</member>
<member name="M:Discord.WebSocket.SocketInteraction.FollowupAsync(Discord.Embed[],System.String,System.Boolean,System.Boolean,Discord.InteractionResponseType,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)">
<summary>
Sends a followup message for this interaction.
</summary>
<param name="text">The text of the message to be sent</param>
<param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/>.</param>
<param name="embeds">A array of embeds to send with this response. Max 10</param>
<param name="type">The type of response to this Interaction.</param>
<param name="ephemeral"><see langword="true"/> if the response should be hidden to everyone besides the invoker of the command, otherwise <see langword="false"/>.</param>
<param name="allowedMentions">The allowed mentions for this response.</param>
<param name="options">The request options for this response.</param>
@@ -3500,11 +3476,19 @@
Gets the original response for this interaction.
</summary>
<param name="options">The request options for this async request.</param>
<returns>A <see cref="T:Discord.Rest.RestInteractionMessage"/> that represents the intitial response, or <see langword="null"/> if there is no response.</returns>
<returns>A <see cref="T:Discord.Rest.RestInteractionMessage"/> that represents the initial response.</returns>
</member>
<member name="M:Discord.WebSocket.SocketInteraction.AcknowledgeAsync(Discord.RequestOptions)">
<member name="M:Discord.WebSocket.SocketInteraction.ModifyOriginalResponseAsync(System.Action{Discord.MessageProperties},Discord.RequestOptions)">
<summary>
Acknowledges this interaction with the <see cref="F:Discord.InteractionResponseType.DeferredChannelMessageWithSource"/>.
Edits original response for this interaction.
</summary>
<param name="func">A delegate containing the properties to modify the message with.</param>
<param name="options">The request options for this async request.</param>
<returns>A <see cref="T:Discord.Rest.RestInteractionMessage"/> that represents the initial response.</returns>
</member>
<member name="M:Discord.WebSocket.SocketInteraction.DeferAsync(Discord.RequestOptions)">
<summary>
Acknowledges this interaction.
</summary>
<returns>
A task that represents the asynchronous operation of acknowledging the interaction.


+ 1
- 1
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -1904,7 +1904,7 @@ namespace Discord.WebSocket
var interaction = SocketInteraction.Create(this, data, channel as ISocketMessageChannel);

if (this.AlwaysAcknowledgeInteractions)
await interaction.AcknowledgeAsync().ConfigureAwait(false);
await interaction.DeferAsync().ConfigureAwait(false);

await TimedInvokeAsync(_interactionCreatedEvent, nameof(InteractionCreated), interaction).ConfigureAwait(false);
}


+ 85
- 24
src/Discord.Net.WebSocket/Entities/Interaction/Message Components/SocketMessageComponent.cs View File

@@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model = Discord.API.Interaction;
using DataModel = Discord.API.MessageComponentInteractionData;
using Newtonsoft.Json.Linq;
using Discord.Rest;

namespace Discord.WebSocket
@@ -71,18 +68,21 @@ namespace Discord.WebSocket
}

/// <inheritdoc/>
public override async Task RespondAsync(Embed[] embeds = null, string text = null, bool isTTS = false, InteractionResponseType type = InteractionResponseType.ChannelMessageWithSource,
bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null)
public override async Task RespondAsync(
string text = null,
Embed[] embeds = null,
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
RequestOptions options = null,
MessageComponent component = null)
{
if (type == InteractionResponseType.Pong)
throw new InvalidOperationException($"Cannot use {Type} on a send message function");

if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");

if (Discord.AlwaysAcknowledgeInteractions)
{
await FollowupAsync(embeds, text, isTTS, ephemeral, type, allowedMentions, options);
await FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, options);
return;
}

@@ -109,13 +109,13 @@ namespace Discord.WebSocket

var response = new API.InteractionResponse
{
Type = type,
Type = InteractionResponseType.ChannelMessageWithSource,
Data = new API.InteractionCallbackData
{
Content = text ?? Optional<string>.Unspecified,
AllowedMentions = allowedMentions?.ToModel(),
Embeds = embeds?.Select(x => x.ToModel()).ToArray() ?? Optional<API.Embed[]>.Unspecified,
TTS = type == InteractionResponseType.ChannelMessageWithSource ? isTTS : Optional<bool>.Unspecified,
TTS = isTTS,
Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified
}
};
@@ -123,17 +123,78 @@ namespace Discord.WebSocket
if (ephemeral)
response.Data.Value.Flags = 64;

await InteractionHelper.SendInteractionResponse(this.Discord, this.Channel, response, this.Id, Token, options);
await InteractionHelper.SendInteractionResponse(this.Discord, response, this.Id, Token, options);
}

/// <inheritdoc/>
public override async Task<RestFollowupMessage> FollowupAsync(Embed[] embeds = null, string text = null, bool isTTS = false, bool ephemeral = false,
InteractionResponseType type = InteractionResponseType.ChannelMessageWithSource,
AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null)
/// <summary>
/// Updates the message which this component resides in with the type <see cref="InteractionResponseType.UpdateMessage"/>
/// </summary>
/// <param name="func">A delegate containing the properties to modify the message with.</param>
/// <param name="options">The request options for this async request.</param>
/// <returns>A task that represents the asynchronous operation of updating the message.</returns>
public async Task UpdateAsync(Action<MessageProperties> func, RequestOptions options = null)
{
if (type == InteractionResponseType.DeferredChannelMessageWithSource || type == InteractionResponseType.DeferredChannelMessageWithSource || type == InteractionResponseType.Pong)
throw new InvalidOperationException($"Cannot use {type} on a slash command!");
var args = new MessageProperties();
func(args);

if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");

if (args.AllowedMentions.IsSpecified)
{
var allowedMentions = args.AllowedMentions.Value;
Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions), "A max of 100 role Ids are allowed.");
Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions), "A max of 100 user Ids are allowed.");
}

if (args.Embeds.IsSpecified)
Preconditions.AtMost(args.Embeds.Value?.Length ?? 0, 10, nameof(args.Embeds), "A max of 10 embeds are allowed.");

// check that user flag and user Id list are exclusive, same with role flag and role Id list
if (args.AllowedMentions.IsSpecified && args.AllowedMentions.Value != null && args.AllowedMentions.Value.AllowedTypes.HasValue)
{
var allowedMentions = args.AllowedMentions.Value;
if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Users)
&& allowedMentions.UserIds != null && allowedMentions.UserIds.Count > 0)
{
throw new ArgumentException("The Users flag is mutually exclusive with the list of User Ids.", nameof(args.AllowedMentions));
}

if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Roles)
&& allowedMentions.RoleIds != null && allowedMentions.RoleIds.Count > 0)
{
throw new ArgumentException("The Roles flag is mutually exclusive with the list of Role Ids.", nameof(args.AllowedMentions));
}
}

var response = new API.InteractionResponse
{
Type = InteractionResponseType.UpdateMessage,
Data = new API.InteractionCallbackData
{
Content = args.Content,
AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value?.ToModel() : Optional<API.AllowedMentions>.Unspecified,
Embeds = args.Embeds.IsSpecified ? args.Embeds.Value?.Select(x => x.ToModel()).ToArray() : Optional<API.Embed[]>.Unspecified,
Components = args.Components.IsSpecified
? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray()
: Optional<API.ActionRowComponent[]>.Unspecified,
Flags = args.Flags.IsSpecified ? (int?)args.Flags.Value ?? Optional<int>.Unspecified : Optional<int>.Unspecified
}
};

await InteractionHelper.SendInteractionResponse(this.Discord, response, this.Id, this.Token, options);
}

/// <inheritdoc/>
public override async Task<RestFollowupMessage> FollowupAsync(
string text = null,
Embed[] embeds = null,
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
RequestOptions options = null,
MessageComponent component = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");

@@ -141,13 +202,12 @@ namespace Discord.WebSocket
Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed.");
Preconditions.AtMost(embeds?.Length ?? 0, 10, nameof(embeds), "A max of 10 embeds are allowed.");

var args = new API.Rest.CreateWebhookMessageParams(text)
var args = new API.Rest.CreateWebhookMessageParams
{
AllowedMentions = allowedMentions?.ToModel(),
Content = text,
AllowedMentions = allowedMentions?.ToModel() ?? Optional<API.AllowedMentions>.Unspecified,
IsTTS = isTTS,
Embeds = embeds != null
? embeds.Select(x => x.ToModel()).ToArray()
: Optional<API.Embed[]>.Unspecified,
Embeds = embeds?.Select(x => x.ToModel()).ToArray() ?? Optional<API.Embed[]>.Unspecified,
Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified
};

@@ -160,10 +220,11 @@ namespace Discord.WebSocket
/// <summary>
/// Acknowledges this interaction with the <see cref="InteractionResponseType.DeferredUpdateMessage"/>.
/// </summary>
/// <param name="options">The request options for this async request.</param>
/// <returns>
/// A task that represents the asynchronous operation of acknowledging the interaction.
/// </returns>
public override Task AcknowledgeAsync(RequestOptions options = null)
public override Task DeferAsync(RequestOptions options = null)
{
var response = new API.InteractionResponse()
{


+ 34
- 29
src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommand.cs View File

@@ -1,5 +1,4 @@
using Discord.Rest;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Threading.Tasks;
@@ -16,7 +15,7 @@ namespace Discord.WebSocket
/// <summary>
/// The data associated with this interaction.
/// </summary>
new public SocketSlashCommandData Data { get; private set; }
new public SocketSlashCommandData Data { get; }

internal SocketSlashCommand(DiscordSocketClient client, Model model, ISocketMessageChannel channel)
: base(client, model.Id, channel)
@@ -51,21 +50,21 @@ namespace Discord.WebSocket
}

/// <inheritdoc/>
public override async Task RespondAsync(Embed[] embeds = null, string text = null, bool isTTS = false, InteractionResponseType type = InteractionResponseType.ChannelMessageWithSource,
bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null)
public override async Task RespondAsync(
string text = null,
Embed[] embeds = null,
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
RequestOptions options = null,
MessageComponent component = null)
{
if (type == InteractionResponseType.Pong)
throw new InvalidOperationException($"Cannot use {Type} on a send message function");

if(type == InteractionResponseType.DeferredUpdateMessage || type == InteractionResponseType.UpdateMessage)
throw new InvalidOperationException($"Cannot use {Type} on a slash command!");

if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");

if (Discord.AlwaysAcknowledgeInteractions)
{
await FollowupAsync(embeds, text, isTTS, ephemeral, type, allowedMentions, options, component);
await FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, options, component);
return;
}

@@ -92,11 +91,11 @@ namespace Discord.WebSocket

var response = new API.InteractionResponse
{
Type = type,
Type = InteractionResponseType.ChannelMessageWithSource,
Data = new API.InteractionCallbackData
{
Content = text ?? Optional<string>.Unspecified,
AllowedMentions = allowedMentions?.ToModel(),
Content = text,
AllowedMentions = allowedMentions?.ToModel() ?? Optional<API.AllowedMentions>.Unspecified,
Embeds = embeds?.Select(x => x.ToModel()).ToArray() ?? Optional<API.Embed[]>.Unspecified,
TTS = isTTS ? true : Optional<bool>.Unspecified,
Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified
@@ -106,17 +105,19 @@ namespace Discord.WebSocket
if (ephemeral)
response.Data.Value.Flags = 64;

await InteractionHelper.SendInteractionResponse(this.Discord, this.Channel, response, this.Id, Token, options);
await InteractionHelper.SendInteractionResponse(this.Discord, response, this.Id, Token, options);
}

/// <inheritdoc/>
public override async Task<RestFollowupMessage> FollowupAsync(Embed[] embeds = null, string text = null, bool isTTS = false, bool ephemeral = false,
InteractionResponseType type = InteractionResponseType.ChannelMessageWithSource,
AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null)
public override async Task<RestFollowupMessage> FollowupAsync(
string text = null,
Embed[] embeds = null,
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
RequestOptions options = null,
MessageComponent component = null)
{
if (type == InteractionResponseType.DeferredChannelMessageWithSource || type == InteractionResponseType.DeferredChannelMessageWithSource || type == InteractionResponseType.Pong || type == InteractionResponseType.DeferredUpdateMessage || type == InteractionResponseType.UpdateMessage)
throw new InvalidOperationException($"Cannot use {type} on a slash command!");

if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");

@@ -124,13 +125,12 @@ namespace Discord.WebSocket
Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed.");
Preconditions.AtMost(embeds?.Length ?? 0, 10, nameof(embeds), "A max of 10 embeds are allowed.");

var args = new API.Rest.CreateWebhookMessageParams(text)
var args = new API.Rest.CreateWebhookMessageParams
{
AllowedMentions = allowedMentions?.ToModel(),
Content = text,
AllowedMentions = allowedMentions?.ToModel() ?? Optional<API.AllowedMentions>.Unspecified,
IsTTS = isTTS,
Embeds = embeds != null
? embeds.Select(x => x.ToModel()).ToArray()
: Optional<API.Embed[]>.Unspecified,
Embeds = embeds?.Select(x => x.ToModel()).ToArray() ?? Optional<API.Embed[]>.Unspecified,
Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified
};

@@ -140,10 +140,15 @@ namespace Discord.WebSocket
return await InteractionHelper.SendFollowupAsync(Discord.Rest, args, Token, Channel, options);
}

/// <inheritdoc/>
public override Task AcknowledgeAsync(RequestOptions options = null)
/// <summary>
/// Acknowledges this interaction with the <see cref="InteractionResponseType.DeferredChannelMessageWithSource"/>.
/// </summary>
/// <returns>
/// A task that represents the asynchronous operation of acknowledging the interaction.
/// </returns>
public override Task DeferAsync(RequestOptions options = null)
{
var response = new API.InteractionResponse()
var response = new API.InteractionResponse
{
Type = InteractionResponseType.DeferredChannelMessageWithSource,
};


+ 30
- 54
src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs View File

@@ -1,8 +1,5 @@
using Discord.Rest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model = Discord.API.Interaction;

@@ -96,71 +93,30 @@ namespace Discord.WebSocket
}

/// <summary>
/// Responds to an Interaction.
/// Responds to an Interaction with type <see cref="InteractionResponseType.ChannelMessageWithSource"/>.
/// <para>
/// If you have <see cref="DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use
/// <see cref="FollowupAsync(Embed[],string, bool, bool, InteractionResponseType, AllowedMentions, RequestOptions, MessageComponent)"/> instead.
/// <see cref="FollowupAsync(Discord.Embed[],string,bool,bool,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent)"/> instead.
/// </para>
/// </summary>
/// <param name="text">The text of the message to be sent.</param>
/// <param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/>.</param>
/// <param name="embed">A <see cref="Embed"/> to send with this response.</param>
/// <param name="type">The type of response to this Interaction.</param>
/// <param name="ephemeral"><see langword="true"/> if the response should be hidden to everyone besides the invoker of the command, otherwise <see langword="false"/>.</param>
/// <param name="allowedMentions">The allowed mentions for this response.</param>
/// <param name="options">The request options for this response.</param>
/// <param name="component">A <see cref="MessageComponent"/> to be sent with this response</param>
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
/// <exception cref="InvalidOperationException">The parameters provided were invalid or the token was invalid.</exception>
public Task RespondAsync(string text = null, bool isTTS = false, Embed embed = null, InteractionResponseType type = InteractionResponseType.ChannelMessageWithSource,
bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null)
=> RespondAsync(embed != null ? new Embed[] { embed } : null, text, isTTS, type, ephemeral, allowedMentions, options, component);

/// <summary>
/// Sends a followup message for this interaction.
/// </summary>
/// <param name="text">The text of the message to be sent</param>
/// <param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/>.</param>
/// <param name="embed">A <see cref="Embed"/> to send with this response</param>
/// <param name="type">The type of response to this Interaction.</param>
/// <param name="ephemeral"><see langword="true"/> if the response should be hidden to everyone besides the invoker of the command, otherwise <see langword="false"/>.</param>
/// <param name="allowedMentions">The allowed mentions for this response.</param>
/// <param name="options">The request options for this response.</param>
/// <param name="component">A <see cref="MessageComponent"/> to be sent with this response</param>
/// <returns>
/// The sent message.
/// </returns>
public Task<RestFollowupMessage> FollowupAsync(string text = null, bool isTTS = false, Embed embed = null, InteractionResponseType type = InteractionResponseType.ChannelMessageWithSource,
bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null)
=> FollowupAsync(embed != null ? new Embed[] { embed } : null, text, isTTS, ephemeral, type, allowedMentions, options, component);
/// <summary>
/// Responds to an Interaction.
/// <para>
/// If you have <see cref="DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use
/// <see cref="FollowupAsync( Embed[],string, bool, bool, InteractionResponseType, AllowedMentions, RequestOptions, MessageComponent)"/> instead.
/// </para>
/// </summary>
/// <param name="text">The text of the message to be sent.</param>
/// <param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/>.</param>
/// <param name="embeds">A array of embeds to send with this response. Max 10</param>
/// <param name="type">The type of response to this Interaction.</param>
/// <param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/>.</param>
/// <param name="ephemeral"><see langword="true"/> if the response should be hidden to everyone besides the invoker of the command, otherwise <see langword="false"/>.</param>
/// <param name="allowedMentions">The allowed mentions for this response.</param>
/// <param name="options">The request options for this response.</param>
/// <param name="component">A <see cref="MessageComponent"/> to be sent with this response</param>
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
/// <exception cref="InvalidOperationException">The parameters provided were invalid or the token was invalid.</exception>

public abstract Task RespondAsync(Embed[] embeds = null, string text = null, bool isTTS = false, InteractionResponseType type = InteractionResponseType.ChannelMessageWithSource,
public abstract Task RespondAsync(string text = null, Embed[] embeds = null, bool isTTS = false,
bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null);

/// <summary>
/// Sends a followup message for this interaction.
/// </summary>
/// <param name="text">The text of the message to be sent</param>
/// <param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/>.</param>
/// <param name="embeds">A array of embeds to send with this response. Max 10</param>
/// <param name="type">The type of response to this Interaction.</param>
/// <param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/>.</param>
/// <param name="ephemeral"><see langword="true"/> if the response should be hidden to everyone besides the invoker of the command, otherwise <see langword="false"/>.</param>
/// <param name="allowedMentions">The allowed mentions for this response.</param>
/// <param name="options">The request options for this response.</param>
@@ -168,25 +124,45 @@ namespace Discord.WebSocket
/// <returns>
/// The sent message.
/// </returns>
public abstract Task<RestFollowupMessage> FollowupAsync(Embed[] embeds = null, string text = null, bool isTTS = false, bool ephemeral = false,
InteractionResponseType type = InteractionResponseType.ChannelMessageWithSource,
public abstract Task<RestFollowupMessage> FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null);

/// <summary>
/// Gets the original response for this interaction.
/// </summary>
/// <param name="options">The request options for this async request.</param>
/// <returns>A <see cref="RestInteractionMessage"/> that represents the intitial response, or <see langword="null"/> if there is no response.</returns>
/// <returns>A <see cref="RestInteractionMessage"/> that represents the initial response.</returns>
public Task<RestInteractionMessage> GetOriginalResponseAsync(RequestOptions options = null)
=> InteractionHelper.GetOriginalResponseAsync(this.Discord, this.Channel, this, options);

/// <summary>
/// Acknowledges this interaction with the <see cref="InteractionResponseType.DeferredChannelMessageWithSource"/>.
/// Edits original response for this interaction.
/// </summary>
/// <param name="func">A delegate containing the properties to modify the message with.</param>
/// <param name="options">The request options for this async request.</param>
/// <returns>A <see cref="RestInteractionMessage"/> that represents the initial response.</returns>
public async Task<RestInteractionMessage> ModifyOriginalResponseAsync(Action<MessageProperties> func, RequestOptions options = null)
{
var model = await InteractionHelper.ModifyInteractionResponse(this.Discord, this.Token, func, options);
return RestInteractionMessage.Create(this.Discord, model, this.Token, this.Channel);
}

/// <summary>
/// Acknowledges this interaction.
/// </summary>
/// <returns>
/// A task that represents the asynchronous operation of acknowledging the interaction.
/// </returns>
[Obsolete("This method deprecated, please use DeferAsync instead")]
public Task AcknowledgeAsync(RequestOptions options = null) => DeferAsync(options);

/// <summary>
/// Acknowledges this interaction.
/// </summary>
/// <returns>
/// A task that represents the asynchronous operation of acknowledging the interaction.
/// </returns>
public abstract Task AcknowledgeAsync(RequestOptions options = null);
public abstract Task DeferAsync(RequestOptions options = null);

private bool CheckToken()
{


+ 7
- 2
src/Discord.Net.Webhook/WebhookClientHelper.cs View File

@@ -20,10 +20,15 @@ namespace Discord.Webhook
throw new InvalidOperationException("Could not find a webhook with the supplied credentials.");
return RestInternalWebhook.Create(client, model);
}
public static async Task<ulong> SendMessageAsync(DiscordWebhookClient client,
public static async Task<ulong> SendMessageAsync(DiscordWebhookClient client,
string text, bool isTTS, IEnumerable<Embed> embeds, string username, string avatarUrl, AllowedMentions allowedMentions, RequestOptions options)
{
var args = new CreateWebhookMessageParams(text) { IsTTS = isTTS };
var args = new CreateWebhookMessageParams
{
Content = text,
IsTTS = isTTS
};

if (embeds != null)
args.Embeds = embeds.Select(x => x.ToModel()).ToArray();
if (username != null)


Loading…
Cancel
Save