Ejemplo n.º 1
0
        /// <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));
        }
Ejemplo n.º 2
0
        /// <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));
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        public string AcknowledgePing()
        {
            var model = new API.InteractionResponse()
            {
                Type = InteractionResponseType.Pong
            };

            return(SerializePayload(model));
        }
Ejemplo n.º 5
0
        /// <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);
        }
Ejemplo n.º 6
0
        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,
            });
        }