diff --git a/src/Discord.Net.Interactions/Builders/Modals/Inputs/IInputComponentBuilder.cs b/src/Discord.Net.Interactions/Builders/Modals/Inputs/IInputComponentBuilder.cs
index ad2f07c73..68c26fd03 100644
--- a/src/Discord.Net.Interactions/Builders/Modals/Inputs/IInputComponentBuilder.cs
+++ b/src/Discord.Net.Interactions/Builders/Modals/Inputs/IInputComponentBuilder.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
namespace Discord.Interactions.Builders
{
@@ -38,6 +39,11 @@ namespace Discord.Interactions.Builders
///
Type Type { get; }
+ ///
+ /// Get the of this component's property.
+ ///
+ PropertyInfo PropertyInfo { get; }
+
///
/// Get the assigned to this input.
///
diff --git a/src/Discord.Net.Interactions/Builders/Modals/Inputs/InputComponentBuilder.cs b/src/Discord.Net.Interactions/Builders/Modals/Inputs/InputComponentBuilder.cs
index 7d1d96712..af0ab3a70 100644
--- a/src/Discord.Net.Interactions/Builders/Modals/Inputs/InputComponentBuilder.cs
+++ b/src/Discord.Net.Interactions/Builders/Modals/Inputs/InputComponentBuilder.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
namespace Discord.Interactions.Builders
{
@@ -33,6 +34,9 @@ namespace Discord.Interactions.Builders
///
public Type Type { get; private set; }
+ ///
+ public PropertyInfo PropertyInfo { get; internal set; }
+
///
public ComponentTypeConverter TypeConverter { get; private set; }
diff --git a/src/Discord.Net.Interactions/Builders/Modals/ModalBuilder.cs b/src/Discord.Net.Interactions/Builders/Modals/ModalBuilder.cs
index c13ff40de..66aeadf75 100644
--- a/src/Discord.Net.Interactions/Builders/Modals/ModalBuilder.cs
+++ b/src/Discord.Net.Interactions/Builders/Modals/ModalBuilder.cs
@@ -37,6 +37,8 @@ namespace Discord.Interactions.Builders
if (!typeof(IModal).IsAssignableFrom(type))
throw new ArgumentException($"Must be an implementation of {nameof(IModal)}", nameof(type));
+ Type = type;
+
_interactionService = interactionService;
_components = new();
}
diff --git a/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs b/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs
index 3f0504e44..ea1875b60 100644
--- a/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs
+++ b/src/Discord.Net.Interactions/Builders/ModuleClassBuilder.cs
@@ -596,6 +596,7 @@ namespace Discord.Interactions.Builders
builder.Label = propertyInfo.Name;
builder.DefaultValue = defaultValue;
builder.WithType(propertyInfo.PropertyType);
+ builder.PropertyInfo = propertyInfo;
foreach(var attribute in attributes)
{
diff --git a/src/Discord.Net.Interactions/Extensions/IDiscordInteractionExtensions.cs b/src/Discord.Net.Interactions/Extensions/IDiscordInteractionExtensions.cs
index d970b9930..5f66df929 100644
--- a/src/Discord.Net.Interactions/Extensions/IDiscordInteractionExtensions.cs
+++ b/src/Discord.Net.Interactions/Extensions/IDiscordInteractionExtensions.cs
@@ -44,6 +44,44 @@ namespace Discord.Interactions
await SendModalResponseAsync(interaction, customId, modalInfo, options, modifyModal);
}
+ ///
+ /// Respond to an interaction with an and fills the value fields of the modal using the property values of the provided
+ /// instance.
+ ///
+ /// Type of the implementation.
+ /// The interaction to respond to.
+ /// The instance to get field values from.
+ /// The request options for this request.
+ /// Delegate that can be used to modify the modal.
+ ///
+ public static async Task RespondWithModalAsync(this IDiscordInteraction interaction, string customId, T modal, RequestOptions options = null,
+ Action modifyModal = null)
+ where T : class, IModal
+ {
+ if (!ModalUtils.TryGet(out var modalInfo))
+ throw new ArgumentException($"{typeof(T).FullName} isn't referenced by any registered Modal Interaction Command and doesn't have a cached {typeof(ModalInfo)}");
+
+ var builder = new ModalBuilder(modal.Title, customId);
+
+ foreach (var input in modalInfo.Components)
+ switch (input)
+ {
+ case TextInputComponentInfo textComponent:
+ {
+ builder.AddTextInput(textComponent.Label, textComponent.CustomId, textComponent.Style, textComponent.Placeholder, textComponent.IsRequired ? textComponent.MinLength : null,
+ textComponent.MaxLength, textComponent.IsRequired, textComponent.Getter(modal) as string);
+ }
+ break;
+ default:
+ throw new InvalidOperationException($"{input.GetType().FullName} isn't a valid component info class");
+ }
+
+ if (modifyModal is not null)
+ modifyModal(builder);
+
+ await interaction.RespondWithModalAsync(builder.Build(), options).ConfigureAwait(false);
+ }
+
private static async Task SendModalResponseAsync(IDiscordInteraction interaction, string customId, ModalInfo modalInfo, RequestOptions options = null, Action modifyModal = null)
{
var builder = new ModalBuilder(modalInfo.Title, customId);
diff --git a/src/Discord.Net.Interactions/Info/InputComponents/InputComponentInfo.cs b/src/Discord.Net.Interactions/Info/InputComponents/InputComponentInfo.cs
index 05695f862..23a0db844 100644
--- a/src/Discord.Net.Interactions/Info/InputComponents/InputComponentInfo.cs
+++ b/src/Discord.Net.Interactions/Info/InputComponents/InputComponentInfo.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
+using System.Reflection;
namespace Discord.Interactions
{
@@ -9,6 +10,10 @@ namespace Discord.Interactions
///
public abstract class InputComponentInfo
{
+ private Lazy> _getter;
+ internal Func