private async IAsyncEnumerable <AutoroleConfiguration> GetRelevantReactionAutoroles
        (
            AutoroleService autoroles,
            Cacheable <IUserMessage, ulong> message,
            SocketReaction?reaction = null
        )
        {
            var realMessage = await message.GetOrDownloadAsync();

            if (!(realMessage.Channel is ITextChannel textChannel))
            {
                yield break;
            }

            var guildAutoroles = (await autoroles.GetAutorolesAsync(textChannel.Guild)).ToList();

            if (guildAutoroles.Count == 0)
            {
                yield break;
            }

            foreach (var autorole in guildAutoroles)
            {
                var isRelevant = autorole.Conditions.Any
                                 (
                    c =>
                {
                    if (!(c is ReactionCondition reactionCondition))
                    {
                        return(false);
                    }

                    if (reactionCondition.MessageID != (long)realMessage.Id)
                    {
                        return(false);
                    }

                    if (reaction is null)
                    {
                        return(true);
                    }

                    if (reactionCondition.EmoteName != reaction.Emote.Name)
                    {
                        return(false);
                    }

                    return(true);
                }
                                 );

                if (isRelevant)
                {
                    yield return(autorole);
                }
            }
        }
    /// <inheritdoc />
    public async Task <Result> RespondAsync(IMessageReactionAdd gatewayEvent, CancellationToken ct = default)
    {
        if (!gatewayEvent.GuildID.IsDefined(out var guildID))
        {
            return(Result.FromSuccess());
        }

        var autoroles = await _autoroles.GetAutorolesAsync
                        (
            guildID,
            q => q
            .Where(a => a.IsEnabled)
            .Where
            (
                a => a.Conditions.Any
                (
                    c =>
                    c is ReactionCondition &&
                    ((ReactionCondition)c).MessageID == gatewayEvent.MessageID &&
                    ((ReactionCondition)c).ChannelID == gatewayEvent.ChannelID &&
                    ((ReactionCondition)c).EmoteName == gatewayEvent.Emoji.Name
                )
            ),
            ct
                        );

        var user = gatewayEvent.UserID;

        foreach (var autorole in autoroles)
        {
            using var transaction = TransactionFactory.Create();

            var updateAutorole = await _autoroleUpdates.UpdateAutoroleForUserAsync(autorole, guildID, user, ct);

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

            transaction.Complete();
        }

        return(Result.FromSuccess());
    }
Beispiel #3
0
    /// <inheritdoc />
    public async Task <Result> RespondAsync(IGuildMemberUpdate gatewayEvent, CancellationToken ct = default)
    {
        var guild = gatewayEvent.GuildID;

        var autoroles = await _autoroles.GetAutorolesAsync
                        (
            guild,
            q => q
            .Where(a => a.IsEnabled)
            .Where
            (
                a => a.Conditions.Any
                (
                    c =>
                    c.GetType() == typeof(RoleCondition)
                )
            ),
            ct
                        );

        foreach (var autorole in autoroles)
        {
            using var transaction = TransactionFactory.Create();

            var rolesToLookFor = autorole.Conditions
                                 .Where(c => c is RoleCondition)
                                 .Cast <RoleCondition>()
                                 .Select(c => c.RoleID);

            var userHasAutorole     = gatewayEvent.Roles.Contains(autorole.DiscordRoleID);
            var userHasRelevantRole = gatewayEvent.Roles.Any(r => rolesToLookFor.Contains(r));

            if (userHasAutorole || userHasRelevantRole)
            {
                var updateAutorole = await _autoroleUpdates.UpdateAutoroleForUserAsync
                                     (
                    autorole,
                    guild,
                    gatewayEvent.User.ID,
                    ct
                                     );

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

            transaction.Complete();
        }

        return(Result.FromSuccess());
    }
Beispiel #4
0
    public async Task <Result> ListAutorolesAsync()
    {
        var autoroles = await _autoroles.GetAutorolesAsync(_context.GuildID.Value, ct : this.CancellationToken);

        var pages = PaginatedEmbedFactory.SimpleFieldsFromCollection
                    (
            autoroles,
            at => $"<@&{at.DiscordRoleID}>",
            at => at.IsEnabled ? "Enabled" : "Disabled",
            "There are no autoroles configured."
                    );

        return((Result)await _feedback.SendContextualPaginatedMessageAsync
               (
                   _context.User.ID,
                   pages,
                   ct : this.CancellationToken
               ));
    }
Beispiel #5
0
    /// <inheritdoc />
    public async Task <Result> RespondAsync(IMessageCreate gatewayEvent, CancellationToken ct = default)
    {
        if (!gatewayEvent.GuildID.IsDefined(out var guildID))
        {
            return(Result.FromSuccess());
        }

        using var transaction = TransactionFactory.Create();

        var user = gatewayEvent.Author.ID;

        var getUserStatistics = await _statistics.GetOrCreateUserServerStatisticsAsync(guildID, user, ct);

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

        var userStatistics = getUserStatistics.Entity;
        var setTotalCount  = await _statistics.SetTotalMessageCountAsync
                             (
            userStatistics,
            (userStatistics.TotalMessageCount ?? 0) + 1,
            ct
                             );

        if (!setTotalCount.IsSuccess)
        {
            return(setTotalCount);
        }

        var channel = gatewayEvent.ChannelID;
        var getChannelStatistics = await _statistics.GetOrCreateUserChannelStatisticsAsync
                                   (
            guildID,
            user,
            channel,
            ct
                                   );

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

        var channelStatistics = getChannelStatistics.Entity;
        var setChannelCount   = await _statistics.SetChannelMessageCountAsync
                                (
            channelStatistics,
            (channelStatistics.MessageCount ?? 0) + 1,
            ct
                                );

        if (!setChannelCount.IsSuccess)
        {
            return(setChannelCount);
        }

        // Finally, update the relevant autoroles
        var autoroles = await _autoroles.GetAutorolesAsync
                        (
            guildID,
            q => q
            .Where(a => a.IsEnabled)
            .Where
            (
                a => a.Conditions.Any
                (
                    c =>
                    c.GetType() == typeof(MessageCountInGuildCondition) ||
                    c.GetType() == typeof(MessageCountInChannelCondition)
                )
            ),
            ct
                        );

        foreach (var autorole in autoroles)
        {
            var updateAutorole = await _autoroleUpdates.UpdateAutoroleForUserAsync(autorole, guildID, user, ct);

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

        transaction.Complete();
        return(Result.FromSuccess());
    }
    private async Task <Result> UpdateTimestampAndRelevantAutorolesAsync
    (
        Snowflake guild,
        Snowflake user,
        CancellationToken ct = default
    )
    {
        {
            using var timestampTransaction = TransactionFactory.Create(ReadCommitted);

            var getServerStatistics = await _statistics.GetOrCreateUserServerStatisticsAsync(guild, user, ct);

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

            var serverStatistics = getServerStatistics.Entity;

            var updateTimestamp = await _statistics.UpdateTimestampAsync(serverStatistics, ct);

            if (!updateTimestamp.IsSuccess)
            {
                return(updateTimestamp);
            }

            timestampTransaction.Complete();
        }

        var autoroles = await _autoroles.GetAutorolesAsync
                        (
            guild,
            q => q
            .Where(a => a.IsEnabled)
            .Where
            (
                a => a.Conditions.Any
                (
                    c =>
                    c.GetType() == typeof(TimeSinceLastActivityCondition) ||
                    c.GetType() == typeof(TimeSinceJoinCondition)
                )
            ),
            ct
                        );

        foreach (var autorole in autoroles)
        {
            using var transaction = TransactionFactory.Create();

            var updateAutorole = await _autoroleUpdates.UpdateAutoroleForUserAsync(autorole, guild, user, ct);

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

            transaction.Complete();
        }

        return(Result.FromSuccess());
    }