* 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. | Properties that are used to modify an <see cref="T:Discord.IUserMessage" /> with the specified changes. | ||||
| </summary> | </summary> | ||||
| <remarks> | <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. | <see cref="T:Discord.Embed"/> is present. | ||||
| </remarks> | </remarks> | ||||
| <seealso cref="M:Discord.IUserMessage.ModifyAsync(System.Action{Discord.MessageProperties},Discord.RequestOptions)"/> | <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"/>. | This must be less than the constant defined by <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>. | ||||
| </remarks> | </remarks> | ||||
| </member> | </member> | ||||
| <member name="P:Discord.MessageProperties.Embed"> | |||||
| <member name="P:Discord.MessageProperties.Embeds"> | |||||
| <summary> | <summary> | ||||
| Gets or sets the embed the message should display. | |||||
| Gets or sets the embeds of the message. | |||||
| </summary> | </summary> | ||||
| </member> | </member> | ||||
| <member name="P:Discord.MessageProperties.Components"> | <member name="P:Discord.MessageProperties.Components"> | ||||
| @@ -120,7 +120,8 @@ namespace Discord | |||||
| } | } | ||||
| /// <summary> | /// <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> | /// </summary> | ||||
| /// <param name="label">The label text for the newly added button.</param> | /// <param name="label">The label text for the newly added button.</param> | ||||
| /// <param name="style">The style of this 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> | /// <param name="row">The row the button should be placed on.</param> | ||||
| /// <returns>The current builder.</returns> | /// <returns>The current builder.</returns> | ||||
| public ComponentBuilder WithButton( | public ComponentBuilder WithButton( | ||||
| string label, | |||||
| string customId, | |||||
| string label = null, | |||||
| string customId = null, | |||||
| ButtonStyle style = ButtonStyle.Primary, | ButtonStyle style = ButtonStyle.Primary, | ||||
| IEmote emote = null, | IEmote emote = null, | ||||
| string url = null, | string url = null, | ||||
| @@ -374,7 +375,7 @@ namespace Discord | |||||
| /// <param name="style">The custom ID of this button</param> | /// <param name="style">The custom ID of this button</param> | ||||
| /// <param name="emote">The emote of this button</param> | /// <param name="emote">The emote of this button</param> | ||||
| /// <param name="disabled">Disabled this button or not</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.CustomId = customId; | ||||
| this.Style = style; | this.Style = style; | ||||
| @@ -400,47 +401,52 @@ namespace Discord | |||||
| /// <summary> | /// <summary> | ||||
| /// Creates a button with the <see cref="ButtonStyle.Link"/> style. | /// Creates a button with the <see cref="ButtonStyle.Link"/> style. | ||||
| /// </summary> | /// </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="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> | /// <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> | /// <summary> | ||||
| /// Creates a button with the <see cref="ButtonStyle.Danger"/> style. | /// Creates a button with the <see cref="ButtonStyle.Danger"/> style. | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="label">The label for this danger button.</param> | /// <param name="label">The label for this danger button.</param> | ||||
| /// <param name="customId">The custom id 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> | /// <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> | /// <summary> | ||||
| /// Creates a button with the <see cref="ButtonStyle.Primary"/> style. | /// Creates a button with the <see cref="ButtonStyle.Primary"/> style. | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="label">The label for this primary button.</param> | /// <param name="label">The label for this primary button.</param> | ||||
| /// <param name="customId">The custom id 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> | /// <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> | /// <summary> | ||||
| /// Creates a button with the <see cref="ButtonStyle.Secondary"/> style. | /// Creates a button with the <see cref="ButtonStyle.Secondary"/> style. | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="label">The label for this secondary button.</param> | /// <param name="label">The label for this secondary button.</param> | ||||
| /// <param name="customId">The custom id 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> | /// <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> | /// <summary> | ||||
| /// Creates a button with the <see cref="ButtonStyle.Success"/> style. | /// Creates a button with the <see cref="ButtonStyle.Success"/> style. | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="label">The label for this success button.</param> | /// <param name="label">The label for this success button.</param> | ||||
| /// <param name="customId">The custom id 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> | /// <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> | /// <summary> | ||||
| /// Sets the current buttons label to the specified text. | /// 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. | /// Properties that are used to modify an <see cref="IUserMessage" /> with the specified changes. | ||||
| /// </summary> | /// </summary> | ||||
| /// <remarks> | /// <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. | /// <see cref="Discord.Embed"/> is present. | ||||
| /// </remarks> | /// </remarks> | ||||
| /// <seealso cref="IUserMessage.ModifyAsync"/> | /// <seealso cref="IUserMessage.ModifyAsync"/> | ||||
| @@ -17,10 +17,11 @@ namespace Discord | |||||
| /// This must be less than the constant defined by <see cref="DiscordConfig.MaxMessageSize"/>. | /// This must be less than the constant defined by <see cref="DiscordConfig.MaxMessageSize"/>. | ||||
| /// </remarks> | /// </remarks> | ||||
| public Optional<string> Content { get; set; } | public Optional<string> Content { get; set; } | ||||
| /// <summary> | /// <summary> | ||||
| /// Gets or sets the embed the message should display. | |||||
| /// Gets or sets the embeds of the message. | |||||
| /// </summary> | /// </summary> | ||||
| public Optional<Embed> Embed { get; set; } | |||||
| public Optional<Embed[]> Embeds { get; set; } | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets or sets the components for this message. | /// Gets or sets the components for this message. | ||||
| @@ -11,7 +11,7 @@ namespace Discord.API | |||||
| public Optional<string> Content { get; set; } | public Optional<string> Content { get; set; } | ||||
| [JsonProperty("embeds")] | [JsonProperty("embeds")] | ||||
| public Optional<Embed[]> Embeds { get; set; } | |||||
| public Optional<API.Embed[]> Embeds { get; set; } | |||||
| [JsonProperty("allowed_mentions")] | [JsonProperty("allowed_mentions")] | ||||
| public Optional<AllowedMentions> AllowedMentions { get; set; } | public Optional<AllowedMentions> AllowedMentions { get; set; } | ||||
| @@ -7,7 +7,7 @@ namespace Discord.API.Rest | |||||
| internal class CreateWebhookMessageParams | internal class CreateWebhookMessageParams | ||||
| { | { | ||||
| [JsonProperty("content")] | [JsonProperty("content")] | ||||
| public string Content { get; } | |||||
| public string Content { get; set; } | |||||
| [JsonProperty("nonce")] | [JsonProperty("nonce")] | ||||
| public Optional<string> Nonce { get; set; } | public Optional<string> Nonce { get; set; } | ||||
| @@ -32,10 +32,5 @@ namespace Discord.API.Rest | |||||
| [JsonProperty("components")] | [JsonProperty("components")] | ||||
| public Optional<API.ActionRowComponent[]> Components { get; set; } | public Optional<API.ActionRowComponent[]> Components { get; set; } | ||||
| public CreateWebhookMessageParams(string content) | |||||
| { | |||||
| Content = content; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -8,8 +8,8 @@ namespace Discord.API.Rest | |||||
| { | { | ||||
| [JsonProperty("content")] | [JsonProperty("content")] | ||||
| public Optional<string> Content { get; set; } | 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")] | [JsonProperty("components")] | ||||
| public Optional<API.ActionRowComponent[]> Components { get; set; } | public Optional<API.ActionRowComponent[]> Components { get; set; } | ||||
| [JsonProperty("flags")] | [JsonProperty("flags")] | ||||
| @@ -4,7 +4,6 @@ using Discord.Net; | |||||
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Linq; | using System.Linq; | ||||
| using System.Text; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| namespace Discord.Rest | namespace Discord.Rest | ||||
| @@ -21,7 +20,7 @@ namespace Discord.Rest | |||||
| return client.ApiClient.BulkOverwriteGlobalApplicationCommands(new CreateApplicationCommandParams[0], options); | 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) | ulong interactionId, string interactionToken, RequestOptions options = null) | ||||
| { | { | ||||
| return client.ApiClient.CreateInteractionResponse(response, interactionId, interactionToken, options); | return client.ApiClient.CreateInteractionResponse(response, interactionId, interactionToken, options); | ||||
| @@ -298,14 +297,14 @@ namespace Discord.Rest | |||||
| func(args); | func(args); | ||||
| bool hasText = args.Content.IsSpecified ? !string.IsNullOrEmpty(args.Content.Value) : !string.IsNullOrEmpty(message.Content); | 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) | if (!hasText && !hasEmbed) | ||||
| Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content)); | Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content)); | ||||
| var apiArgs = new API.Rest.ModifyInteractionResponseParams | var apiArgs = new API.Rest.ModifyInteractionResponseParams | ||||
| { | { | ||||
| Content = args.Content, | 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, | 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, | 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) | public static async Task DeleteFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, RequestOptions options = null) | ||||
| => await client.ApiClient.DeleteInteractionFollowupMessage(message.Id, message.Token, options); | => 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) | RequestOptions options = null) | ||||
| { | { | ||||
| var args = new MessageProperties(); | var args = new MessageProperties(); | ||||
| func(args); | 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, | 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, | 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) | public static async Task DeletedInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null) | ||||
| @@ -30,11 +30,11 @@ namespace Discord.Rest | |||||
| var args = new MessageProperties(); | var args = new MessageProperties(); | ||||
| func(args); | 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."); | 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 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) | if (!hasText && !hasEmbed) | ||||
| Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content)); | 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, | 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, | 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); | 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(); | var args = new MessageProperties(); | ||||
| func(args); | 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)); | Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content)); | ||||
| if (args.AllowedMentions.IsSpecified) | if (args.AllowedMentions.IsSpecified) | ||||
| @@ -86,6 +86,7 @@ namespace Discord.Rest | |||||
| AllowedMentions allowedMentions = args.AllowedMentions.Value; | 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?.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(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 | // check that user flag and user Id list are exclusive, same with role flag and role Id list | ||||
| if (allowedMentions != null && allowedMentions.AllowedTypes.HasValue) | if (allowedMentions != null && allowedMentions.AllowedTypes.HasValue) | ||||
| @@ -107,7 +108,7 @@ namespace Discord.Rest | |||||
| var apiArgs = new API.Rest.ModifyMessageParams | var apiArgs = new API.Rest.ModifyMessageParams | ||||
| { | { | ||||
| Content = args.Content, | 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?>(), | Flags = args.Flags.IsSpecified ? args.Flags.Value : Optional.Create<MessageFlags?>(), | ||||
| AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional.Create<API.AllowedMentions>(), | AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional.Create<API.AllowedMentions>(), | ||||
| }; | }; | ||||
| @@ -1,7 +1,4 @@ | |||||
| using System; | using System; | ||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Model = Discord.API.Message; | using Model = Discord.API.Message; | ||||
| @@ -64,7 +61,7 @@ namespace Discord.Rest | |||||
| { | { | ||||
| try | 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); | this.Update(model); | ||||
| } | } | ||||
| catch (Discord.Net.HttpException x) | catch (Discord.Net.HttpException x) | ||||
| @@ -3223,16 +3223,24 @@ | |||||
| The message that contained the trigger for this interaction. | The message that contained the trigger for this interaction. | ||||
| </summary> | </summary> | ||||
| </member> | </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/> | <inheritdoc/> | ||||
| </member> | </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/> | <inheritdoc/> | ||||
| </member> | </member> | ||||
| <member name="M:Discord.WebSocket.SocketMessageComponent.AcknowledgeAsync(Discord.RequestOptions)"> | |||||
| <member name="M:Discord.WebSocket.SocketMessageComponent.DeferAsync(Discord.RequestOptions)"> | |||||
| <summary> | <summary> | ||||
| Acknowledges this interaction with the <see cref="F:Discord.InteractionResponseType.DeferredUpdateMessage"/>. | Acknowledges this interaction with the <see cref="F:Discord.InteractionResponseType.DeferredUpdateMessage"/>. | ||||
| </summary> | </summary> | ||||
| <param name="options">The request options for this async request.</param> | |||||
| <returns> | <returns> | ||||
| A task that represents the asynchronous operation of acknowledging the interaction. | A task that represents the asynchronous operation of acknowledging the interaction. | ||||
| </returns> | </returns> | ||||
| @@ -3341,14 +3349,19 @@ | |||||
| The data associated with this interaction. | The data associated with this interaction. | ||||
| </summary> | </summary> | ||||
| </member> | </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/> | <inheritdoc/> | ||||
| </member> | </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/> | <inheritdoc/> | ||||
| </member> | </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> | ||||
| <member name="T:Discord.WebSocket.SocketSlashCommandData"> | <member name="T:Discord.WebSocket.SocketSlashCommandData"> | ||||
| <summary> | <summary> | ||||
| @@ -3425,18 +3438,17 @@ | |||||
| <see langword="true"/> if the token is valid for replying to, otherwise <see langword="false"/>. | <see langword="true"/> if the token is valid for replying to, otherwise <see langword="false"/>. | ||||
| </summary> | </summary> | ||||
| </member> | </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> | <summary> | ||||
| Responds to an Interaction. | |||||
| Responds to an Interaction with type <see cref="F:Discord.InteractionResponseType.ChannelMessageWithSource"/>. | |||||
| <para> | <para> | ||||
| If you have <see cref="P:Discord.WebSocket.DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use | 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> | </para> | ||||
| </summary> | </summary> | ||||
| <param name="text">The text of the message to be sent.</param> | <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="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="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="allowedMentions">The allowed mentions for this response.</param> | ||||
| <param name="options">The request options 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.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> | <exception cref="T:System.InvalidOperationException">The parameters provided were invalid or the token was invalid.</exception> | ||||
| </member> | </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> | <summary> | ||||
| Sends a followup message for this interaction. | Sends a followup message for this interaction. | ||||
| </summary> | </summary> | ||||
| <param name="text">The text of the message to be sent</param> | <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="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="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="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="allowedMentions">The allowed mentions for this response.</param> | ||||
| <param name="options">The request options 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. | Gets the original response for this interaction. | ||||
| </summary> | </summary> | ||||
| <param name="options">The request options for this async request.</param> | <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> | ||||
| <member name="M:Discord.WebSocket.SocketInteraction.AcknowledgeAsync(Discord.RequestOptions)"> | |||||
| <member name="M:Discord.WebSocket.SocketInteraction.ModifyOriginalResponseAsync(System.Action{Discord.MessageProperties},Discord.RequestOptions)"> | |||||
| <summary> | <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> | </summary> | ||||
| <returns> | <returns> | ||||
| A task that represents the asynchronous operation of acknowledging the interaction. | 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); | var interaction = SocketInteraction.Create(this, data, channel as ISocketMessageChannel); | ||||
| if (this.AlwaysAcknowledgeInteractions) | if (this.AlwaysAcknowledgeInteractions) | ||||
| await interaction.AcknowledgeAsync().ConfigureAwait(false); | |||||
| await interaction.DeferAsync().ConfigureAwait(false); | |||||
| await TimedInvokeAsync(_interactionCreatedEvent, nameof(InteractionCreated), interaction).ConfigureAwait(false); | await TimedInvokeAsync(_interactionCreatedEvent, nameof(InteractionCreated), interaction).ConfigureAwait(false); | ||||
| } | } | ||||
| @@ -1,11 +1,8 @@ | |||||
| using System; | using System; | ||||
| using System.Collections.Generic; | |||||
| using System.Linq; | using System.Linq; | ||||
| using System.Text; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Model = Discord.API.Interaction; | using Model = Discord.API.Interaction; | ||||
| using DataModel = Discord.API.MessageComponentInteractionData; | using DataModel = Discord.API.MessageComponentInteractionData; | ||||
| using Newtonsoft.Json.Linq; | |||||
| using Discord.Rest; | using Discord.Rest; | ||||
| namespace Discord.WebSocket | namespace Discord.WebSocket | ||||
| @@ -71,18 +68,21 @@ namespace Discord.WebSocket | |||||
| } | } | ||||
| /// <inheritdoc/> | /// <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) | if (!IsValidToken) | ||||
| throw new InvalidOperationException("Interaction token is no longer valid"); | throw new InvalidOperationException("Interaction token is no longer valid"); | ||||
| if (Discord.AlwaysAcknowledgeInteractions) | if (Discord.AlwaysAcknowledgeInteractions) | ||||
| { | { | ||||
| await FollowupAsync(embeds, text, isTTS, ephemeral, type, allowedMentions, options); | |||||
| await FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, options); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -109,13 +109,13 @@ namespace Discord.WebSocket | |||||
| var response = new API.InteractionResponse | var response = new API.InteractionResponse | ||||
| { | { | ||||
| Type = type, | |||||
| Type = InteractionResponseType.ChannelMessageWithSource, | |||||
| Data = new API.InteractionCallbackData | Data = new API.InteractionCallbackData | ||||
| { | { | ||||
| Content = text ?? Optional<string>.Unspecified, | Content = text ?? Optional<string>.Unspecified, | ||||
| AllowedMentions = allowedMentions?.ToModel(), | AllowedMentions = allowedMentions?.ToModel(), | ||||
| Embeds = embeds?.Select(x => x.ToModel()).ToArray() ?? Optional<API.Embed[]>.Unspecified, | 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 | Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -123,17 +123,78 @@ namespace Discord.WebSocket | |||||
| if (ephemeral) | if (ephemeral) | ||||
| response.Data.Value.Flags = 64; | 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) | if (!IsValidToken) | ||||
| throw new InvalidOperationException("Interaction token is no longer valid"); | 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(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."); | 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, | 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 | Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified | ||||
| }; | }; | ||||
| @@ -160,10 +220,11 @@ namespace Discord.WebSocket | |||||
| /// <summary> | /// <summary> | ||||
| /// Acknowledges this interaction with the <see cref="InteractionResponseType.DeferredUpdateMessage"/>. | /// Acknowledges this interaction with the <see cref="InteractionResponseType.DeferredUpdateMessage"/>. | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="options">The request options for this async request.</param> | |||||
| /// <returns> | /// <returns> | ||||
| /// A task that represents the asynchronous operation of acknowledging the interaction. | /// A task that represents the asynchronous operation of acknowledging the interaction. | ||||
| /// </returns> | /// </returns> | ||||
| public override Task AcknowledgeAsync(RequestOptions options = null) | |||||
| public override Task DeferAsync(RequestOptions options = null) | |||||
| { | { | ||||
| var response = new API.InteractionResponse() | var response = new API.InteractionResponse() | ||||
| { | { | ||||
| @@ -1,5 +1,4 @@ | |||||
| using Discord.Rest; | using Discord.Rest; | ||||
| using Newtonsoft.Json.Linq; | |||||
| using System; | using System; | ||||
| using System.Linq; | using System.Linq; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| @@ -16,7 +15,7 @@ namespace Discord.WebSocket | |||||
| /// <summary> | /// <summary> | ||||
| /// The data associated with this interaction. | /// The data associated with this interaction. | ||||
| /// </summary> | /// </summary> | ||||
| new public SocketSlashCommandData Data { get; private set; } | |||||
| new public SocketSlashCommandData Data { get; } | |||||
| internal SocketSlashCommand(DiscordSocketClient client, Model model, ISocketMessageChannel channel) | internal SocketSlashCommand(DiscordSocketClient client, Model model, ISocketMessageChannel channel) | ||||
| : base(client, model.Id, channel) | : base(client, model.Id, channel) | ||||
| @@ -51,21 +50,21 @@ namespace Discord.WebSocket | |||||
| } | } | ||||
| /// <inheritdoc/> | /// <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) | if (!IsValidToken) | ||||
| throw new InvalidOperationException("Interaction token is no longer valid"); | throw new InvalidOperationException("Interaction token is no longer valid"); | ||||
| if (Discord.AlwaysAcknowledgeInteractions) | if (Discord.AlwaysAcknowledgeInteractions) | ||||
| { | { | ||||
| await FollowupAsync(embeds, text, isTTS, ephemeral, type, allowedMentions, options, component); | |||||
| await FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, options, component); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -92,11 +91,11 @@ namespace Discord.WebSocket | |||||
| var response = new API.InteractionResponse | var response = new API.InteractionResponse | ||||
| { | { | ||||
| Type = type, | |||||
| Type = InteractionResponseType.ChannelMessageWithSource, | |||||
| Data = new API.InteractionCallbackData | 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, | Embeds = embeds?.Select(x => x.ToModel()).ToArray() ?? Optional<API.Embed[]>.Unspecified, | ||||
| TTS = isTTS ? true : Optional<bool>.Unspecified, | TTS = isTTS ? true : Optional<bool>.Unspecified, | ||||
| Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified | Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified | ||||
| @@ -106,17 +105,19 @@ namespace Discord.WebSocket | |||||
| if (ephemeral) | if (ephemeral) | ||||
| response.Data.Value.Flags = 64; | 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/> | /// <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) | if (!IsValidToken) | ||||
| throw new InvalidOperationException("Interaction token is no longer valid"); | 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(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."); | 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, | 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 | 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); | 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, | Type = InteractionResponseType.DeferredChannelMessageWithSource, | ||||
| }; | }; | ||||
| @@ -1,8 +1,5 @@ | |||||
| using Discord.Rest; | using Discord.Rest; | ||||
| using System; | using System; | ||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Model = Discord.API.Interaction; | using Model = Discord.API.Interaction; | ||||
| @@ -96,71 +93,30 @@ namespace Discord.WebSocket | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| /// Responds to an Interaction. | |||||
| /// Responds to an Interaction with type <see cref="InteractionResponseType.ChannelMessageWithSource"/>. | |||||
| /// <para> | /// <para> | ||||
| /// If you have <see cref="DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use | /// 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> | /// </para> | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="text">The text of the message to be sent.</param> | /// <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="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="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="allowedMentions">The allowed mentions for this response.</param> | ||||
| /// <param name="options">The request options 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> | /// <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="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> | /// <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); | bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null); | ||||
| /// <summary> | /// <summary> | ||||
| /// Sends a followup message for this interaction. | /// Sends a followup message for this interaction. | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="text">The text of the message to be sent</param> | /// <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="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="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="allowedMentions">The allowed mentions for this response.</param> | ||||
| /// <param name="options">The request options for this response.</param> | /// <param name="options">The request options for this response.</param> | ||||
| @@ -168,25 +124,45 @@ namespace Discord.WebSocket | |||||
| /// <returns> | /// <returns> | ||||
| /// The sent message. | /// The sent message. | ||||
| /// </returns> | /// </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); | AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null); | ||||
| /// <summary> | /// <summary> | ||||
| /// Gets the original response for this interaction. | /// Gets the original response for this interaction. | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="options">The request options for this async request.</param> | /// <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) | public Task<RestInteractionMessage> GetOriginalResponseAsync(RequestOptions options = null) | ||||
| => InteractionHelper.GetOriginalResponseAsync(this.Discord, this.Channel, this, options); | => InteractionHelper.GetOriginalResponseAsync(this.Discord, this.Channel, this, options); | ||||
| /// <summary> | /// <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> | /// </summary> | ||||
| /// <returns> | /// <returns> | ||||
| /// A task that represents the asynchronous operation of acknowledging the interaction. | /// A task that represents the asynchronous operation of acknowledging the interaction. | ||||
| /// </returns> | /// </returns> | ||||
| public abstract Task AcknowledgeAsync(RequestOptions options = null); | |||||
| public abstract Task DeferAsync(RequestOptions options = null); | |||||
| private bool CheckToken() | private bool CheckToken() | ||||
| { | { | ||||
| @@ -20,10 +20,15 @@ namespace Discord.Webhook | |||||
| throw new InvalidOperationException("Could not find a webhook with the supplied credentials."); | throw new InvalidOperationException("Could not find a webhook with the supplied credentials."); | ||||
| return RestInternalWebhook.Create(client, model); | 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) | 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) | if (embeds != null) | ||||
| args.Embeds = embeds.Select(x => x.ToModel()).ToArray(); | args.Embeds = embeds.Select(x => x.ToModel()).ToArray(); | ||||
| if (username != null) | if (username != null) | ||||