Ejemplo n.º 1
0
        public void Validate()
        {
            Preconditions.AtLeast(DeleteMessageDays, Ban.MinMessagePruneDays, nameof(DeleteMessageDays));
            Preconditions.AtMost(DeleteMessageDays, Ban.MaxMessagePruneDays, nameof(DeleteMessageDays));

            Preconditions.NotNullOrWhitespace(Reason, nameof(Reason));
        }
Ejemplo n.º 2
0
        /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
        public static async Task <RestUserMessage> SendMessageAsync(IMessageChannel channel, BaseDiscordClient client,
                                                                    string text, bool isTTS, Embed embed, AllowedMentions allowedMentions, MessageReferenceParams reference, RequestOptions options, InteractionRow[] components)
        {
            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));
                }
            }

            CreateMessageParams args = new CreateMessageParams(text)
            {
                IsTTS            = isTTS, Embed = embed?.ToModel(), AllowedMentions = allowedMentions?.ToModel(),
                MessageReference = reference?.ToModel(),
                Components       = components?.Select(x => x.ToModel()).ToArray()
            };

            //Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(args, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings { ContractResolver = new DiscordContractResolver() }));
            API.MessageJson model = await client.ApiClient.CreateMessageAsync(channel.Id, args, options).ConfigureAwait(false);

            return(RestUserMessage.Create(client, channel, client.CurrentUser, model));
        }
Ejemplo n.º 3
0
        public void Validate()
        {
            if (!Id.IsSpecified && !BroadcasterId.IsSpecified && !GameId.IsSpecified)
            {
                throw new ArgumentException($"At least one of the listed parameters must have a value for this request: {nameof(Id)}, {nameof(BroadcasterId)}, or {nameof(GameId)}");
            }

            if (Id.IsSpecified)
            {
                Preconditions.NotNullOrWhitespace(Id.ToString(), nameof(Id));
            }
            if (First.IsSpecified)
            {
                Preconditions.AtLeast(First, 1, nameof(First));
                Preconditions.AtMost(First, 100, nameof(First));
            }
            if (After.IsSpecified)
            {
                Preconditions.NotNullOrWhitespace(After.ToString(), nameof(After));
            }
            if (Before.IsSpecified)
            {
                Preconditions.NotNullOrWhitespace(Before.ToString(), nameof(Before));
            }
        }
Ejemplo n.º 4
0
 public void Validate()
 {
     Preconditions.NotNull(MessageIds, nameof(MessageIds));
     Preconditions.AtLeast(MessageIds.GetLength(0), Channel.MinBulkMessageDeleteAmount, nameof(MessageIds));
     Preconditions.AtMost(MessageIds.GetLength(0), Channel.MaxBulkMessageDeleteAmount, nameof(MessageIds));
     Preconditions.YoungerThan(MessageIds, TimeSpan.FromDays(14), nameof(MessageIds));
 }
Ejemplo n.º 5
0
        /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
        public static async Task<RestUserMessage> SendFileAsync(IMessageChannel channel, BaseDiscordClient client,
            Stream stream, string filename, string text, bool isTTS, Embed embed, AllowedMentions allowedMentions, RequestOptions options, bool isSpoiler)
        {
            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 args = new UploadFileParams(stream) { Filename = filename, Content = text, IsTTS = isTTS, Embed = embed?.ToModel() ?? Optional<API.Embed>.Unspecified, AllowedMentions = allowedMentions?.ToModel() ?? Optional<API.AllowedMentions>.Unspecified, IsSpoiler = isSpoiler };
            var model = await client.ApiClient.UploadFileAsync(channel.Id, args, options).ConfigureAwait(false);
            return RestUserMessage.Create(client, channel, client.CurrentUser, model);
        }
Ejemplo n.º 6
0
        public void Validate()
        {
            if (!VideoIds.IsSpecified && !UserId.IsSpecified && !GameId.IsSpecified)
            {
                throw new ArgumentException($"At least one of the following parameters must be specified: {nameof(VideoIds)}, {nameof(UserId)}, or {nameof(GameId)}");
            }

            if (VideoIds.IsSpecified)
            {
                Preconditions.CountGreaterThan(VideoIds, 100, nameof(VideoIds));
                Preconditions.CountLessThan(VideoIds, 1, nameof(VideoIds));
            }

            if (First.IsSpecified)
            {
                Preconditions.AtLeast(First, 1, nameof(First));
                Preconditions.AtMost(First, 100, nameof(First));
            }
            if (After.IsSpecified)
            {
                Preconditions.NotNullOrWhitespace(After.ToString(), nameof(After));
            }
            if (Before.IsSpecified)
            {
                Preconditions.NotNullOrWhitespace(Before.ToString(), nameof(Before));
            }
        }
        public static async Task <GuildApplicationCommandPermission> ModifyGuildCommandPermissionsAsync(BaseDiscordClient client, ulong guildId, ulong commandId,
                                                                                                        ApplicationCommandPermission[] args, RequestOptions options)
        {
            Preconditions.NotNull(args, nameof(args));
            Preconditions.AtMost(args.Length, 10, nameof(args));
            Preconditions.AtLeast(args.Length, 0, nameof(args));

            var permissionsList = new List <ApplicationCommandPermissions>();

            foreach (var arg in args)
            {
                var permissions = new ApplicationCommandPermissions
                {
                    Id         = arg.TargetId,
                    Permission = arg.Permission,
                    Type       = arg.TargetType
                };

                permissionsList.Add(permissions);
            }

            var model = new ModifyGuildApplicationCommandPermissionsParams
            {
                Permissions = permissionsList.ToArray()
            };

            var apiModel = await client.ApiClient.ModifyApplicationCommandPermissionsAsync(model, guildId, commandId, options);

            return(new GuildApplicationCommandPermission(apiModel.Id, apiModel.ApplicationId, guildId, apiModel.Permissions.Select(
                                                             x => new ApplicationCommandPermission(x.Id, x.Type, x.Permission)).ToArray()));
        }
        public static async Task <IReadOnlyCollection <GuildApplicationCommandPermission> > BatchEditGuildCommandPermissionsAsync(BaseDiscordClient client, ulong guildId,
                                                                                                                                  IDictionary <ulong, ApplicationCommandPermission[]> args, RequestOptions options)
        {
            Preconditions.NotNull(args, nameof(args));
            Preconditions.NotEqual(args.Count, 0, nameof(args));

            var models = new List <ModifyGuildApplicationCommandPermissions>();

            foreach (var arg in args)
            {
                Preconditions.AtMost(arg.Value.Length, 10, nameof(args));

                var model = new ModifyGuildApplicationCommandPermissions
                {
                    Id          = arg.Key,
                    Permissions = arg.Value.Select(x => new ApplicationCommandPermissions
                    {
                        Id         = x.TargetId,
                        Permission = x.Permission,
                        Type       = x.TargetType
                    }).ToArray()
                };

                models.Add(model);
            }

            var apiModels = await client.ApiClient.BatchModifyApplicationCommandPermissionsAsync(models.ToArray(), guildId, options);

            return(apiModels.Select(
                       x => new GuildApplicationCommandPermission(x.Id, x.ApplicationId, x.GuildId, x.Permissions.Select(
                                                                      y => new ApplicationCommandPermission(y.Id, y.Type, y.Permission)).ToArray())).ToArray());
        }
Ejemplo n.º 9
0
        /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
        public static async Task <RestUserMessage> SendMessageAsync(IMessageChannel channel, BaseDiscordClient client,
                                                                    string text, bool isTTS, Embed embed, AllowedMentions allowedMentions, MessageReference messageReference, RequestOptions options)
        {
            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 args = new CreateMessageParams(text)
            {
                IsTTS = isTTS, Embed = embed?.ToModel(), AllowedMentions = allowedMentions?.ToModel(), MessageReference = messageReference?.ToModel()
            };
            var model = await client.ApiClient.CreateMessageAsync(channel.Id, args, options).ConfigureAwait(false);

            return(RestUserMessage.Create(client, channel, client.CurrentUser, model));
        }
Ejemplo n.º 10
0
        public void Validate()
        {
            Preconditions.NotNegative(Limit, nameof(Limit));

            Preconditions.AtLeast(Limit, Guild.MinGetGuildsLimit, nameof(Limit));
            Preconditions.AtMost(Limit, Guild.MaxGetMembersLimit, nameof(Limit));
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Responds to an Interaction.
        /// </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="flags"></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, int?flags = 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");
            }

            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?.AllowedTypes != null)
            {
                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 callbackData = new InteractionApplicationCommandCallbackData(text)
            {
                TTS = isTTS
            };

            if (allowedMentions != null)
            {
                callbackData.AllowedMentions = allowedMentions.ToModel();
            }
            if (embed != null)
            {
                callbackData.Embeds = new[] { embed.ToModel() }
            }
            ;
            if (flags.HasValue)
            {
                callbackData.Flags = flags.Value;
            }

            var response = new InteractionResponse
            {
                Type = type,
                Data = callbackData
            };
            await Discord.Rest.ApiClient.CreateInteractionResponse(response, Id, Token, options).ConfigureAwait(false);

            return(null);
        }
        public static async Task <Message> ModifyInteractionResponseAsync(BaseDiscordClient client, string token, Action <MessageProperties> func,
                                                                          RequestOptions options = null)
        {
            var args = new MessageProperties();

            func(args);

            var embed  = args.Embed;
            var embeds = args.Embeds;

            bool hasText       = !string.IsNullOrEmpty(args.Content.GetValueOrDefault());
            bool hasEmbeds     = embed.IsSpecified && embed.Value != null || embeds.IsSpecified && embeds.Value?.Length > 0;
            bool hasComponents = args.Components.IsSpecified && args.Components.Value != null;

            if (!hasComponents && !hasText && !hasEmbeds)
            {
                Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content));
            }

            var apiEmbeds = embed.IsSpecified || embeds.IsSpecified ? new List <API.Embed>() : null;

            if (embed.IsSpecified && embed.Value != null)
            {
                apiEmbeds.Add(embed.Value.ToModel());
            }

            if (embeds.IsSpecified && embeds.Value != null)
            {
                apiEmbeds.AddRange(embeds.Value.Select(x => x.ToModel()));
            }

            Preconditions.AtMost(apiEmbeds?.Count ?? 0, 10, nameof(args.Embeds), "A max of 10 embeds are allowed.");

            if (!args.Attachments.IsSpecified)
            {
                var apiArgs = new ModifyInteractionResponseParams
                {
                    Content         = args.Content,
                    Embeds          = apiEmbeds?.ToArray() ?? Optional <API.Embed[]> .Unspecified,
                    AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value?.ToModel() : Optional <API.AllowedMentions> .Unspecified,
                    Components      = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional <API.ActionRowComponent[]> .Unspecified,
                    Flags           = args.Flags
                };

                return(await client.ApiClient.ModifyInteractionResponseAsync(apiArgs, token, options).ConfigureAwait(false));
            }
            else
            {
                var apiArgs = new UploadWebhookFileParams(args.Attachments.Value.ToArray())
                {
                    Content           = args.Content,
                    Embeds            = apiEmbeds?.ToArray() ?? Optional <API.Embed[]> .Unspecified,
                    AllowedMentions   = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value?.ToModel() : Optional <API.AllowedMentions> .Unspecified,
                    MessageComponents = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional <API.ActionRowComponent[]> .Unspecified,
                };

                return(await client.ApiClient.ModifyInteractionResponseAsync(apiArgs, token, options).ConfigureAwait(false));
            }
        }
Ejemplo n.º 13
0
 public void Validate()
 {
     if (Count.IsSpecified)
     {
         Preconditions.AtLeast(Count, 1, nameof(Count));
         Preconditions.AtMost(Count, 100, nameof(Count));
     }
 }
Ejemplo n.º 14
0
        public void Validate()
        {
            Preconditions.NotNullOrWhitespace(Name, nameof(Name));
            Preconditions.LengthAtLeast(Name, Guild.MinNameLength, nameof(Name));
            Preconditions.LengthAtMost(Name, Guild.MaxNameLength, nameof(Name));

            Preconditions.NotNullOrWhitespace(Region, nameof(Region));

            Preconditions.AtLeast(AfkTimeout, Channel.MinAfkTimeoutDuration, nameof(AfkTimeout));
            Preconditions.AtMost(AfkTimeout, Channel.MaxAFkTimeoutDuration, nameof(AfkTimeout));
        }
Ejemplo n.º 15
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.º 16
0
 public void Validate()
 {
     if (First.IsSpecified)
     {
         Preconditions.AtLeast(First, 1, nameof(First));
         Preconditions.AtMost(First, 100, nameof(First));
     }
     if (After.IsSpecified)
     {
         Preconditions.NotNullOrWhitespace(After.ToString(), nameof(After));
     }
 }
Ejemplo n.º 17
0
        /// <exception cref="InvalidOperationException">Only the author of a message may modify the message.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
        public static async Task <Model> ModifyAsync(IMessage msg, BaseDiscordClient client, Action <MessageProperties> func,
                                                     RequestOptions options)
        {
            var args = new MessageProperties();

            func(args);

            if (msg.Author.Id != client.CurrentUser.Id && (args.Content.IsSpecified || args.Embed.IsSpecified || args.AllowedMentions.IsSpecified))
            {
                throw new InvalidOperationException("Only the author of a message may modify the message content, embed, or allowed mentions.");
            }

            bool hasText  = args.Content.IsSpecified ? !string.IsNullOrEmpty(args.Content.Value) : !string.IsNullOrEmpty(msg.Content);
            bool hasEmbed = args.Embed.IsSpecified ? args.Embed.Value != null : msg.Embeds.Any();

            if (!hasText && !hasEmbed)
            {
                Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content));
            }

            if (args.AllowedMentions.IsSpecified)
            {
                AllowedMentions allowedMentions = args.AllowedMentions.Value;
                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 apiArgs = new API.Rest.ModifyMessageParams
            {
                Content         = args.Content,
                Embed           = args.Embed.IsSpecified ? args.Embed.Value.ToModel() : Optional.Create <API.Embed>(),
                Flags           = args.Flags.IsSpecified ? args.Flags.Value : Optional.Create <MessageFlags?>(),
                AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional.Create <API.AllowedMentions>(),
            };

            return(await client.ApiClient.ModifyMessageAsync(msg.Channel.Id, msg.Id, apiArgs, options).ConfigureAwait(false));
        }
Ejemplo n.º 18
0
        public static async Task <ulong> SendFilesAsync(DiscordWebhookClient client,
                                                        IEnumerable <FileAttachment> attachments, string text, bool isTTS, IEnumerable <Embed> embeds, string username,
                                                        string avatarUrl, AllowedMentions allowedMentions, MessageComponent components, RequestOptions options,
                                                        MessageFlags flags)
        {
            embeds ??= Array.Empty <Embed>();

            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.Count(), 10, nameof(embeds), "A max of 10 embeds are allowed.");

            foreach (var attachment in attachments)
            {
                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));
                }
            }

            if (flags is not MessageFlags.None and not MessageFlags.SuppressEmbeds)
            {
                throw new ArgumentException("The only valid MessageFlags are SuppressEmbeds and none.", nameof(flags));
            }

            var args = new UploadWebhookFileParams(attachments.ToArray())
            {
                AvatarUrl         = avatarUrl,
                Username          = username, Content = text,
                IsTTS             = isTTS,
                Embeds            = embeds.Any() ? embeds.Select(x => x.ToModel()).ToArray() : Optional <API.Embed[]> .Unspecified,
                AllowedMentions   = allowedMentions?.ToModel() ?? Optional <API.AllowedMentions> .Unspecified,
                MessageComponents = components?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional <API.ActionRowComponent[]> .Unspecified,
                Flags             = flags
            };
            var msg = await client.ApiClient.UploadWebhookFileAsync(client.Webhook.Id, args, options).ConfigureAwait(false);

            return(msg.Id);
        }
Ejemplo n.º 19
0
        public static async Task <RestUserMessage> SendInteractionFileAsync(IMessageChannel channel, BaseDiscordClient client,
                                                                            InteractionData interaction, Stream stream, string filename, string text, bool isTTS, Embed embed, AllowedMentions allowedMentions, RequestOptions options, bool isSpoiler, MessageReferenceParams reference, InteractionMessageType type, bool ghostMessage, InteractionRow[] components)
        {
            if (interaction == null)
            {
                return(await SendFileAsync(channel, client, stream, filename, text, isTTS, embed, allowedMentions, options, isSpoiler, reference, components).ConfigureAwait(false));
            }
            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));
                }
            }
            UploadInteractionFileParams args = new UploadInteractionFileParams
            {
                Type = type,
                Data = new UploadWebhookFileParams(stream)
                {
                    Filename = filename, Content = text, IsTTS = isTTS, AllowedMentions = allowedMentions?.ToModel() ?? Optional <API.AllowedMentions> .Unspecified, IsSpoiler = isSpoiler, Components = components?.Select(x => x.ToModel()).ToArray()
                }
            };

            if (embed != null)
            {
                args.Data.Embeds = new API.EmbedJson[] { embed.ToModel() }
            }
            ;

            if (ghostMessage)
            {
                args.Data.Flags = 64;
            }


            API.MessageJson model = await client.ApiClient.UploadInteractionFileAsync(channel.Id, interaction, args, options).ConfigureAwait(false);

            return(RestUserMessage.Create(client, channel, client.CurrentUser, model));
        }
 public void Validate()
 {
     Preconditions.NotNullOrWhitespace(Name, nameof(Name));
     Preconditions.LengthAtLeast(Name, Channel.MinChannelNameLength, nameof(Name));
     Preconditions.LengthAtMost(Name, Channel.MaxChannelNameLength, nameof(Name));
     Preconditions.NotNull(PermissionOverwrites, nameof(PermissionOverwrites));
     Preconditions.NotNull(Topic, nameof(Topic));
     Preconditions.LengthAtLeast(Topic, Channel.MinChannelTopicLength, nameof(Topic));
     Preconditions.LengthAtMost(Topic, Channel.MaxChannelTopicLength, nameof(Topic));
     Preconditions.AtLeast(Bitrate, Channel.MinBitrate, nameof(Bitrate));
     Preconditions.AtMost(Bitrate, Channel.MaxBitrate, nameof(Bitrate));
     Preconditions.AtLeast(UserLimit, Channel.MinUserLimit, nameof(UserLimit));
     Preconditions.AtMost(UserLimit, Channel.MaxUserLimit, nameof(UserLimit));
 }
Ejemplo n.º 21
0
        public static async Task ModifyMessageAsync(DiscordWebhookClient client, ulong messageId,
                                                    Action <WebhookMessageProperties> func, RequestOptions options)
        {
            var args = new WebhookMessageProperties();

            func(args);

            if (args.AllowedMentions.IsSpecified)
            {
                var allowedMentions = args.AllowedMentions.Value;
                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?.AllowedTypes != null)
                {
                    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 apiArgs = new ModifyWebhookMessageParams
            {
                Content = args.Content.IsSpecified ? args.Content.Value : Optional.Create <string>(),
                Embeds  =
                    args.Embeds.IsSpecified
                        ? args.Embeds.Value.Select(embed => embed.ToModel()).ToArray()
                        : Optional.Create <API.Embed[]>(),
                AllowedMentions = args.AllowedMentions.IsSpecified
                    ? args.AllowedMentions.Value.ToModel()
                    : Optional.Create <API.AllowedMentions>(),
                Components = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional <API.ActionRowComponent[]> .Unspecified,
            };

            await client.ApiClient.ModifyWebhookMessageAsync(client.Webhook.Id, messageId, apiArgs, options)
            .ConfigureAwait(false);
        }
Ejemplo n.º 22
0
        public void Validate()
        {
            if (!FromId.IsSpecified && !ToId.IsSpecified)
            {
                throw new ArgumentException($"At least one of the following parameters must be specified: {nameof(FromId)} or {nameof(ToId)}");
            }

            if (First.IsSpecified)
            {
                Preconditions.AtLeast(First, 20, nameof(First));
                Preconditions.AtMost(First, 100, nameof(First));
            }
            if (After.IsSpecified)
            {
                Preconditions.NotNullOrWhitespace(After.ToString(), nameof(After));
            }
        }
Ejemplo n.º 23
0
        public static async Task <Model> ModifyAsync(ulong channelId, ulong msgId, BaseDiscordClient client, Action <MessageProperties> func,
                                                     RequestOptions options)
        {
            var args = new MessageProperties();

            func(args);

            if ((args.Content.IsSpecified && string.IsNullOrEmpty(args.Content.Value)) && (args.Embed.IsSpecified && args.Embed.Value == null))
            {
                Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content));
            }

            if (args.AllowedMentions.IsSpecified)
            {
                AllowedMentions allowedMentions = args.AllowedMentions.Value;
                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 apiArgs = new API.Rest.ModifyMessageParams
            {
                Content         = args.Content,
                Embed           = args.Embed.IsSpecified ? args.Embed.Value.ToModel() : Optional.Create <API.Embed>(),
                Flags           = args.Flags.IsSpecified ? args.Flags.Value : Optional.Create <MessageFlags?>(),
                AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional.Create <API.AllowedMentions>(),
            };

            return(await client.ApiClient.ModifyMessageAsync(channelId, msgId, apiArgs, options).ConfigureAwait(false));
        }
Ejemplo n.º 24
0
        public static async Task <Discord.API.Message> ModifyFollowupMessageAsync(BaseDiscordClient client, RestFollowupMessage message, Action <MessageProperties> func,
                                                                                  RequestOptions options = null)
        {
            var args = new MessageProperties();

            func(args);

            var embed  = args.Embed;
            var embeds = args.Embeds;

            bool hasText       = args.Content.IsSpecified ? !string.IsNullOrEmpty(args.Content.Value) : !string.IsNullOrEmpty(message.Content);
            bool hasEmbeds     = embed.IsSpecified && embed.Value != null || embeds.IsSpecified && embeds.Value?.Length > 0 || message.Embeds.Any();
            bool hasComponents = args.Components.IsSpecified && args.Components.Value != null;

            if (!hasComponents && !hasText && !hasEmbeds)
            {
                Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content));
            }

            var apiEmbeds = embed.IsSpecified || embeds.IsSpecified ? new List <API.Embed>() : null;

            if (embed.IsSpecified && embed.Value != null)
            {
                apiEmbeds.Add(embed.Value.ToModel());
            }

            if (embeds.IsSpecified && embeds.Value != null)
            {
                apiEmbeds.AddRange(embeds.Value.Select(x => x.ToModel()));
            }

            Preconditions.AtMost(apiEmbeds?.Count ?? 0, 10, nameof(args.Embeds), "A max of 10 embeds are allowed.");

            var apiArgs = new ModifyInteractionResponseParams
            {
                Content         = args.Content,
                Embeds          = apiEmbeds?.ToArray() ?? Optional <API.Embed[]> .Unspecified,
                AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional <API.AllowedMentions> .Unspecified,
                Components      = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional <API.ActionRowComponent[]> .Unspecified
            };

            return(await client.ApiClient.ModifyInteractionFollowupMessageAsync(apiArgs, message.Id, message.Token, options).ConfigureAwait(false));
        }
Ejemplo n.º 25
0
        /// <summary>
        ///     Adds an option to the current slash command.
        /// </summary>
        /// <param name="Name">The name of the option to add.</param>
        /// <param name="Type">The type of this option.</param>
        /// <param name="Description">The description of this option.</param>
        /// <param name="Required">If this option is required for this command.</param>
        /// <param name="Default">If this option is the default option.</param>
        /// <param name="Options">The options of the option to add.</param>
        /// <param name="Choices">The choices of this option.</param>
        /// <returns>The current builder.</returns>
        public SlashCommandBuilder AddOption(string Name, ApplicationCommandOptionType Type,
                                             string Description, bool Required = true, bool Default = false, List <SlashCommandOptionBuilder> Options = null, params ApplicationCommandOptionChoiceProperties[] Choices)
        {
            // Make sure the name matches the requirements from discord
            Preconditions.NotNullOrEmpty(Name, nameof(Name));
            Preconditions.AtLeast(Name.Length, 3, nameof(Name));
            Preconditions.AtMost(Name.Length, MaxNameLength, nameof(Name));

            // Discord updated the docs, this regex prevents special characters like @!$%( and s p a c e s.. etc,
            // https://discord.com/developers/docs/interactions/slash-commands#applicationcommand
            if (!Regex.IsMatch(Name, @"^[\w-]{3,32}$"))
            {
                throw new ArgumentException("Command name cannot contian any special characters or whitespaces!", nameof(Name));
            }

            // same with description
            Preconditions.NotNullOrEmpty(Description, nameof(Description));
            Preconditions.AtLeast(Description.Length, 3, nameof(Description));
            Preconditions.AtMost(Description.Length, MaxDescriptionLength, nameof(Description));

            // make sure theres only one option with default set to true
            if (Default)
            {
                if (this.Options != null)
                {
                    if (this.Options.Any(x => x.Default))
                    {
                        throw new ArgumentException("There can only be one command option with default set to true!", nameof(Default));
                    }
                }
            }

            SlashCommandOptionBuilder option = new SlashCommandOptionBuilder();

            option.Name        = Name;
            option.Description = Description;
            option.Required    = Required;
            option.Default     = Default;
            option.Options     = Options;
            option.Choices     = Choices != null ? new List <ApplicationCommandOptionChoiceProperties>(Choices) : null;

            return(AddOption(option));
        }
Ejemplo n.º 26
0
        public void Validate()
        {
            if (CommunityIds.IsSpecified)
            {
                Preconditions.CountGreaterThan(CommunityIds, 100, nameof(CommunityIds));
                Preconditions.CountLessThan(CommunityIds, 1, nameof(CommunityIds));
            }
            if (GameIds.IsSpecified)
            {
                Preconditions.CountGreaterThan(GameIds, 100, nameof(GameIds));
                Preconditions.CountLessThan(GameIds, 1, nameof(GameIds));
            }
            if (Languages.IsSpecified)
            {
                Preconditions.CountGreaterThan(Languages, 100, nameof(Languages));
                Preconditions.CountLessThan(Languages, 1, nameof(Languages));
            }
            if (UserIds.IsSpecified)
            {
                Preconditions.CountGreaterThan(UserIds, 100, nameof(UserIds));
                Preconditions.CountLessThan(UserIds, 1, nameof(UserIds));
            }
            if (UserNames.IsSpecified)
            {
                Preconditions.CountGreaterThan(UserNames, 100, nameof(UserNames));
                Preconditions.CountLessThan(UserNames, 1, nameof(UserNames));
            }

            if (First.IsSpecified)
            {
                Preconditions.AtLeast(First, 1, nameof(First));
                Preconditions.AtMost(First, 100, nameof(First));
            }
            if (After.IsSpecified)
            {
                Preconditions.NotNullOrWhitespace(After.ToString(), nameof(After));
            }
            if (Before.IsSpecified)
            {
                Preconditions.NotNullOrWhitespace(Before.ToString(), nameof(Before));
            }
        }
        public static async Task <ApplicationCommand> ModifyGlobalCommandAsync(BaseDiscordClient client, IApplicationCommand command,
                                                                               ApplicationCommandProperties args, RequestOptions options = null)
        {
            if (args.Name.IsSpecified)
            {
                Preconditions.AtMost(args.Name.Value.Length, 32, nameof(args.Name));
                Preconditions.AtLeast(args.Name.Value.Length, 1, nameof(args.Name));
            }

            var model = new ModifyApplicationCommandParams
            {
                Name = args.Name,
                DefaultPermission = args.IsDefaultPermission.IsSpecified
                        ? args.IsDefaultPermission.Value
                        : Optional <bool> .Unspecified
            };

            if (args is SlashCommandProperties slashProps)
            {
                if (slashProps.Description.IsSpecified)
                {
                    Preconditions.AtMost(slashProps.Description.Value.Length, 100, nameof(slashProps.Description));
                    Preconditions.AtLeast(slashProps.Description.Value.Length, 1, nameof(slashProps.Description));
                }

                if (slashProps.Options.IsSpecified)
                {
                    if (slashProps.Options.Value.Count > 10)
                    {
                        throw new ArgumentException("Option count must be 10 or less");
                    }
                }

                model.Description = slashProps.Description;

                model.Options = slashProps.Options.IsSpecified
                    ? slashProps.Options.Value.Select(x => new ApplicationCommandOption(x)).ToArray()
                    : Optional <ApplicationCommandOption[]> .Unspecified;
            }

            return(await client.ApiClient.ModifyGlobalApplicationCommandAsync(model, command.Id, options).ConfigureAwait(false));
        }
Ejemplo n.º 28
0
        public static Task SendAutocompleteResultAsync(BaseDiscordClient client, IEnumerable<AutocompleteResult> result, ulong interactionId,
            string interactionToken, RequestOptions options)
        {
            result ??= Array.Empty<AutocompleteResult>();

            Preconditions.AtMost(result.Count(), 25, nameof(result), "A maximum of 25 choices are allowed!");

            var apiArgs = new InteractionResponse
            {
                Type = InteractionResponseType.ApplicationCommandAutocompleteResult,
                Data = new InteractionCallbackData
                {
                    Choices = result.Any()
                        ? result.Select(x => new ApplicationCommandOptionChoice { Name = x.Name, Value = x.Value }).ToArray()
                        : Array.Empty<ApplicationCommandOptionChoice>()
                }
            };

            return client.ApiClient.CreateInteractionResponseAsync(apiArgs, interactionId, interactionToken, options);
        }
Ejemplo n.º 29
0
        public void Validate()
        {
            int specified = 0;

            if (UserId.IsSpecified)
            {
                specified++;
                Preconditions.NotZero(UserId, nameof(UserId));
            }
            if (VideoId.IsSpecified)
            {
                specified++;
                Preconditions.NotZero(VideoId, nameof(VideoId));
            }

            if (specified > 1)
            {
                throw new ArgumentException($"Only one of {nameof(UserId)} or {nameof(VideoId)} can be specified for this request.");
            }
            if (specified == 0)
            {
                throw new ArgumentException($"Either {nameof(UserId)} or {nameof(VideoId)} must be specified for this request.");
            }

            if (First.IsSpecified)
            {
                Preconditions.AtLeast(First, 1, nameof(First));
                Preconditions.AtMost(First, 100, nameof(First));
            }
            if (After.IsSpecified)
            {
                Preconditions.NotNullOrWhitespace(After.ToString(), nameof(After));
            }
            if (Before.IsSpecified)
            {
                Preconditions.NotNullOrWhitespace(Before.ToString(), nameof(Before));
            }
        }
Ejemplo n.º 30
0
        public static async Task <Model> ModifyAsync(ulong channelId, ulong msgId, BaseDiscordClient client, Action <MessageProperties> func,
                                                     RequestOptions options)
        {
            var args = new MessageProperties();

            func(args);

            var embed  = args.Embed;
            var embeds = args.Embeds;

            bool hasText        = args.Content.IsSpecified && string.IsNullOrEmpty(args.Content.Value);
            bool hasEmbeds      = embed.IsSpecified && embed.Value != null || embeds.IsSpecified && embeds.Value?.Length > 0;
            bool hasComponents  = args.Components.IsSpecified && args.Components.Value != null;
            bool hasAttachments = args.Attachments.IsSpecified;
            bool hasFlags       = args.Flags.IsSpecified;

            // No content needed if modifying flags
            if ((!hasComponents && !hasText && !hasEmbeds && !hasAttachments) && !hasFlags)
            {
                Preconditions.NotNullOrEmpty(args.Content.IsSpecified ? args.Content.Value : string.Empty, nameof(args.Content));
            }

            if (args.AllowedMentions.IsSpecified)
            {
                AllowedMentions allowedMentions = args.AllowedMentions.Value;
                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 apiEmbeds = embed.IsSpecified || embeds.IsSpecified ? new List <API.Embed>() : null;

            if (embed.IsSpecified && embed.Value != null)
            {
                apiEmbeds.Add(embed.Value.ToModel());
            }

            if (embeds.IsSpecified && embeds.Value != null)
            {
                apiEmbeds.AddRange(embeds.Value.Select(x => x.ToModel()));
            }

            Preconditions.AtMost(apiEmbeds?.Count ?? 0, 10, nameof(args.Embeds), "A max of 10 embeds are allowed.");

            if (!args.Attachments.IsSpecified)
            {
                var apiArgs = new API.Rest.ModifyMessageParams
                {
                    Content         = args.Content,
                    Embeds          = apiEmbeds?.ToArray() ?? Optional <API.Embed[]> .Unspecified,
                    Flags           = args.Flags.IsSpecified ? args.Flags.Value : Optional.Create <MessageFlags?>(),
                    AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional.Create <API.AllowedMentions>(),
                    Components      = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Array.Empty <API.ActionRowComponent>() : Optional <API.ActionRowComponent[]> .Unspecified,
                };
                return(await client.ApiClient.ModifyMessageAsync(channelId, msgId, apiArgs, options).ConfigureAwait(false));
            }
            else
            {
                var apiArgs = new UploadFileParams(args.Attachments.Value.ToArray())
                {
                    Content          = args.Content,
                    Embeds           = apiEmbeds?.ToArray() ?? Optional <API.Embed[]> .Unspecified,
                    Flags            = args.Flags.IsSpecified ? args.Flags.Value : Optional.Create <MessageFlags?>(),
                    AllowedMentions  = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value.ToModel() : Optional.Create <API.AllowedMentions>(),
                    MessageComponent = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Array.Empty <API.ActionRowComponent>() : Optional <API.ActionRowComponent[]> .Unspecified
                };

                return(await client.ApiClient.ModifyMessageAsync(channelId, msgId, apiArgs, options).ConfigureAwait(false));
            }
        }