private async Task <OperationResult> NotifyUserNeedsAffirmation
        (
            AutoroleService autoroles,
            SocketGuild guild,
            AutoroleConfiguration autorole,
            IUser user
        )
        {
            var getAutoroleConfirmation = await autoroles.GetOrCreateAutoroleConfirmationAsync(autorole, user);

            if (!getAutoroleConfirmation.IsSuccess)
            {
                return(OperationResult.FromError(getAutoroleConfirmation));
            }

            var autoroleConfirmation = getAutoroleConfirmation.Entity;

            if (autoroleConfirmation.HasNotificationBeenSent)
            {
                return(OperationResult.FromSuccess());
            }

            var getSettings = await autoroles.GetOrCreateServerSettingsAsync(guild);

            if (!getSettings.IsSuccess)
            {
                return(OperationResult.FromError(getSettings));
            }

            var settings = getSettings.Entity;

            var notificationChannelID = settings.AffirmationRequiredNotificationChannelID;

            if (notificationChannelID is null)
            {
                return(OperationResult.FromError("There's no notification channel set."));
            }

            var notificationChannel = guild.GetTextChannel((ulong)notificationChannelID.Value);

            if (notificationChannel is null)
            {
                return(OperationResult.FromError("The notification channel is set, but does not exist."));
            }

            var embed = _feedback.CreateEmbedBase()
                        .WithTitle("Confirmation Required")
                        .WithDescription
                        (
                $"{MentionUtils.MentionUser(user.Id)} has met the requirements for the " +
                $"{MentionUtils.MentionRole((ulong)autorole.DiscordRoleID)} role.\n" +
                $"\n" +
                $"Use \"!at affirm {MentionUtils.MentionRole((ulong)autorole.DiscordRoleID)} " +
                $"{MentionUtils.MentionUser(user.Id)}\" to affirm and give the user the role."
                        )
                        .WithColor(Color.Green);

            try
            {
                await _feedback.SendEmbedAsync(notificationChannel, embed.Build());

                var setResult = await autoroles.SetHasNotificationBeenSentAsync(autoroleConfirmation, true);

                if (!setResult.IsSuccess)
                {
                    return(OperationResult.FromError(setResult));
                }
            }
            catch (HttpException hex) when(hex.WasCausedByMissingPermission())
            {
                return(OperationResult.FromError(hex));
            }

            return(OperationResult.FromSuccess());
        }
示例#2
0
        private async Task NotifyUserNeedsAffirmation
        (
            AutoroleService autoroles,
            AutoroleConfiguration autorole,
            IGuildUser user
        )
        {
            var getAutoroleConfirmation = await autoroles.GetOrCreateAutoroleConfirmationAsync(autorole, user);

            if (!getAutoroleConfirmation.IsSuccess)
            {
                this.Log.LogError(getAutoroleConfirmation.Exception, getAutoroleConfirmation.ErrorReason);
                return;
            }

            var autoroleConfirmation = getAutoroleConfirmation.Entity;

            if (autoroleConfirmation.HasNotificationBeenSent)
            {
                return;
            }

            var getSettings = await autoroles.GetOrCreateServerSettingsAsync(user.Guild);

            if (!getSettings.IsSuccess)
            {
                this.Log.LogError(getSettings.Exception, getSettings.ErrorReason);
                return;
            }

            var settings = getSettings.Entity;

            var notificationChannelID = settings.AffirmationRequiredNotificationChannelID;

            if (notificationChannelID is null)
            {
                return;
            }

            var notificationChannel = await user.Guild.GetTextChannelAsync((ulong)notificationChannelID.Value);

            if (notificationChannel is null)
            {
                return;
            }

            var embed = _feedback.CreateEmbedBase()
                        .WithTitle("Confirmation Required")
                        .WithDescription
                        (
                $"{MentionUtils.MentionUser(user.Id)} has met the requirements for the " +
                $"{MentionUtils.MentionRole((ulong)autorole.DiscordRoleID)} role.\n" +
                $"\n" +
                $"Use \"!at affirm {MentionUtils.MentionRole((ulong)autorole.DiscordRoleID)} " +
                $"{MentionUtils.MentionUser(user.Id)}\" to affirm and give the user the role."
                        )
                        .WithColor(Color.Green);

            try
            {
                await _feedback.SendEmbedAsync(notificationChannel, embed.Build());

                autoroleConfirmation.HasNotificationBeenSent = true;
                await autoroles.SaveChangesAsync();
            }
            catch (HttpException hex) when(hex.WasCausedByMissingPermission())
            {
            }
        }
示例#3
0
    /// <summary>
    /// Applies the given autorole to the given user, if it is applicable. If the user no longer qualifies,
    /// the autorole is removed.
    /// </summary>
    /// <param name="autorole">The autorole.</param>
    /// <param name="guildID">The ID of the guild the user is on.</param>
    /// <param name="userID">The ID of the user.</param>
    /// <param name="ct">The cancellation token in use.</param>
    /// <returns>A modification result which may or may not have succeeded.</returns>
    public async Task <Result <AutoroleUpdateStatus> > UpdateAutoroleForUserAsync
    (
        AutoroleConfiguration autorole,
        Snowflake guildID,
        Snowflake userID,
        CancellationToken ct = default
    )
    {
        if (!autorole.IsEnabled)
        {
            return(Disabled);
        }

        if (!autorole.Conditions.Any())
        {
            return(Unconditional);
        }

        var getRoles = await _guildAPI.GetGuildRolesAsync(guildID, ct);

        if (!getRoles.IsSuccess)
        {
            return(Result <AutoroleUpdateStatus> .FromError(getRoles));
        }

        var roles = getRoles.Entity;

        if (roles.All(r => r.ID != autorole.DiscordRoleID))
        {
            // If the role can't be found any longer, we disable it
            var disableAutoroleAsync = await _autoroles.DisableAutoroleAsync(autorole, ct);

            return(!disableAutoroleAsync.IsSuccess
                ? Result <AutoroleUpdateStatus> .FromError(disableAutoroleAsync)
                : Disabled);
        }

        var getIsUserQualified = await _autoroles.IsUserQualifiedForAutoroleAsync(autorole, userID, ct);

        if (!getIsUserQualified.IsSuccess)
        {
            return(Result <AutoroleUpdateStatus> .FromError(getIsUserQualified));
        }

        var isUserQualified = getIsUserQualified.Entity;

        var getMember = await _guildAPI.GetGuildMemberAsync(guildID, userID, ct);

        if (!getMember.IsSuccess)
        {
            return(Result <AutoroleUpdateStatus> .FromError(getMember));
        }

        var member = getMember.Entity;

        if (!member.User.IsDefined(out var user))
        {
            return(Unqualified);
        }

        if (user.IsBot.IsDefined(out var isBot) && isBot)
        {
            return(Unqualified);
        }

        var userHasRole = member.Roles.Contains(autorole.DiscordRoleID);

        switch (isUserQualified)
        {
        case true when userHasRole:
        {
            return(Unchanged);
        }

        case false when userHasRole:
        {
            var removeRole = await _guildAPI.RemoveGuildMemberRoleAsync
                             (
                guildID,
                userID,
                autorole.DiscordRoleID,
                ct : ct
                             );

            if (!removeRole.IsSuccess)
            {
                return(Result <AutoroleUpdateStatus> .FromError(removeRole));
            }

            var getConfirmation = await _autoroles.GetOrCreateAutoroleConfirmationAsync
                                  (
                autorole,
                userID,
                ct
                                  );

            if (!getConfirmation.IsSuccess)
            {
                return(Removed);
            }

            // Remove any existing affirmation
            var confirmation       = getConfirmation.Entity;
            var removeConfirmation = await _autoroles.RemoveAutoroleConfirmationAsync(confirmation, ct);

            return(!removeConfirmation.IsSuccess
                    ? Result <AutoroleUpdateStatus> .FromError(removeConfirmation)
                    : Removed);
        }

        case false:
        {
            // At this point, the user doesn't have the role, and either is or is not qualified.
            // We consider a no-op for an unqualified user a success.
            return(Unqualified);
        }
        }

        if (autorole.RequiresConfirmation)
        {
            var getConfirmation = await _autoroles.GetOrCreateAutoroleConfirmationAsync
                                  (
                autorole,
                userID,
                ct
                                  );

            if (!getConfirmation.IsSuccess)
            {
                return(Result <AutoroleUpdateStatus> .FromError(getConfirmation));
            }

            var confirmation = getConfirmation.Entity;
            if (!confirmation.IsConfirmed)
            {
                // We consider a no-op for an qualified but not affirmed user a success.
                return(RequiresAffirmation);
            }
        }

        var addRole = await _guildAPI.AddGuildMemberRoleAsync(guildID, userID, autorole.DiscordRoleID, ct : ct);

        return(!addRole.IsSuccess
            ? Result <AutoroleUpdateStatus> .FromError(addRole)
            : Applied);
    }