* 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) | |||