* Refactor emojis/emotes & SelectMenu * Update Emoji.cs * Continue emoji refactor * Remove WithLabel from example of SelectMenuBuilder * Remove EmojiUtils and move it stuff to Emoji * Revertpull/1923/head0fbf1000da
* Revert "Update Emoji.cs" and add Parse method This reverts commitf297dcfc43
. * Partial revert3c27ab36c9
* 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
@@ -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"> | |||
@@ -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,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. | |||
@@ -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; } | |||
@@ -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; | |||
} | |||
} | |||
} |
@@ -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")] | |||
@@ -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) | |||
@@ -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,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) | |||
@@ -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. | |||
@@ -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); | |||
} | |||
@@ -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() | |||
{ | |||
@@ -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, | |||
}; | |||
@@ -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() | |||
{ | |||
@@ -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) | |||