using Discord.Rest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model = Discord.API.Interaction;
namespace Discord.WebSocket
{
///
/// Represents an Interaction recieved over the gateway.
///
public abstract class SocketInteraction : SocketEntity, IDiscordInteraction
{
///
/// The this interaction was used in.
///
public ISocketMessageChannel Channel { get; private set; }
///
/// The who triggered this interaction.
///
public SocketUser User { get; private set; }
///
/// The type of this interaction.
///
public InteractionType Type { get; private set; }
///
/// The token used to respond to this interaction.
///
public string Token { get; private set; }
///
/// The data sent with this interaction.
///
public IDiscordInteractionData Data { get; private set; }
///
/// The version of this interaction.
///
public int Version { get; private set; }
public DateTimeOffset CreatedAt { get; }
///
/// if the token is valid for replying to, otherwise .
///
public bool IsValidToken
=> CheckToken();
private ulong? GuildId { get; set; }
private ulong? ChannelId { get; set; }
internal SocketInteraction(DiscordSocketClient client, ulong id, ISocketMessageChannel channel)
: base(client, id)
{
this.Channel = channel;
}
internal static SocketInteraction Create(DiscordSocketClient client, Model model, ISocketMessageChannel channel)
{
if (model.Type == InteractionType.ApplicationCommand)
return SocketSlashCommand.Create(client, model, channel);
if (model.Type == InteractionType.MessageComponent)
return SocketMessageComponent.Create(client, model, channel);
else
return null;
}
internal virtual void Update(Model model)
{
this.Data = model.Data.IsSpecified
? model.Data.Value
: null;
this.GuildId = model.GuildId.ToNullable();
this.ChannelId = model.ChannelId.ToNullable();
this.Token = model.Token;
this.Version = model.Version;
this.Type = model.Type;
if (this.User == null)
{
if (model.Member.IsSpecified && model.GuildId.IsSpecified)
{
this.User = SocketGuildUser.Create(Discord.State.GetGuild(this.GuildId.Value), Discord.State, model.Member.Value);
}
else
{
this.User = SocketGlobalUser.Create(this.Discord, this.Discord.State, model.User.Value);
}
}
}
///
/// Responds to an Interaction.
///
/// If you have set to , You should use
/// instead.
///
///
/// The text of the message to be sent.
/// if the message should be read out by a text-to-speech reader, otherwise .
/// A to send with this response.
/// The type of response to this Interaction.
/// 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
/// 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, bool isTTS = false, Embed embed = null, InteractionResponseType type = InteractionResponseType.ChannelMessageWithSource,
bool ephemeral = false, AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null);
///
/// Sends a followup message for this interaction.
///
/// The text of the message to be sent
/// if the message should be read out by a text-to-speech reader, otherwise .
/// A to send with this response.
/// The type of response to this Interaction.
/// /// 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
///
/// The sent message.
///
public abstract Task FollowupAsync(string text = null, bool isTTS = false, Embed embed = null, bool ephemeral = false,
InteractionResponseType type = InteractionResponseType.ChannelMessageWithSource,
AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent component = null);
///
/// Gets the original response for this interaction.
///
/// The request options for this async request.
/// A that represents the intitial response, or if there is no response.
public Task GetOriginalResponseAsync(RequestOptions options = null)
{
return InteractionHelper.GetOriginalResponseAsync(this.Discord, this.Channel, this, options);
}
///
/// Acknowledges this interaction with the .
///
///
/// A task that represents the asynchronous operation of acknowledging the interaction.
///
public virtual Task AcknowledgeAsync(RequestOptions options = null)
{
var response = new API.InteractionResponse()
{
Type = InteractionResponseType.DeferredChannelMessageWithSource,
};
return Discord.Rest.ApiClient.CreateInteractionResponse(response, this.Id, this.Token, options);
}
private bool CheckToken()
{
// Tokens last for 15 minutes according to https://discord.com/developers/docs/interactions/slash-commands#responding-to-an-interaction
return (DateTime.UtcNow - this.CreatedAt.UtcDateTime).TotalMinutes >= 15d;
}
}
}