/// <summary> /// Responds to this interaction with a set of choices. /// </summary> /// <param name="result"> /// The set of choices for the user to pick from. /// <remarks> /// A max of 25 choices are allowed. Passing <see langword="null"/> for this argument will show the executing user that /// there is no choices for their autocompleted input. /// </remarks> /// </param> /// <param name="options">The request options for this response.</param> /// <returns> /// A string that contains json to write back to the incoming http request. /// </returns> public string Respond(IEnumerable <AutocompleteResult> result, RequestOptions options = null) { if (!InteractionHelper.CanSendResponse(this)) { throw new TimeoutException($"Cannot respond to an interaction after {InteractionHelper.ResponseTimeLimit} seconds!"); } lock (_lock) { if (HasResponded) { throw new InvalidOperationException("Cannot respond twice to the same interaction"); } HasResponded = true; } var model = new API.InteractionResponse { Type = InteractionResponseType.ApplicationCommandAutocompleteResult, Data = new API.InteractionCallbackData { Choices = result.Any() ? result.Select(x => new API.ApplicationCommandOptionChoice { Name = x.Name, Value = x.Value }).ToArray() : Array.Empty <API.ApplicationCommandOptionChoice>() } }; return(SerializePayload(model)); }
/// <summary> /// Acknowledges this interaction with the <see cref="InteractionResponseType.DeferredChannelMessageWithSource"/>. /// </summary> /// <returns> /// A string that contains json to write back to the incoming http request. /// </returns> public override string Defer(bool ephemeral = false, RequestOptions options = null) { if (!InteractionHelper.CanSendResponse(this)) { throw new TimeoutException($"Cannot defer an interaction after {InteractionHelper.ResponseTimeLimit} seconds!"); } var response = new API.InteractionResponse { Type = InteractionResponseType.DeferredChannelMessageWithSource, Data = new API.InteractionCallbackData { Flags = ephemeral ? MessageFlags.Ephemeral : Optional <MessageFlags> .Unspecified } }; lock (_lock) { if (HasResponded) { throw new InvalidOperationException("Cannot respond or defer twice to the same interaction"); } } lock (_lock) { HasResponded = true; } return(SerializePayload(response)); }
/// <summary> /// Acknowledges this interaction with the <see cref="InteractionResponseType.ACKWithSource"/> /// </summary> /// <returns> /// A task that represents the asynchronous operation of acknowledging the interaction /// </returns> public async Task AcknowledgeAsync(RequestOptions options = null) { var response = new API.InteractionResponse() { Type = InteractionResponseType.ACKWithSource, }; await Discord.Rest.ApiClient.CreateInteractionResponse(response, this.Id, Token, options).ConfigureAwait(false); }
public string AcknowledgePing() { var model = new API.InteractionResponse() { Type = InteractionResponseType.Pong }; return(SerializePayload(model)); }
/// <summary> /// Responds to an Interaction. /// <para> /// If you have <see cref="DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use /// <see cref="FollowupAsync(string, bool, Embed, InteractionResponseType, AllowedMentions, RequestOptions)"/> instead. /// </para> /// </summary> /// <param name="text">The text of the message to be sent</param> /// <param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/></param> /// <param name="embed">A <see cref="Embed"/> to send with this response</param> /// <param name="Type">The type of response to this Interaction</param> /// <param name="allowedMentions">The allowed mentions for this response</param> /// <param name="options">The request options for this response</param> /// <returns> /// The <see cref="IMessage"/> sent as the response. If this is the first acknowledgement, it will return null; /// </returns> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="InvalidOperationException">The parameters provided were invalid or the token was invalid</exception> public async Task <IMessage> RespondAsync(string text = null, bool isTTS = false, Embed embed = null, InteractionResponseType Type = InteractionResponseType.ChannelMessageWithSource, AllowedMentions allowedMentions = null, RequestOptions options = null) { if (Type == InteractionResponseType.Pong) { throw new InvalidOperationException($"Cannot use {Type} on a send message function"); } if (!IsValidToken) { throw new InvalidOperationException("Interaction token is no longer valid"); } if (Discord.AlwaysAcknowledgeInteractions) { return(await FollowupAsync()); } 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."); // 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 response = new API.InteractionResponse() { Type = Type, Data = new API.InteractionApplicationCommandCallbackData(text) { AllowedMentions = allowedMentions?.ToModel(), Embeds = embed != null ? new API.Embed[] { embed.ToModel() } : Optional <API.Embed[]> .Unspecified, TTS = isTTS } }; await Discord.Rest.ApiClient.CreateInteractionResponse(response, this.Id, Token, options); return(null); }
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.IsSpecified && data.Content.Value == null) ? Optional <string> .Unspecified : 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 <UserProperties> .Unspecified, Id = command.User.Id, } }; } return(messageModel); } return(new API.Message { Id = interaction.Id, }); }