Skip to content

Commit 08b0d79

Browse files
committed
feat: cache votes on reaction add/remove
1 parent be060fb commit 08b0d79

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

SuggestionBot/Services/SuggestionService.cs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,9 @@ await thread.ModifyAsync(t =>
717717
protected override Task ExecuteAsync(CancellationToken stoppingToken)
718718
{
719719
_discordClient.GuildAvailable += OnGuildAvailable;
720+
_discordClient.MessageReactionAdded += OnMessageReactionAdded;
721+
_discordClient.MessageReactionRemoved += OnMessageReactionRemoved;
722+
720723
Load();
721724
return Task.CompletedTask;
722725
}
@@ -763,6 +766,66 @@ private DiscordEmbedBuilder CreateDefaultEmbed(Suggestion suggestion, DiscordGui
763766
return embed;
764767
}
765768

769+
private Task OnMessageReactionRemoved(DiscordClient sender, MessageReactionRemoveEventArgs args)
770+
{
771+
string emoji = args.Emoji.Name;
772+
773+
if (!ValidateReaction(args.User as DiscordMember, args.Message, emoji, out Suggestion? suggestion))
774+
{
775+
return Task.CompletedTask;
776+
}
777+
778+
switch (emoji)
779+
{
780+
case "👍":
781+
suggestion.UpVotes--;
782+
break;
783+
784+
case "👎":
785+
suggestion.DownVotes--;
786+
break;
787+
788+
default:
789+
return Task.CompletedTask;
790+
}
791+
792+
using SuggestionContext context = _contextFactory.CreateDbContext();
793+
context.Suggestions.Update(suggestion);
794+
context.SaveChanges();
795+
796+
return Task.CompletedTask;
797+
}
798+
799+
private Task OnMessageReactionAdded(DiscordClient sender, MessageReactionAddEventArgs args)
800+
{
801+
string emoji = args.Emoji.Name;
802+
803+
if (!ValidateReaction(args.User as DiscordMember, args.Message, emoji, out Suggestion? suggestion))
804+
{
805+
return Task.CompletedTask;
806+
}
807+
808+
switch (emoji)
809+
{
810+
case "👍":
811+
suggestion.UpVotes++;
812+
break;
813+
814+
case "👎":
815+
suggestion.DownVotes++;
816+
break;
817+
818+
default:
819+
return Task.CompletedTask;
820+
}
821+
822+
using SuggestionContext context = _contextFactory.CreateDbContext();
823+
context.Suggestions.Update(suggestion);
824+
context.SaveChanges();
825+
826+
return Task.CompletedTask;
827+
}
828+
766829
private Task OnGuildAvailable(DiscordClient sender, GuildCreateEventArgs args)
767830
{
768831
DiscordGuild guild = args.Guild;
@@ -785,9 +848,88 @@ private Task OnGuildAvailable(DiscordClient sender, GuildCreateEventArgs args)
785848
_logger.LogWarning("{Guild} is not configured!", guild);
786849
}
787850

851+
RefreshSuggestionScores(args.Guild);
788852
return Task.CompletedTask;
789853
}
790854

855+
private bool ValidateReaction(DiscordMember? member,
856+
DiscordMessage message,
857+
string emoji,
858+
[NotNullWhen(true)] out Suggestion? suggestion)
859+
{
860+
suggestion = null;
861+
862+
if (member is null || member.IsBot)
863+
{
864+
return false;
865+
}
866+
867+
DiscordGuild guild = member.Guild;
868+
if (message.Channel.Id != _configurationService.GetGuildConfiguration(guild)?.SuggestionChannel)
869+
{
870+
return false;
871+
}
872+
873+
if (!_suggestions.TryGetValue(guild.Id, out List<Suggestion>? suggestions))
874+
{
875+
return false;
876+
}
877+
878+
if (emoji != "👍" && emoji != "👎")
879+
{
880+
return false;
881+
}
882+
883+
suggestion = suggestions.FirstOrDefault(s => s.MessageId == message.Id);
884+
if (suggestion is null)
885+
{
886+
return false;
887+
}
888+
889+
return suggestion.Status != SuggestionStatus.Suggested;
890+
}
891+
892+
private void RefreshSuggestionScores(DiscordGuild guild)
893+
{
894+
IEnumerable<Suggestion> suggestions = GetSuggestions(guild).Where(s => s is
895+
{
896+
Status: SuggestionStatus.Suggested,
897+
UpVotes: 0,
898+
DownVotes: 0
899+
});
900+
901+
var updatedSuggestions = new List<Suggestion>();
902+
903+
foreach (Suggestion suggestion in suggestions)
904+
{
905+
DiscordMessage? message = GetSuggestionMessage(suggestion);
906+
if (message is null)
907+
{
908+
continue;
909+
}
910+
911+
int upVotes = message.Reactions.Count(r => r.Emoji.Name == "👍");
912+
int downVotes = message.Reactions.Count(r => r.Emoji.Name == "👎");
913+
if (upVotes == suggestion.UpVotes && downVotes == suggestion.DownVotes)
914+
{
915+
continue;
916+
}
917+
918+
suggestion.UpVotes = upVotes;
919+
suggestion.DownVotes = downVotes;
920+
updatedSuggestions.Add(suggestion);
921+
}
922+
923+
if (updatedSuggestions.Count == 0)
924+
{
925+
return;
926+
}
927+
928+
using SuggestionContext context = _contextFactory.CreateDbContext();
929+
context.Suggestions.UpdateRange(updatedSuggestions);
930+
context.SaveChanges();
931+
}
932+
791933
private void Load()
792934
{
793935
using SuggestionContext context = _contextFactory.CreateDbContext();

0 commit comments

Comments
 (0)