diff --git a/src/Discord.Net.Core/Entities/Interactions/Modals/IModalInteraction.cs b/src/Discord.Net.Core/Entities/Interactions/Modals/IModalInteraction.cs index 0d967768..454b48cb 100644 --- a/src/Discord.Net.Core/Entities/Interactions/Modals/IModalInteraction.cs +++ b/src/Discord.Net.Core/Entities/Interactions/Modals/IModalInteraction.cs @@ -31,5 +31,13 @@ namespace Discord /// This method can be used only if the modal was created from a message component. /// Task UpdateAsync(Action func, RequestOptions options = null); + + /// + /// Defers an interaction with the response type 5 (). + /// + /// to defer ephemerally, otherwise . + /// The options to be used when sending the request. + /// A task that represents the asynchronous operation of acknowledging the interaction. + Task DeferLoadingAsync(bool ephemeral = false, RequestOptions options = null); } } diff --git a/src/Discord.Net.Rest/Entities/Interactions/Modals/RestModal.cs b/src/Discord.Net.Rest/Entities/Interactions/Modals/RestModal.cs index 3d2f4ba4..37abc22d 100644 --- a/src/Discord.Net.Rest/Entities/Interactions/Modals/RestModal.cs +++ b/src/Discord.Net.Rest/Entities/Interactions/Modals/RestModal.cs @@ -43,7 +43,8 @@ namespace Discord.Rest private object _lock = new object(); /// - /// Acknowledges this interaction with the . + /// Acknowledges this interaction with the if the modal was created + /// in a response to a message component interaction, otherwise. /// /// /// A string that contains json to write back to the incoming http request. @@ -55,7 +56,9 @@ namespace Discord.Rest var response = new API.InteractionResponse { - Type = InteractionResponseType.DeferredChannelMessageWithSource, + Type = Message is not null + ? InteractionResponseType.DeferredUpdateMessage + : InteractionResponseType.DeferredChannelMessageWithSource, Data = new API.InteractionCallbackData { Flags = ephemeral ? MessageFlags.Ephemeral : Optional.Unspecified @@ -78,6 +81,39 @@ namespace Discord.Rest return SerializePayload(response); } + /// + /// Defers an interaction and responds with type 5 () + /// + /// to send this message ephemerally, otherwise . + /// The request options for this request. + /// + /// A string that contains json to write back to the incoming http request. + /// + public string DeferLoading(bool ephemeral = false, RequestOptions options = null) + { + if (!InteractionHelper.CanSendResponse(this)) + throw new TimeoutException($"Cannot defer an interaction after {InteractionHelper.ResponseTimeLimit} seconds of no response/acknowledgement"); + + var response = new API.InteractionResponse + { + Type = InteractionResponseType.DeferredChannelMessageWithSource, + Data = ephemeral ? new API.InteractionCallbackData { Flags = MessageFlags.Ephemeral } : Optional.Unspecified + }; + + lock (_lock) + { + if (HasResponded) + { + throw new InvalidOperationException("Cannot respond or defer twice to the same interaction"); + } + + HasResponded = true; + } + + return SerializePayload(response); + } + + /// /// Sends a followup message for this interaction. /// @@ -413,6 +449,10 @@ namespace Discord.Rest IModalInteractionData IModalInteraction.Data => Data; + /// + Task IModalInteraction.DeferLoadingAsync(bool ephemeral, RequestOptions options) + => Task.FromResult(DeferLoading(ephemeral, options)); + /// public async Task UpdateAsync(Action func, RequestOptions options = null) { diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/Modals/SocketModal.cs b/src/Discord.Net.WebSocket/Entities/Interaction/Modals/SocketModal.cs index c9fed6a4..20daf7a0 100644 --- a/src/Discord.Net.WebSocket/Entities/Interaction/Modals/SocketModal.cs +++ b/src/Discord.Net.WebSocket/Entities/Interaction/Modals/SocketModal.cs @@ -376,6 +376,10 @@ namespace Discord.WebSocket } /// + /// + /// Acknowledges this interaction with the if the modal was created + /// in a response to a message component interaction, otherwise. + /// public override async Task DeferAsync(bool ephemeral = false, RequestOptions options = null) { if (!InteractionHelper.CanSendResponse(this)) @@ -383,7 +387,9 @@ namespace Discord.WebSocket var response = new API.InteractionResponse { - Type = InteractionResponseType.DeferredUpdateMessage, + Type = Message is not null + ? InteractionResponseType.DeferredUpdateMessage + : InteractionResponseType.DeferredChannelMessageWithSource, Data = ephemeral ? new API.InteractionCallbackData { Flags = MessageFlags.Ephemeral } : Optional.Unspecified }; @@ -403,6 +409,30 @@ namespace Discord.WebSocket } } + /// + public async Task DeferLoadingAsync(bool ephemeral = false, RequestOptions options = null) + { + if (!InteractionHelper.CanSendResponse(this)) + throw new TimeoutException($"Cannot defer an interaction after {InteractionHelper.ResponseTimeLimit} seconds of no response/acknowledgement"); + + var response = new API.InteractionResponse + { + Type = InteractionResponseType.DeferredChannelMessageWithSource, + Data = ephemeral ? new API.InteractionCallbackData { Flags = MessageFlags.Ephemeral } : Optional.Unspecified + }; + + lock (_lock) + { + if (HasResponded) + { + throw new InvalidOperationException("Cannot respond or defer twice to the same interaction"); + } + } + + await Discord.Rest.ApiClient.CreateInteractionResponseAsync(response, Id, Token, options).ConfigureAwait(false); + HasResponded = true; + } + /// public override Task RespondWithModalAsync(Modal modal, RequestOptions options = null) => throw new NotSupportedException("You cannot respond to a modal with a modal!");