diff --git a/src/Discord.Net.Core/Entities/Interactions/ContextMenus/IMessageCommandInteraction.cs b/src/Discord.Net.Core/Entities/Interactions/ContextMenus/IMessageCommandInteraction.cs
index b1b331e8b..07d66bfcb 100644
--- a/src/Discord.Net.Core/Entities/Interactions/ContextMenus/IMessageCommandInteraction.cs
+++ b/src/Discord.Net.Core/Entities/Interactions/ContextMenus/IMessageCommandInteraction.cs
@@ -3,7 +3,7 @@ namespace Discord
///
/// Represents a Message Command interaction.
///
- public interface IMessageCommandInteraction : IDiscordInteraction
+ public interface IMessageCommandInteraction : IApplicationCommandInteraction
{
///
/// Gets the data associated with this interaction.
diff --git a/src/Discord.Net.Core/Entities/Interactions/ContextMenus/IUserCommandInteraction.cs b/src/Discord.Net.Core/Entities/Interactions/ContextMenus/IUserCommandInteraction.cs
index f7cfd67f0..2ffdfd9f6 100644
--- a/src/Discord.Net.Core/Entities/Interactions/ContextMenus/IUserCommandInteraction.cs
+++ b/src/Discord.Net.Core/Entities/Interactions/ContextMenus/IUserCommandInteraction.cs
@@ -3,7 +3,7 @@ namespace Discord
///
/// Represents a User Command interaction.
///
- public interface IUserCommandInteraction : IDiscordInteraction
+ public interface IUserCommandInteraction : IApplicationCommandInteraction
{
///
/// Gets the data associated with this interaction.
diff --git a/src/Discord.Net.Core/Entities/Interactions/IApplicationCommandInteraction.cs b/src/Discord.Net.Core/Entities/Interactions/IApplicationCommandInteraction.cs
new file mode 100644
index 000000000..b079a47be
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Interactions/IApplicationCommandInteraction.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ ///
+ /// Represents an application command interaction.
+ ///
+ public interface IApplicationCommandInteraction : IDiscordInteraction
+ {
+ ///
+ /// Gets the data of the application command interaction
+ ///
+ new IApplicationCommandInteractionData Data { get; }
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Interactions/IDiscordInteraction.cs b/src/Discord.Net.Core/Entities/Interactions/IDiscordInteraction.cs
index 38a543964..77971b9f3 100644
--- a/src/Discord.Net.Core/Entities/Interactions/IDiscordInteraction.cs
+++ b/src/Discord.Net.Core/Entities/Interactions/IDiscordInteraction.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
@@ -34,6 +35,11 @@ namespace Discord
///
int Version { get; }
+ ///
+ /// Gets the user who invoked the interaction.
+ ///
+ IUser User { get; }
+
///
/// Responds to an Interaction with type .
///
@@ -43,10 +49,14 @@ namespace Discord
/// if the response should be hidden to everyone besides the invoker of the command, otherwise .
/// The allowed mentions for this response.
/// The request options for this response.
- /// A to be sent with this response.
+ /// A to be sent with this response.
/// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
- Task RespondAsync(string text = null, Embed[] embeds = null, bool isTTS = false,
- bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null);
+ ///
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
+ ///
+ Task RespondAsync(string text = null, Embed[] embeds = null, bool isTTS = false,
+ bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
///
/// Sends a followup message for this interaction.
@@ -57,13 +67,14 @@ namespace Discord
/// if the response should be hidden to everyone besides the invoker of the command, otherwise .
/// The allowed mentions for this response.
/// The request options for this response.
- /// A to be sent with this response.
+ /// A to be sent with this response.
/// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
///
- /// The sent message.
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
///
Task FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null);
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
///
/// Sends a followup message for this interaction.
@@ -76,13 +87,14 @@ namespace Discord
/// if the response should be hidden to everyone besides the invoker of the command, otherwise .
/// The allowed mentions for this response.
/// The request options for this response.
- /// A to be sent with this response.
+ /// A to be sent with this response.
/// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
///
- /// The sent message.
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
///
public Task FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null);
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
///
/// Sends a followup message for this interaction.
@@ -95,13 +107,50 @@ namespace Discord
/// if the response should be hidden to everyone besides the invoker of the command, otherwise .
/// The allowed mentions for this response.
/// The request options for this response.
- /// A to be sent with this response.
+ /// A to be sent with this response.
+ /// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ ///
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
+ ///
+ public Task FollowupWithFileAsync(string filePath, string fileName = null, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
+ ///
+ /// Sends a followup message for this interaction.
+ ///
+ /// The attachment containing the file and description.
+ /// The text of the message to be sent.
+ /// A array of embeds to send with this response. Max 10.
+ /// if the message should be read out by a text-to-speech reader, otherwise .
+ /// if the response should be hidden to everyone besides the invoker of the command, otherwise .
+ /// The allowed mentions for this response.
+ /// The request options for this response.
+ /// A to be sent with this response.
+ /// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ ///
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
+ ///
+ Task FollowupWithFileAsync(FileAttachment attachment, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
+ ///
+ /// Sends a followup message for this interaction.
+ ///
+ /// A collection of attachments to upload.
+ /// The text of the message to be sent.
+ /// A array of embeds to send with this response. Max 10.
+ /// if the message should be read out by a text-to-speech reader, otherwise .
+ /// if the response should be hidden to everyone besides the invoker of the command, otherwise .
+ /// The allowed mentions for this response.
+ /// The request options for this response.
+ /// A to be sent with this response.
/// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
///
- /// The sent message.
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
///
- public Task FollowupWithFileAsync(string filePath, string text = null, string fileName = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null);
+ Task FollowupWithFilesAsync(IEnumerable attachments, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
///
/// Gets the original response for this interaction.
@@ -115,14 +164,17 @@ namespace Discord
///
/// A delegate containing the properties to modify the message with.
/// The request options for this request.
- /// A that represents the initial response.
+ ///
+ /// A task that represents an asynchronous modification operation. The task result
+ /// contains the updated message.
+ ///
Task ModifyOriginalResponseAsync(Action func, RequestOptions options = null);
///
/// Acknowledges this interaction.
///
///
- /// A task that represents the asynchronous operation of acknowledging the interaction.
+ /// A task that represents the asynchronous operation of deferring the interaction.
///
Task DeferAsync(bool ephemeral = false, RequestOptions options = null);
}
diff --git a/src/Discord.Net.Core/Entities/Interactions/SlashCommands/ISlashCommandInteraction.cs b/src/Discord.Net.Core/Entities/Interactions/SlashCommands/ISlashCommandInteraction.cs
index 556182987..f28c35e40 100644
--- a/src/Discord.Net.Core/Entities/Interactions/SlashCommands/ISlashCommandInteraction.cs
+++ b/src/Discord.Net.Core/Entities/Interactions/SlashCommands/ISlashCommandInteraction.cs
@@ -3,7 +3,7 @@ namespace Discord
///
/// Represents a slash command interaction.
///
- public interface ISlashCommandInteraction : IDiscordInteraction
+ public interface ISlashCommandInteraction : IApplicationCommandInteraction
{
///
/// Gets the data associated with this interaction.
diff --git a/src/Discord.Net.Core/Net/ApplicationCommandException.cs b/src/Discord.Net.Core/Net/ApplicationCommandException.cs
deleted file mode 100644
index 4b4890d12..000000000
--- a/src/Discord.Net.Core/Net/ApplicationCommandException.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Linq;
-
-namespace Discord.Net
-{
- [Obsolete("Please use HttpException instead of this. Will be removed in next major version.", false)]
- public class ApplicationCommandException : HttpException
- {
- public ApplicationCommandException(HttpException httpError)
- : base(httpError.HttpCode, httpError.Request, httpError.DiscordCode, httpError.Reason, httpError.Errors.ToArray())
- {
-
- }
- }
-}
diff --git a/src/Discord.Net.Interactions/InteractionModuleBase.cs b/src/Discord.Net.Interactions/InteractionModuleBase.cs
index c00f6b694..f0e50da8d 100644
--- a/src/Discord.Net.Interactions/InteractionModuleBase.cs
+++ b/src/Discord.Net.Interactions/InteractionModuleBase.cs
@@ -36,12 +36,12 @@ namespace Discord.Interactions
///
protected virtual async Task RespondAsync (string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null) =>
- await Context.Interaction.RespondAsync(text, embeds, isTTS, ephemeral, allowedMentions, options, component, embed).ConfigureAwait(false);
+ await Context.Interaction.RespondAsync(text, embeds, isTTS, ephemeral, allowedMentions, component, embed, options).ConfigureAwait(false);
///
protected virtual async Task FollowupAsync (string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null) =>
- await Context.Interaction.FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, options, component, embed).ConfigureAwait(false);
+ await Context.Interaction.FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, component, embed, options).ConfigureAwait(false);
///
protected virtual async Task ReplyAsync (string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null,
diff --git a/src/Discord.Net.Interactions/RestInteractionModuleBase.cs b/src/Discord.Net.Interactions/RestInteractionModuleBase.cs
index b086e14fb..ee1ce229e 100644
--- a/src/Discord.Net.Interactions/RestInteractionModuleBase.cs
+++ b/src/Discord.Net.Interactions/RestInteractionModuleBase.cs
@@ -53,7 +53,7 @@ namespace Discord.Interactions
if (Context.Interaction is not RestInteraction restInteraction)
throw new InvalidOperationException($"Invalid interaction type. Interaction must be a type of {nameof(RestInteraction)} in order to execute this method");
- await InteractionService._restResponseCallback(Context, restInteraction.Respond(text, embeds, isTTS, ephemeral, allowedMentions, options, component, embed)).ConfigureAwait(false);
+ await InteractionService._restResponseCallback(Context, restInteraction.Respond(text, embeds, isTTS, ephemeral, allowedMentions, component, embed, options)).ConfigureAwait(false);
}
}
}
diff --git a/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs b/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs
index 3d09ad145..1a25e4782 100644
--- a/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs
@@ -21,6 +21,7 @@ namespace Discord.API.Rest
public Optional Embeds { get; set; }
public Optional AllowedMentions { get; set; }
public Optional MessageComponents { get; set; }
+ public Optional Flags { get; set; }
public UploadWebhookFileParams(params FileAttachment[] files)
{
@@ -48,6 +49,8 @@ namespace Discord.API.Rest
payload["embeds"] = Embeds.Value;
if (AllowedMentions.IsSpecified)
payload["allowed_mentions"] = AllowedMentions.Value;
+ if (Flags.IsSpecified)
+ payload["flags"] = Flags.Value;
List attachments = new();
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index abe059c64..4fec637bb 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -1198,25 +1198,25 @@ namespace Discord.API
options = RequestOptions.CreateOrClone(options);
- return await TrySendApplicationCommandAsync(SendJsonAsync("POST", () => $"applications/{CurrentUserId}/commands", command, new BucketIds(), options: options)).ConfigureAwait(false);
+ return await SendJsonAsync("POST", () => $"applications/{CurrentUserId}/commands", command, new BucketIds(), options: options).ConfigureAwait(false);
}
public async Task ModifyGlobalApplicationCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
- return await TrySendApplicationCommandAsync(SendJsonAsync("PATCH", () => $"applications/{CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
+ return await SendJsonAsync("PATCH", () => $"applications/{CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options).ConfigureAwait(false);
}
public async Task ModifyGlobalApplicationUserCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
- return await TrySendApplicationCommandAsync(SendJsonAsync("PATCH", () => $"applications/{CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
+ return await SendJsonAsync("PATCH", () => $"applications/{CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options).ConfigureAwait(false);
}
public async Task ModifyGlobalApplicationMessageCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
- return await TrySendApplicationCommandAsync(SendJsonAsync("PATCH", () => $"applications/{CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
+ return await SendJsonAsync("PATCH", () => $"applications/{CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options).ConfigureAwait(false);
}
public async Task DeleteGlobalApplicationCommandAsync(ulong commandId, RequestOptions options = null)
{
@@ -1229,7 +1229,7 @@ namespace Discord.API
{
options = RequestOptions.CreateOrClone(options);
- return await TrySendApplicationCommandAsync(SendJsonAsync("PUT", () => $"applications/{CurrentUserId}/commands", commands, new BucketIds(), options: options)).ConfigureAwait(false);
+ return await SendJsonAsync("PUT", () => $"applications/{CurrentUserId}/commands", commands, new BucketIds(), options: options).ConfigureAwait(false);
}
public async Task GetGuildApplicationCommandsAsync(ulong guildId, RequestOptions options = null)
@@ -1271,7 +1271,7 @@ namespace Discord.API
var bucket = new BucketIds(guildId: guildId);
- return await TrySendApplicationCommandAsync(SendJsonAsync("POST", () => $"applications/{CurrentUserId}/guilds/{guildId}/commands", command, bucket, options: options)).ConfigureAwait(false);
+ return await SendJsonAsync("POST", () => $"applications/{CurrentUserId}/guilds/{guildId}/commands", command, bucket, options: options).ConfigureAwait(false);
}
public async Task ModifyGuildApplicationCommandAsync(ModifyApplicationCommandParams command, ulong guildId, ulong commandId, RequestOptions options = null)
{
@@ -1279,7 +1279,7 @@ namespace Discord.API
var bucket = new BucketIds(guildId: guildId);
- return await TrySendApplicationCommandAsync(SendJsonAsync("PATCH", () => $"applications/{CurrentUserId}/guilds/{guildId}/commands/{commandId}", command, bucket, options: options)).ConfigureAwait(false);
+ return await SendJsonAsync("PATCH", () => $"applications/{CurrentUserId}/guilds/{guildId}/commands/{commandId}", command, bucket, options: options).ConfigureAwait(false);
}
public async Task DeleteGuildApplicationCommandAsync(ulong guildId, ulong commandId, RequestOptions options = null)
{
@@ -1296,7 +1296,7 @@ namespace Discord.API
var bucket = new BucketIds(guildId: guildId);
- return await TrySendApplicationCommandAsync(SendJsonAsync("PUT", () => $"applications/{CurrentUserId}/guilds/{guildId}/commands", commands, bucket, options: options)).ConfigureAwait(false);
+ return await SendJsonAsync("PUT", () => $"applications/{CurrentUserId}/guilds/{guildId}/commands", commands, bucket, options: options).ConfigureAwait(false);
}
#endregion
@@ -1316,7 +1316,7 @@ namespace Discord.API
options = RequestOptions.CreateOrClone(options);
- return await SendAsync("GET", () => $"webhooks/{CurrentUserId}/{interactionToken}/messages/@original", new BucketIds(), options: options).ConfigureAwait(false);
+ return await NullifyNotFound(SendAsync("GET", () => $"webhooks/{CurrentUserId}/{interactionToken}/messages/@original", new BucketIds(), options: options)).ConfigureAwait(false);
}
public async Task ModifyInteractionResponseAsync(ModifyInteractionResponseParams args, string interactionToken, RequestOptions options = null)
{
@@ -1347,6 +1347,21 @@ namespace Discord.API
return await SendMultipartAsync("POST", () => $"webhooks/{CurrentUserId}/{token}?wait=true", args.ToDictionary(), new BucketIds(), options: options).ConfigureAwait(false);
}
+ public async Task CreateInteractionFollowupMessageAsync(UploadWebhookFileParams args, string token, RequestOptions options = null)
+ {
+ if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0) && !args.Files.Any())
+ Preconditions.NotNullOrEmpty(args.Content, nameof(args.Content));
+
+
+ if (args.Content.IsSpecified && args.Content.Value.Length > DiscordConfig.MaxMessageSize)
+ throw new ArgumentException(message: $"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", paramName: nameof(args.Content));
+
+ options = RequestOptions.CreateOrClone(options);
+
+ var ids = new BucketIds();
+ return await SendMultipartAsync("POST", () => $"webhooks/{CurrentUserId}/{token}?wait=true", args.ToDictionary(), ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false);
+ }
+
public async Task ModifyInteractionFollowupMessageAsync(ModifyInteractionResponseParams args, ulong id, string token, RequestOptions options = null)
{
Preconditions.NotNull(args, nameof(args));
@@ -2222,40 +2237,6 @@ namespace Discord.API
return _serializer.Deserialize(reader);
}
- protected async Task TrySendApplicationCommandAsync(Task sendTask)
- {
- try
- {
- var result = await sendTask.ConfigureAwait(false);
-
- if (sendTask.Exception != null)
- {
- if (sendTask.Exception.InnerException is HttpException x)
- {
- if (x.HttpCode == HttpStatusCode.BadRequest)
- {
- var json = (x.Request as JsonRestRequest).Json;
- throw new ApplicationCommandException(x);
- }
- }
-
- throw sendTask.Exception;
- }
- else
- return result;
- }
- catch (HttpException x)
- {
- if (x.HttpCode == HttpStatusCode.BadRequest)
- {
- var json = (x.Request as JsonRestRequest).Json;
- throw new ApplicationCommandException(x);
- }
-
- throw;
- }
- }
-
protected async Task NullifyNotFound(Task sendTask) where T : class
{
try
diff --git a/src/Discord.Net.Rest/Entities/Interactions/CommandBase/RestCommandBase.cs b/src/Discord.Net.Rest/Entities/Interactions/CommandBase/RestCommandBase.cs
index a9efb6de1..1673fd922 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/CommandBase/RestCommandBase.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/CommandBase/RestCommandBase.cs
@@ -76,9 +76,9 @@ namespace Discord.Rest
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
MessageComponent component = null,
- Embed embed = null)
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -132,37 +132,29 @@ namespace Discord.Rest
}
}
- lock (_lock)
+ try
{
- _hasResponded = true;
+ return SerializePayload(response);
+ }
+ finally
+ {
+ lock (_lock)
+ {
+ _hasResponded = true;
+ }
}
-
- return SerializePayload(response);
}
- ///
- /// Sends a followup message for this interaction.
- ///
- /// The text of the message to be sent.
- /// A array of embeds to send with this response. Max 10.
- /// if the message should be read out by a text-to-speech reader, otherwise .
- /// if the response should be hidden to everyone besides the invoker of the command, otherwise .
- /// The allowed mentions for this response.
- /// The request options for this response.
- /// A to be sent with this response.
- /// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
- ///
- /// The sent message.
- ///
+ ///
public override async Task FollowupAsync(
string text = null,
Embed[] embeds = null,
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
MessageComponent component = null,
- Embed embed = null)
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -190,23 +182,8 @@ namespace Discord.Rest
return await InteractionHelper.SendFollowupAsync(Discord, args, Token, Channel, options);
}
- ///
- /// Sends a followup message for this interaction.
- ///
- /// The text of the message to be sent.
- /// The file to upload.
- /// The file name of the attachment.
- /// A array of embeds to send with this response. Max 10.
- /// if the message should be read out by a text-to-speech reader, otherwise .
- /// if the response should be hidden to everyone besides the invoker of the command, otherwise .
- /// The allowed mentions for this response.
- /// The request options for this response.
- /// A to be sent with this response.
- /// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
- ///
- /// The sent message.
- ///
- public override async Task FollowupWithFileAsync(
+ ///
+ public override Task FollowupWithFileAsync(
Stream fileStream,
string fileName,
string text = null,
@@ -214,9 +191,9 @@ namespace Discord.Rest
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
- MessageComponent component = null,
- Embed embed = null)
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -225,55 +202,59 @@ namespace Discord.Rest
if (embed != null)
embeds = new[] { embed }.Concat(embeds).ToArray();
- 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(embeds.Length, 10, nameof(embeds), "A max of 10 embeds are allowed.");
Preconditions.NotNull(fileStream, nameof(fileStream), "File Stream must have data");
Preconditions.NotNullOrEmpty(fileName, nameof(fileName), "File Name must not be empty or null");
- var args = new API.Rest.CreateWebhookMessageParams
- {
- Content = text,
- AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified,
- IsTTS = isTTS,
- Embeds = embeds.Select(x => x.ToModel()).ToArray(),
- Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified,
- File = fileStream is not null ? new MultipartFile(fileStream, fileName) : Optional.Unspecified
- };
+ return FollowupWithFileAsync(new FileAttachment(fileStream, fileName), text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+ }
- if (ephemeral)
- args.Flags = MessageFlags.Ephemeral;
+ ///
+ public override Task FollowupWithFileAsync(
+ string filePath,
+ string fileName = null,
+ string text = null,
+ Embed[] embeds = null,
+ bool isTTS = false,
+ bool ephemeral = false,
+ AllowedMentions allowedMentions = null,
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
+ {
+ Preconditions.NotNullOrEmpty(filePath, nameof(filePath), "Path must exist");
- return await InteractionHelper.SendFollowupAsync(Discord, args, Token, Channel, options);
+ fileName ??= Path.GetFileName(filePath);
+ Preconditions.NotNullOrEmpty(fileName, nameof(fileName), "File Name must not be empty or null");
+
+ return FollowupWithFileAsync(new FileAttachment(File.OpenRead(filePath), fileName), text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
}
- ///
- /// Sends a followup message for this interaction.
- ///
- /// The text of the message to be sent.
- /// The file to upload.
- /// The file name of the attachment.
- /// A array of embeds to send with this response. Max 10.
- /// if the message should be read out by a text-to-speech reader, otherwise .
- /// if the response should be hidden to everyone besides the invoker of the command, otherwise .
- /// The allowed mentions for this response.
- /// The request options for this response.
- /// A to be sent with this response.
- /// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
- ///
- /// The sent message.
- ///
- public override async Task FollowupWithFileAsync(
- string filePath,
+ ///
+ public override Task FollowupWithFileAsync(
+ FileAttachment attachment,
string text = null,
- string fileName = null,
Embed[] embeds = null,
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
- MessageComponent component = null,
- Embed embed = null)
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
+ {
+ return FollowupWithFilesAsync(new FileAttachment[] { attachment }, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+ }
+
+ ///
+ public override async Task FollowupWithFilesAsync(
+ IEnumerable attachments,
+ string text = null,
+ Embed[] embeds = null,
+ bool isTTS = false,
+ bool ephemeral = false,
+ AllowedMentions allowedMentions = null,
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -285,25 +266,35 @@ namespace Discord.Rest
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(embeds.Length, 10, nameof(embeds), "A max of 10 embeds are allowed.");
- Preconditions.NotNullOrEmpty(filePath, nameof(filePath), "Path must exist");
- fileName ??= Path.GetFileName(filePath);
- Preconditions.NotNullOrEmpty(fileName, nameof(fileName), "File Name must not be empty or null");
+ foreach (var attachment in attachments)
+ {
+ Preconditions.NotNullOrEmpty(attachment.FileName, nameof(attachment.FileName), "File Name must not be empty or null");
+ }
- var args = new API.Rest.CreateWebhookMessageParams
+ // check that user flag and user Id list are exclusive, same with role flag and role Id list
+ if (allowedMentions != null && allowedMentions.AllowedTypes.HasValue)
{
- Content = text,
- AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified,
- IsTTS = isTTS,
- Embeds = embeds.Select(x => x.ToModel()).ToArray(),
- Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified,
- File = !string.IsNullOrEmpty(filePath) ? new MultipartFile(new MemoryStream(File.ReadAllBytes(filePath), false), fileName) : Optional.Unspecified
- };
+ 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(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(allowedMentions));
+ }
+ }
+
+ var flags = MessageFlags.None;
if (ephemeral)
- args.Flags = MessageFlags.Ephemeral;
+ flags |= MessageFlags.Ephemeral;
- return await InteractionHelper.SendFollowupAsync(Discord, args, Token, Channel, options);
+ var args = new API.Rest.UploadWebhookFileParams(attachments.ToArray()) { Flags = flags, Content = text, IsTTS = isTTS, Embeds = embeds.Any() ? embeds.Select(x => x.ToModel()).ToArray() : Optional.Unspecified, AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified, MessageComponents = components?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified };
+ return await InteractionHelper.SendFollowupAsync(Discord, args, Token, Channel, options).ConfigureAwait(false);
}
///
diff --git a/src/Discord.Net.Rest/Entities/Interactions/ContextMenuCommands/MessageCommands/RestMessageCommand.cs b/src/Discord.Net.Rest/Entities/Interactions/ContextMenuCommands/MessageCommands/RestMessageCommand.cs
index 53055cac3..7a85d2e0a 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/ContextMenuCommands/MessageCommands/RestMessageCommand.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/ContextMenuCommands/MessageCommands/RestMessageCommand.cs
@@ -41,5 +41,8 @@ namespace Discord.Rest
//IMessageCommandInteraction
///
IMessageCommandInteractionData IMessageCommandInteraction.Data => Data;
+ //IApplicationCommandInteraction
+ ///
+ IApplicationCommandInteractionData IApplicationCommandInteraction.Data => Data;
}
}
diff --git a/src/Discord.Net.Rest/Entities/Interactions/ContextMenuCommands/UserCommands/RestUserCommand.cs b/src/Discord.Net.Rest/Entities/Interactions/ContextMenuCommands/UserCommands/RestUserCommand.cs
index 58f1ed375..7f55fd61b 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/ContextMenuCommands/UserCommands/RestUserCommand.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/ContextMenuCommands/UserCommands/RestUserCommand.cs
@@ -44,5 +44,9 @@ namespace Discord.Rest
//IUserCommandInteractionData
///
IUserCommandInteractionData IUserCommandInteraction.Data => Data;
+
+ //IApplicationCommandInteraction
+ ///
+ IApplicationCommandInteractionData IApplicationCommandInteraction.Data => Data;
}
}
diff --git a/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs b/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
index ed537a062..b20cfe2ed 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
@@ -34,17 +34,20 @@ namespace Discord.Rest
return client.ApiClient.BulkOverwriteGlobalApplicationCommandsAsync(Array.Empty(), options);
}
- public static Task SendInteractionResponseAsync(BaseDiscordClient client, InteractionResponse response,
- ulong interactionId, string interactionToken, RequestOptions options = null)
+ public static async Task SendInteractionResponseAsync(BaseDiscordClient client, InteractionResponse response,
+ IDiscordInteraction interaction, IMessageChannel channel = null, RequestOptions options = null)
{
- return client.ApiClient.CreateInteractionResponseAsync(response, interactionId, interactionToken, options);
+ await client.ApiClient.CreateInteractionResponseAsync(response, interaction.Id, interaction.Token, options).ConfigureAwait(false);
+ return RestInteractionMessage.Create(client, response, interaction, channel);
}
public static async Task GetOriginalResponseAsync(BaseDiscordClient client, IMessageChannel channel,
IDiscordInteraction interaction, RequestOptions options = null)
{
var model = await client.ApiClient.GetInteractionResponseAsync(interaction.Token, options).ConfigureAwait(false);
- return RestInteractionMessage.Create(client, model, interaction.Token, channel);
+ if(model != null)
+ return RestInteractionMessage.Create(client, model, interaction.Token, channel);
+ return null;
}
public static async Task SendFollowupAsync(BaseDiscordClient client, CreateWebhookMessageParams args,
@@ -55,6 +58,15 @@ namespace Discord.Rest
var entity = RestFollowupMessage.Create(client, model, token, channel);
return entity;
}
+
+ public static async Task SendFollowupAsync(BaseDiscordClient client, UploadWebhookFileParams args,
+ string token, IMessageChannel channel, RequestOptions options = null)
+ {
+ var model = await client.ApiClient.CreateInteractionFollowupMessageAsync(args, token, options).ConfigureAwait(false);
+
+ var entity = RestFollowupMessage.Create(client, model, token, channel);
+ return entity;
+ }
#endregion
#region Global commands
diff --git a/src/Discord.Net.Rest/Entities/Interactions/MessageComponents/RestMessageComponent.cs b/src/Discord.Net.Rest/Entities/Interactions/MessageComponents/RestMessageComponent.cs
index eb47e15aa..9660bf7b0 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/MessageComponents/RestMessageComponent.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/MessageComponents/RestMessageComponent.cs
@@ -64,9 +64,9 @@ namespace Discord.Rest
/// if the message should be read out by a text-to-speech reader, otherwise .
/// if the response should be hidden to everyone besides the invoker of the command, otherwise .
/// The allowed mentions for this response.
- /// The request options for this response.
/// A to be sent with this response.
/// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ /// The request options for this response.
///
/// A string that contains json to write back to the incoming http request.
///
@@ -76,9 +76,9 @@ namespace Discord.Rest
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
MessageComponent component = null,
- Embed embed = null)
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -237,29 +237,16 @@ namespace Discord.Rest
return SerializePayload(response);
}
- ///
- /// Sends a followup message for this interaction.
- ///
- /// The text of the message to be sent.
- /// A array of embeds to send with this response. Max 10.
- /// if the message should be read out by a text-to-speech reader, otherwise .
- /// if the response should be hidden to everyone besides the invoker of the command, otherwise .
- /// The allowed mentions for this response.
- /// The request options for this response.
- /// A to be sent with this response.
- /// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
- ///
- /// The sent message.
- ///
+ ///
public override async Task FollowupAsync(
string text = null,
Embed[] embeds = null,
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
MessageComponent component = null,
- Embed embed = null)
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -284,11 +271,11 @@ namespace Discord.Rest
if (ephemeral)
args.Flags = MessageFlags.Ephemeral;
- return await InteractionHelper.SendFollowupAsync(Discord, args, Token, Message.Channel, options).ConfigureAwait(false);
+ return await InteractionHelper.SendFollowupAsync(Discord, args, Token, Channel, options);
}
///
- public override async Task FollowupWithFileAsync(
+ public override Task FollowupWithFileAsync(
Stream fileStream,
string fileName,
string text = null,
@@ -296,9 +283,9 @@ namespace Discord.Rest
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
- MessageComponent component = null,
- Embed embed = null)
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -307,40 +294,59 @@ namespace Discord.Rest
if (embed != null)
embeds = new[] { embed }.Concat(embeds).ToArray();
- 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(embeds.Length, 10, nameof(embeds), "A max of 10 embeds are allowed.");
Preconditions.NotNull(fileStream, nameof(fileStream), "File Stream must have data");
- Preconditions.NotNullOrWhitespace(fileName, nameof(fileName), "File Name must not be empty or null");
+ Preconditions.NotNullOrEmpty(fileName, nameof(fileName), "File Name must not be empty or null");
- var args = new API.Rest.CreateWebhookMessageParams
- {
- Content = text,
- AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified,
- IsTTS = isTTS,
- Embeds = embeds.Select(x => x.ToModel()).ToArray(),
- Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified,
- File = fileStream is not null ? new MultipartFile(fileStream, fileName) : Optional.Unspecified
- };
+ return FollowupWithFileAsync(new FileAttachment(fileStream, fileName), text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+ }
- if (ephemeral)
- args.Flags = MessageFlags.Ephemeral;
+ ///
+ public override Task FollowupWithFileAsync(
+ string filePath,
+ string fileName = null,
+ string text = null,
+ Embed[] embeds = null,
+ bool isTTS = false,
+ bool ephemeral = false,
+ AllowedMentions allowedMentions = null,
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
+ {
+ Preconditions.NotNullOrEmpty(filePath, nameof(filePath), "Path must exist");
- return await InteractionHelper.SendFollowupAsync(Discord, args, Token, Message.Channel, options).ConfigureAwait(false);
+ fileName ??= Path.GetFileName(filePath);
+ Preconditions.NotNullOrEmpty(fileName, nameof(fileName), "File Name must not be empty or null");
+
+ return FollowupWithFileAsync(new FileAttachment(File.OpenRead(filePath), fileName), text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
}
///
- public override async Task FollowupWithFileAsync(
- string filePath,
+ public override Task FollowupWithFileAsync(
+ FileAttachment attachment,
string text = null,
- string fileName = null,
Embed[] embeds = null,
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
- MessageComponent component = null,
- Embed embed = null)
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
+ {
+ return FollowupWithFilesAsync(new FileAttachment[] { attachment }, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+ }
+
+ ///
+ public override async Task FollowupWithFilesAsync(
+ IEnumerable attachments,
+ string text = null,
+ Embed[] embeds = null,
+ bool isTTS = false,
+ bool ephemeral = false,
+ AllowedMentions allowedMentions = null,
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -352,22 +358,35 @@ namespace Discord.Rest
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(embeds.Length, 10, nameof(embeds), "A max of 10 embeds are allowed.");
- Preconditions.NotNullOrWhitespace(filePath, nameof(filePath), "Path must exist");
- var args = new API.Rest.CreateWebhookMessageParams
+ foreach (var attachment in attachments)
{
- Content = text,
- AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified,
- IsTTS = isTTS,
- Embeds = embeds.Select(x => x.ToModel()).ToArray(),
- Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified,
- File = !string.IsNullOrEmpty(filePath) ? new MultipartFile(new MemoryStream(File.ReadAllBytes(filePath), false), fileName) : Optional.Unspecified
- };
+ Preconditions.NotNullOrEmpty(attachment.FileName, nameof(attachment.FileName), "File Name must not be empty or null");
+ }
+
+ // 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.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(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(allowedMentions));
+ }
+ }
+
+ var flags = MessageFlags.None;
if (ephemeral)
- args.Flags = MessageFlags.Ephemeral;
+ flags |= MessageFlags.Ephemeral;
- return await InteractionHelper.SendFollowupAsync(Discord, args, Token, Message.Channel, options).ConfigureAwait(false);
+ var args = new API.Rest.UploadWebhookFileParams(attachments.ToArray()) { Flags = flags, Content = text, IsTTS = isTTS, Embeds = embeds.Any() ? embeds.Select(x => x.ToModel()).ToArray() : Optional.Unspecified, AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified, MessageComponents = components?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified };
+ return await InteractionHelper.SendFollowupAsync(Discord, args, Token, Channel, options).ConfigureAwait(false);
}
///
diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs b/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs
index 37eb2a849..5c3219fa7 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs
@@ -139,8 +139,7 @@ namespace Discord.Rest
///
public abstract string Defer(bool ephemeral = false, RequestOptions options = null);
- ///
- public abstract Task FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null);
+
///
/// Gets the original response for this interaction.
///
@@ -154,14 +153,36 @@ namespace Discord.Rest
///
/// A delegate containing the properties to modify the message with.
/// The request options for this request.
- /// A that represents the initial response.
+ ///
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
+ ///
public async Task ModifyOriginalResponseAsync(Action func, RequestOptions options = null)
{
var model = await InteractionHelper.ModifyInteractionResponseAsync(Discord, Token, func, options);
return RestInteractionMessage.Create(Discord, model, Token, Channel);
}
///
- public abstract string Respond(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null);
+ public abstract string Respond(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent component = null, Embed embed = null, RequestOptions options = null);
+
+ ///
+ /// Sends a followup message for this interaction.
+ ///
+ /// The text of the message to be sent.
+ /// A array of embeds to send with this response. Max 10.
+ /// if the message should be read out by a text-to-speech reader, otherwise .
+ /// if the response should be hidden to everyone besides the invoker of the command, otherwise .
+ /// The allowed mentions for this response.
+ /// A to be sent with this response.
+ /// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ /// The request options for this response.
+ ///
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
+ ///
+ public abstract Task FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
+
///
/// Sends a followup message for this interaction.
///
@@ -172,14 +193,16 @@ namespace Discord.Rest
/// if the message should be read out by a text-to-speech reader, otherwise .
/// if the response should be hidden to everyone besides the invoker of the command, otherwise .
/// The allowed mentions for this response.
- /// The request options for this response.
- /// A to be sent with this response.
+ /// A to be sent with this response.
/// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ /// The request options for this response.
///
- /// The sent message.
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
///
public abstract Task FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null);
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
+
///
/// Sends a followup message for this interaction.
///
@@ -190,45 +213,90 @@ namespace Discord.Rest
/// if the message should be read out by a text-to-speech reader, otherwise .
/// if the response should be hidden to everyone besides the invoker of the command, otherwise .
/// The allowed mentions for this response.
+ /// A to be sent with this response.
+ /// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
/// The request options for this response.
- /// A to be sent with this response.
+ ///
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
+ ///
+ public abstract Task FollowupWithFileAsync(string filePath, string fileName = null, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
+
+ ///
+ /// Sends a followup message for this interaction.
+ ///
+ /// The attachment containing the file and description.
+ /// The text of the message to be sent.
+ /// A array of embeds to send with this response. Max 10.
+ /// if the message should be read out by a text-to-speech reader, otherwise .
+ /// if the response should be hidden to everyone besides the invoker of the command, otherwise .
+ /// The allowed mentions for this response.
+ /// The request options for this response.
+ /// A to be sent with this response.
/// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
///
- /// The sent message.
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
///
- public abstract Task FollowupWithFileAsync(string filePath, string text = null, string fileName = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null);
+ public abstract Task FollowupWithFileAsync(FileAttachment attachment, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
+
+ ///
+ /// Sends a followup message for this interaction.
+ ///
+ /// A collection of attachments to upload.
+ /// The text of the message to be sent.
+ /// A array of embeds to send with this response. Max 10.
+ /// if the message should be read out by a text-to-speech reader, otherwise .
+ /// if the response should be hidden to everyone besides the invoker of the command, otherwise .
+ /// The allowed mentions for this response.
+ /// The request options for this response.
+ /// A to be sent with this response.
+ /// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ ///
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
+ ///
+ public abstract Task FollowupWithFilesAsync(IEnumerable attachments, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
#region IDiscordInteraction
///
- Task IDiscordInteraction.RespondAsync(string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions, RequestOptions options, MessageComponent component, Embed embed)
- => Task.FromResult(Respond(text, embeds, isTTS, ephemeral, allowedMentions, options, component, embed));
+ IUser IDiscordInteraction.User => User;
+ ///
+ Task IDiscordInteraction.RespondAsync(string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions, MessageComponent components, Embed embed, RequestOptions options)
+ {
+ return Task.FromResult(null);
+ }
+ ///
Task IDiscordInteraction.DeferAsync(bool ephemeral, RequestOptions options)
=> Task.FromResult(Defer(ephemeral, options));
-
///
async Task IDiscordInteraction.FollowupAsync(string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions,
- RequestOptions options, MessageComponent component, Embed embed)
- => await FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, options, component, embed).ConfigureAwait(false);
-
+ MessageComponent component, Embed embed, RequestOptions options)
+ => await FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, component, embed, options).ConfigureAwait(false);
///
async Task IDiscordInteraction.GetOriginalResponseAsync(RequestOptions options)
=> await GetOriginalResponseAsync(options).ConfigureAwait(false);
-
///
async Task IDiscordInteraction.ModifyOriginalResponseAsync(Action func, RequestOptions options)
=> await ModifyOriginalResponseAsync(func, options).ConfigureAwait(false);
-
///
- async Task IDiscordInteraction.FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => await FollowupWithFileAsync(fileStream, fileName, text, embeds, isTTS, ephemeral, allowedMentions, options, component, embed).ConfigureAwait(false);
-
+ async Task IDiscordInteraction.FollowupWithFileAsync(Stream fileStream, string fileName, string text, Embed[] embeds, bool isTTS, bool ephemeral,
+ AllowedMentions allowedMentions, MessageComponent components, Embed embed, RequestOptions options)
+ => await FollowupWithFileAsync(fileStream, fileName, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false);
+ ///
+ async Task IDiscordInteraction.FollowupWithFileAsync(string filePath, string text, string fileName, Embed[] embeds, bool isTTS, bool ephemeral,
+ AllowedMentions allowedMentions, MessageComponent components, Embed embed, RequestOptions options)
+ => await FollowupWithFileAsync(filePath, text, fileName, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false);
+ ///
+ async Task IDiscordInteraction.FollowupWithFileAsync(FileAttachment attachment, string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions, MessageComponent components, Embed embed, RequestOptions options)
+ => await FollowupWithFileAsync(attachment, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false);
///
- async Task IDiscordInteraction.FollowupWithFileAsync(string filePath, string text = null, string fileName = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => await FollowupWithFileAsync(filePath, text, fileName, embeds, isTTS, ephemeral, allowedMentions, options, component, embed).ConfigureAwait(false);
+ async Task IDiscordInteraction.FollowupWithFilesAsync(IEnumerable attachments, string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions, MessageComponent components, Embed embed, RequestOptions options)
+ => await FollowupWithFilesAsync(attachments, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false);
#endregion
}
}
diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestPingInteraction.cs b/src/Discord.Net.Rest/Entities/Interactions/RestPingInteraction.cs
index f979a4df2..5ed5e054a 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/RestPingInteraction.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/RestPingInteraction.cs
@@ -38,9 +38,11 @@ namespace Discord.Rest
}
public override string Defer(bool ephemeral = false, RequestOptions options = null) => throw new NotSupportedException();
- public override Task FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null) => throw new NotSupportedException();
- public override Task FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null) => throw new NotSupportedException();
- public override Task FollowupWithFileAsync(string filePath, string text = null, string fileName = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null) => throw new NotSupportedException();
- public override string Respond(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null) => throw new NotSupportedException();
+ public override string Respond(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent component = null, Embed embed = null, RequestOptions options = null) => throw new NotSupportedException();
+ public override Task FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null) => throw new NotSupportedException();
+ public override Task FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null) => throw new NotSupportedException();
+ public override Task FollowupWithFileAsync(string filePath, string fileName = null, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null) => throw new NotSupportedException();
+ public override Task FollowupWithFileAsync(FileAttachment attachment, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null) => throw new NotSupportedException();
+ public override Task FollowupWithFilesAsync(IEnumerable attachments, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null) => throw new NotSupportedException();
}
}
diff --git a/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestAutocompleteInteraction.cs b/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestAutocompleteInteraction.cs
index 8737dc5ac..1abeb4b3f 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestAutocompleteInteraction.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestAutocompleteInteraction.cs
@@ -102,31 +102,21 @@ namespace Discord.Rest
///
public string Respond(RequestOptions options = null, params AutocompleteResult[] result)
=> Respond(result, options);
-
- ///
- [Obsolete("Autocomplete interactions cannot be deferred!", true)]
public override string Defer(bool ephemeral = false, RequestOptions options = null)
- => throw new NotSupportedException("Autocomplete interactions cannot be deferred!");
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
+ public override string Respond(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent component = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
+ public override Task FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
+ public override Task FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
+ public override Task FollowupWithFileAsync(string filePath, string fileName = null, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
+ public override Task FollowupWithFileAsync(FileAttachment attachment, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
+ public override Task FollowupWithFilesAsync(IEnumerable attachments, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
- ///
- [Obsolete("Autocomplete interactions cannot have followups!", true)]
- public override Task FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => throw new NotSupportedException("Autocomplete interactions cannot be deferred!");
-
- ///
- [Obsolete("Autocomplete interactions cannot have followups!", true)]
- public override Task FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => throw new NotSupportedException("Autocomplete interactions cannot be deferred!");
-
- ///
- [Obsolete("Autocomplete interactions cannot have followups!", true)]
- public override Task FollowupWithFileAsync(string filePath, string text = null, string fileName = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => throw new NotSupportedException("Autocomplete interactions cannot be deferred!");
-
- ///
- [Obsolete("Autocomplete interactions cannot have normal responses!", true)]
- public override string Respond(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => throw new NotSupportedException("Autocomplete interactions cannot be deferred!");
//IAutocompleteInteraction
///
diff --git a/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestSlashCommand.cs b/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestSlashCommand.cs
index 785e39a12..21184fcf6 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestSlashCommand.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestSlashCommand.cs
@@ -44,5 +44,9 @@ namespace Discord.Rest
//ISlashCommandInteraction
///
IApplicationCommandInteractionData ISlashCommandInteraction.Data => Data;
+
+ //IApplicationCommandInteraction
+ ///
+ IApplicationCommandInteractionData IApplicationCommandInteraction.Data => Data;
}
}
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestFollowupMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestFollowupMessage.cs
index 693d36e56..aa5dd5aeb 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestFollowupMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestFollowupMessage.cs
@@ -5,7 +5,7 @@ using Model = Discord.API.Message;
namespace Discord.Rest
{
///
- /// Represents a REST-based follow up message sent by a bot responding to a slash command.
+ /// Represents a REST-based follow up message sent by a bot responding to an interaction.
///
public class RestFollowupMessage : RestUserMessage
{
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestInteractionMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestInteractionMessage.cs
index 26beb03b6..815f1953f 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestInteractionMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestInteractionMessage.cs
@@ -1,15 +1,16 @@
using System;
using System.Threading.Tasks;
-using Model = Discord.API.Message;
+using MessageModel = Discord.API.Message;
+using Model = Discord.API.InteractionResponse;
namespace Discord.Rest
{
///
- /// Represents the initial REST-based response to a slash command.
+ /// Represents the initial REST-based response to an interaction.
///
public class RestInteractionMessage : RestUserMessage
{
- // Token used to delete/modify this followup message
+ public InteractionResponseType ResponseType { get; private set; }
internal string Token { get; }
internal RestInteractionMessage(BaseDiscordClient discord, ulong id, IUser author, string token, IMessageChannel channel)
@@ -18,18 +19,31 @@ namespace Discord.Rest
Token = token;
}
- internal static RestInteractionMessage Create(BaseDiscordClient discord, Model model, string token, IMessageChannel channel)
+ internal static RestInteractionMessage Create(BaseDiscordClient discord, MessageModel model, string token, IMessageChannel channel)
{
var entity = new RestInteractionMessage(discord, model.Id, model.Author.IsSpecified ? RestUser.Create(discord, model.Author.Value) : discord.CurrentUser, token, channel);
entity.Update(model);
return entity;
}
- internal new void Update(Model model)
+ internal static RestInteractionMessage Create(BaseDiscordClient discord, Model model, IDiscordInteraction interaction, IMessageChannel channel)
+ {
+ var entity = new RestInteractionMessage(discord, interaction.Id, discord.CurrentUser, interaction.Token, channel);
+ entity.Update(model, interaction);
+ return entity;
+ }
+
+ internal new void Update(MessageModel model)
{
base.Update(model);
}
+ internal void Update(Model model, IDiscordInteraction interaction)
+ {
+ ResponseType = model.Type;
+ base.Update(model.ToMessage(interaction));
+ }
+
///
/// Deletes this object and all of it's children.
///
diff --git a/src/Discord.Net.Rest/Extensions/EntityExtensions.cs b/src/Discord.Net.Rest/Extensions/EntityExtensions.cs
index 05bd04e64..bca2e8715 100644
--- a/src/Discord.Net.Rest/Extensions/EntityExtensions.cs
+++ b/src/Discord.Net.Rest/Extensions/EntityExtensions.cs
@@ -170,5 +170,48 @@ namespace Discord.Rest
{
return new Overwrite(model.TargetId, model.TargetType, new OverwritePermissions(model.Allow, model.Deny));
}
+
+ public static API.Message ToMessage(this API.InteractionResponse model, IDiscordInteraction interaction)
+ {
+ if (model.Data.IsSpecified)
+ {
+ var data = model.Data.Value;
+ var messageModel = new API.Message
+ {
+ IsTextToSpeech = data.TTS,
+ Content = data.Content,
+ Embeds = data.Embeds,
+ AllowedMentions = data.AllowedMentions,
+ Components = data.Components,
+ Flags = data.Flags,
+ };
+
+ if(interaction is IApplicationCommandInteraction command)
+ {
+ messageModel.Interaction = new API.MessageInteraction
+ {
+ Id = command.Id,
+ Name = command.Data.Name,
+ Type = InteractionType.ApplicationCommand,
+ User = new API.User
+ {
+ Username = command.User.Username,
+ Avatar = command.User.AvatarId,
+ Bot = command.User.IsBot,
+ Discriminator = command.User.Discriminator,
+ PublicFlags = command.User.PublicFlags.HasValue ? command.User.PublicFlags.Value : Optional.Unspecified,
+ Id = command.User.Id,
+ }
+ };
+ }
+
+ return messageModel;
+ }
+
+ return new API.Message
+ {
+ Id = interaction.Id,
+ };
+ }
}
}
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/ContextMenuCommands/MessageCommands/SocketMessageCommand.cs b/src/Discord.Net.WebSocket/Entities/Interaction/ContextMenuCommands/MessageCommands/SocketMessageCommand.cs
index 0aa061439..fee33f8cb 100644
--- a/src/Discord.Net.WebSocket/Entities/Interaction/ContextMenuCommands/MessageCommands/SocketMessageCommand.cs
+++ b/src/Discord.Net.WebSocket/Entities/Interaction/ContextMenuCommands/MessageCommands/SocketMessageCommand.cs
@@ -41,5 +41,9 @@ namespace Discord.WebSocket
//IDiscordInteraction
///
IDiscordInteractionData IDiscordInteraction.Data => Data;
+
+ //IApplicationCommandInteraction
+ ///
+ IApplicationCommandInteractionData IApplicationCommandInteraction.Data => Data;
}
}
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/ContextMenuCommands/UserCommands/SocketUserCommand.cs b/src/Discord.Net.WebSocket/Entities/Interaction/ContextMenuCommands/UserCommands/SocketUserCommand.cs
index 40ee5b537..75e8ebff9 100644
--- a/src/Discord.Net.WebSocket/Entities/Interaction/ContextMenuCommands/UserCommands/SocketUserCommand.cs
+++ b/src/Discord.Net.WebSocket/Entities/Interaction/ContextMenuCommands/UserCommands/SocketUserCommand.cs
@@ -41,5 +41,9 @@ namespace Discord.WebSocket
//IDiscordInteraction
///
IDiscordInteractionData IDiscordInteraction.Data => Data;
+
+ //IApplicationCommandInteraction
+ ///
+ IApplicationCommandInteractionData IApplicationCommandInteraction.Data => Data;
}
}
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/MessageComponents/SocketMessageComponent.cs b/src/Discord.Net.WebSocket/Entities/Interaction/MessageComponents/SocketMessageComponent.cs
index 928a4302a..d5d5f959d 100644
--- a/src/Discord.Net.WebSocket/Entities/Interaction/MessageComponents/SocketMessageComponent.cs
+++ b/src/Discord.Net.WebSocket/Entities/Interaction/MessageComponents/SocketMessageComponent.cs
@@ -72,15 +72,15 @@ namespace Discord.WebSocket
}
}
///
- public override async Task RespondAsync(
+ 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,
- Embed embed = null)
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -136,11 +136,16 @@ namespace Discord.WebSocket
}
}
- await InteractionHelper.SendInteractionResponseAsync(Discord, response, Id, Token, options).ConfigureAwait(false);
-
- lock (_lock)
+ try
{
- HasResponded = true;
+ return await InteractionHelper.SendInteractionResponseAsync(Discord, response, this, Channel, options).ConfigureAwait(false);
+ }
+ finally
+ {
+ lock (_lock)
+ {
+ HasResponded = true;
+ }
}
}
@@ -231,7 +236,7 @@ namespace Discord.WebSocket
}
}
- await InteractionHelper.SendInteractionResponseAsync(Discord, response, Id, Token, options).ConfigureAwait(false);
+ await InteractionHelper.SendInteractionResponseAsync(Discord, response, this, Channel, options).ConfigureAwait(false);
lock (_lock)
{
@@ -246,9 +251,9 @@ namespace Discord.WebSocket
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
MessageComponent component = null,
- Embed embed = null)
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -273,11 +278,11 @@ namespace Discord.WebSocket
if (ephemeral)
args.Flags = MessageFlags.Ephemeral;
- return await InteractionHelper.SendFollowupAsync(Discord.Rest, args, Token, Channel, options).ConfigureAwait(false);
+ return await InteractionHelper.SendFollowupAsync(Discord.Rest, args, Token, Channel, options);
}
///
- public override async Task FollowupWithFileAsync(
+ public override Task FollowupWithFileAsync(
Stream fileStream,
string fileName,
string text = null,
@@ -285,9 +290,9 @@ namespace Discord.WebSocket
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
- MessageComponent component = null,
- Embed embed = null)
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -296,40 +301,59 @@ namespace Discord.WebSocket
if (embed != null)
embeds = new[] { embed }.Concat(embeds).ToArray();
- 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(embeds.Length, 10, nameof(embeds), "A max of 10 embeds are allowed.");
Preconditions.NotNull(fileStream, nameof(fileStream), "File Stream must have data");
- Preconditions.NotNullOrWhitespace(fileName, nameof(fileName), "File Name must not be empty or null");
+ Preconditions.NotNullOrEmpty(fileName, nameof(fileName), "File Name must not be empty or null");
- var args = new API.Rest.CreateWebhookMessageParams
- {
- Content = text,
- AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified,
- IsTTS = isTTS,
- Embeds = embeds.Select(x => x.ToModel()).ToArray(),
- Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified,
- File = fileStream is not null ? new MultipartFile(fileStream, fileName) : Optional.Unspecified
- };
+ return FollowupWithFileAsync(new FileAttachment(fileStream, fileName), text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+ }
- if (ephemeral)
- args.Flags = MessageFlags.Ephemeral;
+ ///
+ public override Task FollowupWithFileAsync(
+ string filePath,
+ string fileName = null,
+ string text = null,
+ Embed[] embeds = null,
+ bool isTTS = false,
+ bool ephemeral = false,
+ AllowedMentions allowedMentions = null,
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
+ {
+ Preconditions.NotNullOrEmpty(filePath, nameof(filePath), "Path must exist");
- return await InteractionHelper.SendFollowupAsync(Discord.Rest, args, Token, Channel, options).ConfigureAwait(false);
+ fileName ??= Path.GetFileName(filePath);
+ Preconditions.NotNullOrEmpty(fileName, nameof(fileName), "File Name must not be empty or null");
+
+ return FollowupWithFileAsync(new FileAttachment(File.OpenRead(filePath), fileName), text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
}
///
- public override async Task FollowupWithFileAsync(
- string filePath,
+ public override Task FollowupWithFileAsync(
+ FileAttachment attachment,
string text = null,
- string fileName = null,
Embed[] embeds = null,
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
- MessageComponent component = null,
- Embed embed = null)
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
+ {
+ return FollowupWithFilesAsync(new FileAttachment[] { attachment }, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+ }
+
+ ///
+ public override async Task FollowupWithFilesAsync(
+ IEnumerable attachments,
+ string text = null,
+ Embed[] embeds = null,
+ bool isTTS = false,
+ bool ephemeral = false,
+ AllowedMentions allowedMentions = null,
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -341,22 +365,35 @@ namespace Discord.WebSocket
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(embeds.Length, 10, nameof(embeds), "A max of 10 embeds are allowed.");
- Preconditions.NotNullOrWhitespace(filePath, nameof(filePath), "Path must exist");
- var args = new API.Rest.CreateWebhookMessageParams
+ foreach (var attachment in attachments)
{
- Content = text,
- AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified,
- IsTTS = isTTS,
- Embeds = embeds.Select(x => x.ToModel()).ToArray(),
- Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified,
- File = !string.IsNullOrEmpty(filePath) ? new MultipartFile(new MemoryStream(File.ReadAllBytes(filePath), false), fileName) : Optional.Unspecified
- };
+ Preconditions.NotNullOrEmpty(attachment.FileName, nameof(attachment.FileName), "File Name must not be empty or null");
+ }
+
+ // 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.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(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(allowedMentions));
+ }
+ }
+
+ var flags = MessageFlags.None;
if (ephemeral)
- args.Flags = MessageFlags.Ephemeral;
+ flags |= MessageFlags.Ephemeral;
- return await InteractionHelper.SendFollowupAsync(Discord.Rest, args, Token, Channel, options).ConfigureAwait(false);
+ var args = new API.Rest.UploadWebhookFileParams(attachments.ToArray()) { Flags = flags, Content = text, IsTTS = isTTS, Embeds = embeds.Any() ? embeds.Select(x => x.ToModel()).ToArray() : Optional.Unspecified, AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified, MessageComponents = components?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified };
+ return await InteractionHelper.SendFollowupAsync(Discord, args, Token, Channel, options).ConfigureAwait(false);
}
///
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketAutocompleteInteraction.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketAutocompleteInteraction.cs
index 0f598586b..955d7d53f 100644
--- a/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketAutocompleteInteraction.cs
+++ b/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketAutocompleteInteraction.cs
@@ -89,31 +89,20 @@ namespace Discord.WebSocket
///
public Task RespondAsync(RequestOptions options = null, params AutocompleteResult[] result)
=> RespondAsync(result, options);
-
- ///
- [Obsolete("Autocomplete interactions cannot be deferred!", true)]
+ public override Task RespondAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
+ public override Task FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
+ public override Task FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
+ public override Task FollowupWithFileAsync(string filePath, string fileName = null, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
+ public override Task FollowupWithFileAsync(FileAttachment attachment, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
+ public override Task FollowupWithFilesAsync(IEnumerable attachments, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
public override Task DeferAsync(bool ephemeral = false, RequestOptions options = null)
- => throw new NotSupportedException("Autocomplete interactions cannot be deferred!");
-
- ///
- [Obsolete("Autocomplete interactions cannot have followups!", true)]
- public override Task FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => throw new NotSupportedException("Autocomplete interactions cannot be deferred!");
-
- ///
- [Obsolete("Autocomplete interactions cannot have followups!", true)]
- public override Task FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => throw new NotSupportedException("Autocomplete interactions cannot be deferred!");
-
- ///
- [Obsolete("Autocomplete interactions cannot have followups!", true)]
- public override Task FollowupWithFileAsync(string filePath, string text = null, string fileName = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => throw new NotSupportedException("Autocomplete interactions cannot be deferred!");
-
- ///
- [Obsolete("Autocomplete interactions cannot have normal responses!", true)]
- public override Task RespondAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => throw new NotSupportedException("Autocomplete interactions cannot be deferred!");
+ => throw new NotSupportedException("Autocomplete interactions don't support this method!");
//IAutocompleteInteraction
///
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketSlashCommand.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketSlashCommand.cs
index 5343bb225..5934a3864 100644
--- a/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketSlashCommand.cs
+++ b/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketSlashCommand.cs
@@ -41,5 +41,9 @@ namespace Discord.WebSocket
//IDiscordInteraction
///
IDiscordInteractionData IDiscordInteraction.Data => Data;
+
+ //IApplicationCommandInteraction
+ ///
+ IApplicationCommandInteractionData IApplicationCommandInteraction.Data => Data;
}
}
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs
index 92303d488..80c4a93be 100644
--- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs
+++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs
@@ -1,6 +1,7 @@
using Discord.Net.Rest;
using Discord.Rest;
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
@@ -68,15 +69,15 @@ namespace Discord.WebSocket
}
///
- public override async Task RespondAsync(
+ 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,
- Embed embed = null)
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -130,11 +131,16 @@ namespace Discord.WebSocket
}
}
- await InteractionHelper.SendInteractionResponseAsync(Discord, response, Id, Token, options).ConfigureAwait(false);
-
- lock (_lock)
+ try
{
- HasResponded = true;
+ return await InteractionHelper.SendInteractionResponseAsync(Discord, response, this, Channel, options).ConfigureAwait(false);
+ }
+ finally
+ {
+ lock (_lock)
+ {
+ HasResponded = true;
+ }
}
}
@@ -145,9 +151,9 @@ namespace Discord.WebSocket
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
MessageComponent component = null,
- Embed embed = null)
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -176,7 +182,7 @@ namespace Discord.WebSocket
}
///
- public override async Task FollowupWithFileAsync(
+ public override Task FollowupWithFileAsync(
Stream fileStream,
string fileName,
string text = null,
@@ -184,9 +190,9 @@ namespace Discord.WebSocket
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
- MessageComponent component = null,
- Embed embed = null)
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -195,40 +201,59 @@ namespace Discord.WebSocket
if (embed != null)
embeds = new[] { embed }.Concat(embeds).ToArray();
- 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(embeds.Length, 10, nameof(embeds), "A max of 10 embeds are allowed.");
Preconditions.NotNull(fileStream, nameof(fileStream), "File Stream must have data");
Preconditions.NotNullOrEmpty(fileName, nameof(fileName), "File Name must not be empty or null");
- var args = new API.Rest.CreateWebhookMessageParams
- {
- Content = text,
- AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified,
- IsTTS = isTTS,
- Embeds = embeds.Select(x => x.ToModel()).ToArray(),
- Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified,
- File = fileStream is not null ? new MultipartFile(fileStream, fileName) : Optional.Unspecified
- };
+ return FollowupWithFileAsync(new FileAttachment(fileStream, fileName), text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+ }
- if (ephemeral)
- args.Flags = MessageFlags.Ephemeral;
+ ///
+ public override Task FollowupWithFileAsync(
+ string filePath,
+ string fileName = null,
+ string text = null,
+ Embed[] embeds = null,
+ bool isTTS = false,
+ bool ephemeral = false,
+ AllowedMentions allowedMentions = null,
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
+ {
+ Preconditions.NotNullOrEmpty(filePath, nameof(filePath), "Path must exist");
- return await InteractionHelper.SendFollowupAsync(Discord.Rest, args, Token, Channel, options);
+ fileName ??= Path.GetFileName(filePath);
+ Preconditions.NotNullOrEmpty(fileName, nameof(fileName), "File Name must not be empty or null");
+
+ return FollowupWithFileAsync(new FileAttachment(File.OpenRead(filePath), fileName), text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
}
///
- public override async Task FollowupWithFileAsync(
- string filePath,
+ public override Task FollowupWithFileAsync(
+ FileAttachment attachment,
string text = null,
- string fileName = null,
Embed[] embeds = null,
bool isTTS = false,
bool ephemeral = false,
AllowedMentions allowedMentions = null,
- RequestOptions options = null,
- MessageComponent component = null,
- Embed embed = null)
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
+ {
+ return FollowupWithFilesAsync(new FileAttachment[] { attachment }, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+ }
+
+ ///
+ public override async Task FollowupWithFilesAsync(
+ IEnumerable attachments,
+ string text = null,
+ Embed[] embeds = null,
+ bool isTTS = false,
+ bool ephemeral = false,
+ AllowedMentions allowedMentions = null,
+ MessageComponent components = null,
+ Embed embed = null,
+ RequestOptions options = null)
{
if (!IsValidToken)
throw new InvalidOperationException("Interaction token is no longer valid");
@@ -240,25 +265,35 @@ namespace Discord.WebSocket
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(embeds.Length, 10, nameof(embeds), "A max of 10 embeds are allowed.");
- Preconditions.NotNullOrEmpty(filePath, nameof(filePath), "Path must exist");
- fileName ??= Path.GetFileName(filePath);
- Preconditions.NotNullOrEmpty(fileName, nameof(fileName), "File Name must not be empty or null");
+ foreach (var attachment in attachments)
+ {
+ Preconditions.NotNullOrEmpty(attachment.FileName, nameof(attachment.FileName), "File Name must not be empty or null");
+ }
- var args = new API.Rest.CreateWebhookMessageParams
+ // check that user flag and user Id list are exclusive, same with role flag and role Id list
+ if (allowedMentions != null && allowedMentions.AllowedTypes.HasValue)
{
- Content = text,
- AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified,
- IsTTS = isTTS,
- Embeds = embeds.Select(x => x.ToModel()).ToArray(),
- Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified,
- File = !string.IsNullOrEmpty(filePath) ? new MultipartFile(new MemoryStream(File.ReadAllBytes(filePath), false), fileName) : Optional.Unspecified
- };
+ 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(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(allowedMentions));
+ }
+ }
+
+ var flags = MessageFlags.None;
if (ephemeral)
- args.Flags = MessageFlags.Ephemeral;
+ flags |= MessageFlags.Ephemeral;
- return await InteractionHelper.SendFollowupAsync(Discord.Rest, args, Token, Channel, options);
+ var args = new API.Rest.UploadWebhookFileParams(attachments.ToArray()) { Flags = flags, Content = text, IsTTS = isTTS, Embeds = embeds.Any() ? embeds.Select(x => x.ToModel()).ToArray() : Optional.Unspecified, AllowedMentions = allowedMentions?.ToModel() ?? Optional.Unspecified, MessageComponents = components?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional.Unspecified };
+ return await InteractionHelper.SendFollowupAsync(Discord, args, Token, Channel, options).ConfigureAwait(false);
}
///
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs
index 52f3254c5..1bfd77479 100644
--- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs
+++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs
@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Model = Discord.API.Interaction;
using DataModel = Discord.API.ApplicationCommandInteractionData;
using System.IO;
+using System.Collections.Generic;
namespace Discord.WebSocket
{
@@ -130,13 +131,13 @@ namespace Discord.WebSocket
/// if the message should be read out by a text-to-speech reader, otherwise .
/// if the response should be hidden to everyone besides the invoker of the command, otherwise .
/// The allowed mentions for this response.
- /// The request options for this response.
- /// A to be sent with this response.
+ /// A to be sent with this response.
/// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ /// The request options for this response.
/// Message content is too long, length must be less or equal to .
/// The parameters provided were invalid or the token was invalid.
- 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, Embed embed = null);
+ public abstract Task RespondAsync(string text = null, Embed[] embeds = null, bool isTTS = false,
+ bool ephemeral = false, AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
///
/// Sends a followup message for this interaction.
@@ -146,14 +147,14 @@ namespace Discord.WebSocket
/// if the message should be read out by a text-to-speech reader, otherwise .
/// if the response should be hidden to everyone besides the invoker of the command, otherwise .
/// The allowed mentions for this response.
- /// The request options for this response.
- /// A to be sent with this response.
+ /// A to be sent with this response.
/// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ /// The request options for this response.
///
/// The sent message.
///
public abstract Task FollowupAsync(string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null);
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
///
/// Sends a followup message for this interaction.
@@ -165,14 +166,14 @@ namespace Discord.WebSocket
/// if the message should be read out by a text-to-speech reader, otherwise .
/// if the response should be hidden to everyone besides the invoker of the command, otherwise .
/// The allowed mentions for this response.
- /// The request options for this response.
- /// A to be sent with this response.
+ /// A to be sent with this response.
/// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ /// The request options for this response.
///
/// The sent message.
///
public abstract Task FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null);
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
///
/// Sends a followup message for this interaction.
@@ -184,14 +185,52 @@ namespace Discord.WebSocket
/// if the message should be read out by a text-to-speech reader, otherwise .
/// if the response should be hidden to everyone besides the invoker of the command, otherwise .
/// The allowed mentions for this response.
- /// The request options for this response.
- /// A to be sent with this response.
+ /// A to be sent with this response.
/// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ /// The request options for this response.
///
/// The sent message.
///
- public abstract Task FollowupWithFileAsync(string filePath, string text = null, string fileName = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null);
+ public abstract Task FollowupWithFileAsync(string filePath, string fileName = null, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
+
+ ///
+ /// Sends a followup message for this interaction.
+ ///
+ /// The attachment containing the file and description.
+ /// The text of the message to be sent.
+ /// A array of embeds to send with this response. Max 10.
+ /// if the message should be read out by a text-to-speech reader, otherwise .
+ /// if the response should be hidden to everyone besides the invoker of the command, otherwise .
+ /// The allowed mentions for this response.
+ /// The request options for this response.
+ /// A to be sent with this response.
+ /// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ ///
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
+ ///
+ public abstract Task FollowupWithFileAsync(FileAttachment attachment, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
+
+ ///
+ /// Sends a followup message for this interaction.
+ ///
+ /// A collection of attachments to upload.
+ /// The text of the message to be sent.
+ /// A array of embeds to send with this response. Max 10.
+ /// if the message should be read out by a text-to-speech reader, otherwise .
+ /// if the response should be hidden to everyone besides the invoker of the command, otherwise .
+ /// The allowed mentions for this response.
+ /// The request options for this response.
+ /// A to be sent with this response.
+ /// A single embed to send with this response. If this is passed alongside an array of embeds, the single embed will be ignored.
+ ///
+ /// A task that represents an asynchronous send operation for delivering the message. The task result
+ /// contains the sent message.
+ ///
+ public abstract Task FollowupWithFilesAsync(IEnumerable attachments, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null);
///
/// Gets the original response for this interaction.
@@ -222,32 +261,37 @@ namespace Discord.WebSocket
/// A task that represents the asynchronous operation of acknowledging the interaction.
///
public abstract Task DeferAsync(bool ephemeral = false, RequestOptions options = null);
-
+
#endregion
#region IDiscordInteraction
///
- async Task IDiscordInteraction.FollowupAsync(string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions,
- RequestOptions options, MessageComponent component, Embed embed)
- => await FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, options, component, embed).ConfigureAwait(false);
-
- ///
- async Task IDiscordInteraction.FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => await FollowupWithFileAsync(fileStream, fileName, text, embeds, isTTS, ephemeral, allowedMentions, options, component, embed).ConfigureAwait(false);
-
- ///
- async Task IDiscordInteraction.FollowupWithFileAsync(string filePath, string text = null, string fileName = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
- AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null, Embed embed = null)
- => await FollowupWithFileAsync(filePath, text, fileName, embeds, isTTS, ephemeral, allowedMentions, options, component, embed).ConfigureAwait(false);
+ IUser IDiscordInteraction.User => User;
///
async Task IDiscordInteraction.GetOriginalResponseAsync(RequestOptions options)
=> await GetOriginalResponseAsync(options).ConfigureAwait(false);
-
///
async Task IDiscordInteraction.ModifyOriginalResponseAsync(Action func, RequestOptions options)
=> await ModifyOriginalResponseAsync(func, options).ConfigureAwait(false);
+ ///
+ async Task IDiscordInteraction.RespondAsync(string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions, MessageComponent components, Embed embed, RequestOptions options)
+ => await RespondAsync(text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false);
+ ///
+ async Task IDiscordInteraction.FollowupAsync(string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions, MessageComponent components, Embed embed, RequestOptions options)
+ => await FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false);
+ ///
+ async Task IDiscordInteraction.FollowupWithFileAsync(Stream fileStream, string fileName, string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions, MessageComponent components, Embed embed, RequestOptions options)
+ => await FollowupWithFileAsync(fileStream, fileName, text, embeds, isTTS, ephemeral, allowedMentions, components, embed).ConfigureAwait(false);
+ ///
+ async Task IDiscordInteraction.FollowupWithFileAsync(string filePath, string fileName, string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions, MessageComponent components, Embed embed, RequestOptions options)
+ => await FollowupWithFileAsync(filePath, fileName, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false);
+ ///
+ async Task IDiscordInteraction.FollowupWithFileAsync(FileAttachment attachment, string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions, MessageComponent components, Embed embed, RequestOptions options)
+ => await FollowupWithFileAsync(attachment, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false);
+ ///
+ async Task IDiscordInteraction.FollowupWithFilesAsync(IEnumerable attachments, string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions, MessageComponent components, Embed embed, RequestOptions options)
+ => await FollowupWithFilesAsync(attachments, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false);
#endregion
}
}
diff --git a/src/Discord.Net.WebSocket/Entities/Stickers/SocketSticker.cs b/src/Discord.Net.WebSocket/Entities/Stickers/SocketSticker.cs
index ee45720b5..b9c122cce 100644
--- a/src/Discord.Net.WebSocket/Entities/Stickers/SocketSticker.cs
+++ b/src/Discord.Net.WebSocket/Entities/Stickers/SocketSticker.cs
@@ -88,5 +88,11 @@ namespace Discord.WebSocket
return base.Equals(obj);
}
+
+ ///
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
}
}