diff --git a/DisCatSharp.ApplicationCommands/Context/BaseContext.cs b/DisCatSharp.ApplicationCommands/Context/BaseContext.cs
index a7443f35f..d88cd5163 100644
--- a/DisCatSharp.ApplicationCommands/Context/BaseContext.cs
+++ b/DisCatSharp.ApplicationCommands/Context/BaseContext.cs
@@ -1,180 +1,180 @@
// This file is part of the DisCatSharp project.
//
// Copyright (c) 2021 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using System.Threading.Tasks;
using DisCatSharp.Entities;
using DisCatSharp.Enums;
using Microsoft.Extensions.DependencyInjection;
namespace DisCatSharp.ApplicationCommands
{
///
/// Respresents a base context for application command contexts.
///
public class BaseContext
{
///
/// Gets the interaction that was created.
///
public DiscordInteraction Interaction { get; internal set; }
///
/// Gets the client for this interaction.
///
public DiscordClient Client { get; internal set; }
///
/// Gets the guild this interaction was executed in.
///
public DiscordGuild Guild { get; internal set; }
///
/// Gets the channel this interaction was executed in.
///
public DiscordChannel Channel { get; internal set; }
///
/// Gets the user which executed this interaction.
///
public DiscordUser User { get; internal set; }
///
/// Gets the member which executed this interaction, or null if the command is in a DM.
///
public DiscordMember Member
=> this.User is DiscordMember member ? member : null;
///
/// Gets the application command module this interaction was created in.
///
public ApplicationCommandsExtension ApplicationCommandsExtension { get; internal set; }
///
/// Gets the token for this interaction.
///
public string Token { get; internal set; }
///
/// Gets the id for this interaction.
///
public ulong InteractionId { get; internal set; }
///
/// Gets the name of the command.
///
public string CommandName { get; internal set; }
///
/// Gets the invoking user locale.
///
public string Locale { get; internal set; }
///
/// Gets the guild locale if applicable.
///
public string GuildLocale { get; internal set; }
///
/// Gets the type of this interaction.
///
public ApplicationCommandType Type { get; internal set;}
///
/// Gets the service provider.
/// This allows passing data around without resorting to static members.
/// Defaults to null.
///
public IServiceProvider Services { get; internal set; } = new ServiceCollection().BuildServiceProvider(true);
///
/// Creates a response to this interaction.
/// You must create a response within 3 seconds of this interaction being executed; if the command has the potential to take more than 3 seconds, create a at the start, and edit the response later.
///
/// The type of the response.
/// The data to be sent, if any.
///
public Task CreateResponseAsync(InteractionResponseType type, DiscordInteractionResponseBuilder builder = null)
=> this.Interaction.CreateResponseAsync(type, builder);
///
/// Creates a modal response to this interaction.
///
/// The data to send.
- public Task CreateModalResponseAsync(DiscordInteractionModalBuilder builder) =>
- this.Interaction.CreateInteractionModalResponseAsync(builder);
+ public Task CreateModalResponseAsync(DiscordInteractionModalBuilder builder)
+ => this.Interaction.Type != InteractionType.Ping && this.Interaction.Type != InteractionType.ModalSubmit ? this.Interaction.CreateInteractionModalResponseAsync(builder) : throw new NotSupportedException("You can't respond to an PING with a modal.");
///
/// Edits the interaction response.
///
/// The data to edit the response with.
///
public Task EditResponseAsync(DiscordWebhookBuilder builder)
=> this.Interaction.EditOriginalResponseAsync(builder);
///
/// Deletes the interaction response.
///
///
public Task DeleteResponseAsync()
=> this.Interaction.DeleteOriginalResponseAsync();
///
/// Creates a follow up message to the interaction.
///
/// The message to be sent, in the form of a webhook.
/// The created message.
public Task FollowUpAsync(DiscordFollowupMessageBuilder builder)
=> this.Interaction.CreateFollowupMessageAsync(builder);
///
/// Edits a followup message.
///
/// The id of the followup message to edit.
/// The webhook builder.
///
public Task EditFollowupAsync(ulong followupMessageId, DiscordWebhookBuilder builder)
=> this.Interaction.EditFollowupMessageAsync(followupMessageId, builder);
///
/// Deletes a followup message.
///
/// The id of the followup message to delete.
///
public Task DeleteFollowupAsync(ulong followupMessageId)
=> this.Interaction.DeleteFollowupMessageAsync(followupMessageId);
///
/// Gets the followup message.
///
/// The followup message id.
public Task GetFollowupMessageAsync(ulong followupMessageId)
=> this.Interaction.GetFollowupMessageAsync(followupMessageId);
///
/// Gets the original interaction response.
///
/// The original interaction response.
public Task GetOriginalResponseAsync()
=> this.Interaction.GetOriginalResponseAsync();
}
}
diff --git a/DisCatSharp/Entities/Interaction/DiscordInteraction.cs b/DisCatSharp/Entities/Interaction/DiscordInteraction.cs
index e26159bc2..3c6f55402 100644
--- a/DisCatSharp/Entities/Interaction/DiscordInteraction.cs
+++ b/DisCatSharp/Entities/Interaction/DiscordInteraction.cs
@@ -1,218 +1,219 @@
// This file is part of the DisCatSharp project.
//
// Copyright (c) 2021 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
+using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace DisCatSharp.Entities
{
///
/// Represents an interaction that was invoked.
///
public sealed class DiscordInteraction : SnowflakeObject
{
///
/// Gets the type of interaction invoked.
///
[JsonProperty("type")]
public InteractionType Type { get; internal set; }
///
/// Gets the command data for this interaction.
///
[JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)]
public DiscordInteractionData Data { get; internal set; }
///
/// Gets the Id of the guild that invoked this interaction.
///
[JsonIgnore]
public ulong? GuildId { get; internal set; }
///
/// Gets the guild that invoked this interaction.
///
[JsonIgnore]
public DiscordGuild Guild
=> (this.Discord as DiscordClient).InternalGetCachedGuild(this.GuildId);
///
/// Gets the Id of the channel that invoked this interaction.
///
[JsonIgnore]
public ulong ChannelId { get; internal set; }
///
/// Gets the channel that invoked this interaction.
///
[JsonIgnore]
public DiscordChannel Channel
=> (this.Discord as DiscordClient).InternalGetCachedChannel(this.ChannelId) ?? (DiscordChannel)(this.Discord as DiscordClient).InternalGetCachedThread(this.ChannelId) ?? (this.Guild == null ? new DiscordDmChannel { Id = this.ChannelId, Type = ChannelType.Private, Discord = this.Discord } : null);
///
/// Gets the user that invoked this interaction.
/// This can be cast to a if created in a guild.
///
[JsonIgnore]
public DiscordUser User { get; internal set; }
///
/// Gets the continuation token for responding to this interaction.
///
[JsonProperty("token")]
public string Token { get; internal set; }
///
/// Gets the version number for this interaction type.
///
[JsonProperty("version")]
public int Version { get; internal set; }
///
/// Gets the ID of the application that created this interaction.
///
[JsonProperty("application_id")]
public ulong ApplicationId { get; internal set; }
///
/// The message this interaction was created with, if any.
///
[JsonProperty("message")]
internal DiscordMessage Message { get; set; }
///
/// Gets the invoking user locale.
///
[JsonProperty("locale", NullValueHandling = NullValueHandling.Ignore)]
public string Locale { get; internal set; }
///
/// Gets the guild locale if applicable.
///
[JsonProperty("guild_locale", NullValueHandling = NullValueHandling.Ignore)]
public string GuildLocale { get; internal set; }
///
/// Creates a response to this interaction.
///
/// The type of the response.
/// The data, if any, to send.
- public Task CreateResponseAsync(InteractionResponseType type, DiscordInteractionResponseBuilder builder = null) =>
- this.Discord.ApiClient.CreateInteractionResponseAsync(this.Id, this.Token, type, builder);
+ public Task CreateResponseAsync(InteractionResponseType type, DiscordInteractionResponseBuilder builder = null)
+ => this.Discord.ApiClient.CreateInteractionResponseAsync(this.Id, this.Token, type, builder);
///
/// Creates a modal response to this interaction.
///
/// The data to send.
- public Task CreateInteractionModalResponseAsync(DiscordInteractionModalBuilder builder) =>
- this.Discord.ApiClient.CreateInteractionModalResponseAsync(this.Id, this.Token, InteractionResponseType.Modal, builder);
+ public Task CreateInteractionModalResponseAsync(DiscordInteractionModalBuilder builder)
+ => this.Type != InteractionType.Ping && this.Type != InteractionType.ModalSubmit ? this.Discord.ApiClient.CreateInteractionModalResponseAsync(this.Id, this.Token, InteractionResponseType.Modal, builder) : throw new NotSupportedException("You can't respond to an PING with a modal.");
///
/// Gets the original interaction response.
///
/// The origingal message that was sent. This does not work on ephemeral messages.
- public Task GetOriginalResponseAsync() =>
- this.Discord.ApiClient.GetOriginalInteractionResponseAsync(this.Discord.CurrentApplication.Id, this.Token);
+ public Task GetOriginalResponseAsync()
+ => this.Discord.ApiClient.GetOriginalInteractionResponseAsync(this.Discord.CurrentApplication.Id, this.Token);
///
/// Edits the original interaction response.
///
/// The webhook builder.
/// The edited .
public async Task EditOriginalResponseAsync(DiscordWebhookBuilder builder)
{
builder.Validate(isInteractionResponse: true);
if (builder._keepAttachments.HasValue && builder._keepAttachments.Value)
{
var attachments = this.Discord.ApiClient.GetOriginalInteractionResponseAsync(this.Discord.CurrentApplication.Id, this.Token).Result.Attachments;
if (attachments?.Count > 0)
{
builder._attachments.AddRange(attachments);
}
}
else if (builder._keepAttachments.HasValue)
{
builder._attachments.Clear();
}
return await this.Discord.ApiClient.EditOriginalInteractionResponseAsync(this.Discord.CurrentApplication.Id, this.Token, builder).ConfigureAwait(false);
}
///
/// Deletes the original interaction response.
/// >
- public Task DeleteOriginalResponseAsync() =>
- this.Discord.ApiClient.DeleteOriginalInteractionResponseAsync(this.Discord.CurrentApplication.Id, this.Token);
+ public Task DeleteOriginalResponseAsync()
+ => this.Discord.ApiClient.DeleteOriginalInteractionResponseAsync(this.Discord.CurrentApplication.Id, this.Token);
///
/// Creates a follow up message to this interaction.
///
/// The webhook builder.
/// The created .
public async Task CreateFollowupMessageAsync(DiscordFollowupMessageBuilder builder)
{
builder.Validate();
return await this.Discord.ApiClient.CreateFollowupMessageAsync(this.Discord.CurrentApplication.Id, this.Token, builder).ConfigureAwait(false);
}
///
/// Gets a follow up message.
///
/// The id of the follow up message.
- public Task GetFollowupMessageAsync(ulong messageId) =>
- this.Discord.ApiClient.GetFollowupMessageAsync(this.Discord.CurrentApplication.Id, this.Token, messageId);
+ public Task GetFollowupMessageAsync(ulong messageId)
+ => this.Discord.ApiClient.GetFollowupMessageAsync(this.Discord.CurrentApplication.Id, this.Token, messageId);
///
/// Edits a follow up message.
///
/// The id of the follow up message.
/// The webhook builder.
/// The edited .
public async Task EditFollowupMessageAsync(ulong messageId, DiscordWebhookBuilder builder)
{
builder.Validate(isFollowup: true);
if (builder._keepAttachments.HasValue && builder._keepAttachments.Value)
{
var attachments = this.Discord.ApiClient.GetFollowupMessageAsync(this.Discord.CurrentApplication.Id, this.Token, messageId).Result.Attachments;
if (attachments?.Count > 0)
{
builder._attachments.AddRange(attachments);
}
}
else if (builder._keepAttachments.HasValue)
{
builder._attachments.Clear();
}
return await this.Discord.ApiClient.EditFollowupMessageAsync(this.Discord.CurrentApplication.Id, this.Token, messageId, builder).ConfigureAwait(false);
}
///
/// Deletes a follow up message.
///
/// The id of the follow up message.
- public Task DeleteFollowupMessageAsync(ulong messageId) =>
- this.Discord.ApiClient.DeleteFollowupMessageAsync(this.Discord.CurrentApplication.Id, this.Token, messageId);
+ public Task DeleteFollowupMessageAsync(ulong messageId)
+ => this.Discord.ApiClient.DeleteFollowupMessageAsync(this.Discord.CurrentApplication.Id, this.Token, messageId);
}
}