public async Task <IResult> ListNotesAsync(IUser user)
    {
        var notes = await _notes.GetNotesAsync(_context.GuildID.Value, user.ID);

        var createPages = await PaginatedEmbedFactory.PagesFromCollectionAsync
                          (
            notes,
            async note =>
        {
            var getAuthor = await _userAPI.GetUserAsync(note.Author.DiscordID);
            if (!getAuthor.IsSuccess)
            {
                return(Result <Embed> .FromError(getAuthor));
            }

            var author = getAuthor.Entity;

            var getAuthorAvatar = CDN.GetUserAvatarUrl(author);

            var embedFields = new List <EmbedField>();
            var eb          = new Embed
            {
                Title  = $"Note #{note.ID} for {user.Username}:{user.Discriminator}",
                Colour = Color.Gold,
                Author = new EmbedAuthor(author.Username)
                {
                    IconUrl = getAuthorAvatar.IsSuccess
                            ? getAuthorAvatar.Entity.ToString()
                            : default(Optional <string>)
                },
                Description = note.Content,
                Fields      = embedFields
            };

            embedFields.Add(new EmbedField("Created", note.CreatedAt.Humanize()));

            if (note.CreatedAt != note.UpdatedAt)
            {
                embedFields.Add(new EmbedField("Last Updated", note.UpdatedAt.Humanize()));
            }

            return(eb);
        }
                          );

        if (createPages.Any(p => !p.IsSuccess))
        {
            return(createPages.First(p => !p.IsSuccess));
        }

        var pages = createPages.Select(p => p.Entity).ToList();

        return((Result)await _feedback.SendContextualPaginatedMessageAsync
               (
                   _context.User.ID,
                   pages,
                   ct : this.CancellationToken
               ));
    }
        /// <inheritdoc />
        public override async ValueTask <Result <IUser> > TryParse(string value, CancellationToken ct)
        {
            if (!Snowflake.TryParse(value.Unmention(), out var userID))
            {
                return(new ParsingError <IUser>(value.Unmention()));
            }

            return(await _userAPI.GetUserAsync(userID.Value, ct));
        }
        /// <inheritdoc />
        public override async ValueTask <RetrieveEntityResult <IUser> > TryParse(string value, CancellationToken ct)
        {
            if (!Snowflake.TryParse(value.Unmention(), out var userID))
            {
                return(RetrieveEntityResult <IUser> .FromError($"Failed to parse \"{value}\" as a user ID."));
            }

            var getUser = await _userAPI.GetUserAsync(userID.Value, ct);

            if (!getUser.IsSuccess)
            {
                return(RetrieveEntityResult <IUser> .FromError(getUser));
            }

            return(getUser.IsSuccess
                ? RetrieveEntityResult <IUser> .FromSuccess(getUser.Entity)
                : RetrieveEntityResult <IUser> .FromError("No user with that ID could be found."));
        }
    /// <summary>
    /// Posts a notification that a message was deleted.
    /// </summary>
    /// <param name="message">The deleted message.</param>
    /// <param name="guildID">The ID of the guild in which the message was.</param>
    /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
    public async Task <Result> NotifyMessageDeletedAsync(IMessage message, Snowflake guildID)
    {
        // We don't care about bot messages
        var isNonFeedbackMessage = (message.Author.IsBot.IsDefined(out var isBot) && isBot) ||
                                   (message.Author.IsSystem.IsDefined(out var isSystem) && isSystem);

        if (isNonFeedbackMessage)
        {
            return(Result.FromSuccess());
        }

        var getChannel = await GetMonitoringChannelAsync(guildID);

        if (!getChannel.IsSuccess)
        {
            return(Result.FromError(getChannel));
        }

        var getSelf = await _userAPI.GetCurrentUserAsync();

        if (!getSelf.IsSuccess)
        {
            return(Result.FromError(getSelf));
        }

        var self    = getSelf.Entity;
        var channel = getChannel.Entity;

        var eb = new Embed
        {
            Colour = _feedback.Theme.Warning,
            Title  = "Message Deleted"
        };

        var getGuildRoles = await _guildAPI.GetGuildRolesAsync(guildID);

        if (!getGuildRoles.IsSuccess)
        {
            return(Result.FromError(getGuildRoles));
        }

        var guildRoles   = getGuildRoles.Entity;
        var everyoneRole = guildRoles.First(r => r.ID == guildID);

        var getGuildMember = await _guildAPI.GetGuildMemberAsync(guildID, self.ID);

        if (!getGuildMember.IsSuccess)
        {
            return(Result.FromError(getGuildMember));
        }

        var botGuildMember = getGuildMember.Entity;
        var botRoles       = guildRoles.Where(r => botGuildMember.Roles.Contains(r.ID)).ToList();

        var botPermissions = DiscordPermissionSet.ComputePermissions
                             (
            self.ID,
            everyoneRole,
            botRoles
                             );

        var extra = string.Empty;

        if (botPermissions.HasPermission(DiscordPermission.ViewAuditLog))
        {
            var getMostProbableDeleter = await FindMostProbableDeleterAsync(message, guildID);

            if (!getMostProbableDeleter.IsSuccess)
            {
                return(Result.FromError(getMostProbableDeleter));
            }

            var userID  = getMostProbableDeleter.Entity;
            var getUser = await _userAPI.GetUserAsync(userID);

            if (!getUser.IsSuccess)
            {
                return(Result.FromError(getUser));
            }

            var mostProbableDeleter = getUser.Entity;

            var isNonUserDeleter = (mostProbableDeleter.IsBot.IsDefined(out var isDeleterBot) && isDeleterBot) ||
                                   (mostProbableDeleter.IsSystem.IsDefined(out var isDeleterSystem) && isDeleterSystem);

            // We don't care about bot deletions
            if (!isNonUserDeleter)
            {
                extra = $" (probably) by <@{mostProbableDeleter.ID}>";
            }
        }

        eb = eb with
        {
            Description = $"A message was deleted from <#{message.ChannelID}>{extra}."
        };

        var quote = QuoteService.CreateMessageQuote(message, self.ID);

        var sendResult = await _feedback.SendEmbedAsync(channel, eb);

        if (!sendResult.IsSuccess)
        {
            return(Result.FromError(sendResult));
        }

        sendResult = await _feedback.SendEmbedAsync(channel, quote);

        return(sendResult.IsSuccess
            ? Result.FromSuccess()
            : Result.FromError(sendResult));
    }
Beispiel #5
0
    public async Task <IResult> ListBansAsync()
    {
        var bans = await _bans.GetBansAsync(_context.GuildID.Value);

        var createPages = await PaginatedEmbedFactory.PagesFromCollectionAsync
                          (
            bans,
            async ban =>
        {
            var getBanAuthor = await _userAPI.GetUserAsync(ban.Author.DiscordID);
            if (!getBanAuthor.IsSuccess)
            {
                return(Result <Embed> .FromError(getBanAuthor));
            }

            var banAuthor = getBanAuthor.Entity;

            var getBannedUser = await _userAPI.GetUserAsync(ban.User.DiscordID);
            if (!getBannedUser.IsSuccess)
            {
                return(Result <Embed> .FromError(getBannedUser));
            }

            var bannedUser = getBanAuthor.Entity;

            var getBanAuthorAvatar = CDN.GetUserAvatarUrl(banAuthor);

            var embedFields = new List <IEmbedField>();
            var eb          = new Embed
            {
                Title  = $"Ban #{ban.ID} for {bannedUser.Username}:{bannedUser.Discriminator}",
                Colour = Color.Orange,
                Author = new EmbedAuthor(banAuthor.Username)
                {
                    Url = getBanAuthorAvatar.IsSuccess
                            ? getBanAuthorAvatar.Entity.ToString()
                            : default(Optional <string>)
                },
                Description = ban.Reason,
                Fields      = embedFields
            };

            embedFields.Add(new EmbedField("Created", ban.CreatedAt.Humanize()));

            if (ban.CreatedAt != ban.UpdatedAt)
            {
                embedFields.Add(new EmbedField("Last Updated", ban.UpdatedAt.Humanize()));
            }

            if (ban.ExpiresOn.HasValue)
            {
                embedFields.Add(new EmbedField("Expires On", ban.ExpiresOn.Humanize()));
            }

            if (ban.MessageID is not null)
            {
                // TODO
            }

            return(eb);
        }
                          );

        if (createPages.Any(p => !p.IsSuccess))
        {
            return(createPages.First(p => !p.IsSuccess));
        }

        var pages = createPages.Select(p => p.Entity).ToList();

        return((Result)await _feedback.SendContextualPaginatedMessageAsync
               (
                   _context.User.ID,
                   pages,
                   ct : this.CancellationToken
               ));
    }