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()); }
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()) { } }
/// <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); }