feat: emoji update event

This commit is contained in:
sam 2024-10-14 17:09:12 +02:00
parent f1c75124a8
commit 4f718cde20
Signed by: sam
GPG key ID: 5F3C3C1B3166639D
7 changed files with 174 additions and 2 deletions

View file

@ -16,13 +16,13 @@
using Catalogger.Backend.Cache;
using Catalogger.Backend.Cache.InMemoryCache;
using Catalogger.Backend.Database;
using Catalogger.Backend.Database.Models;
using Catalogger.Backend.Extensions;
using Catalogger.Backend.Services;
using Remora.Discord.API.Abstractions.Gateway.Events;
using Remora.Discord.Extensions.Embeds;
using Remora.Discord.Gateway.Responders;
using Remora.Results;
using Guild = Catalogger.Backend.Database.Models.Guild;
namespace Catalogger.Backend.Bot.Responders.Guilds;
@ -33,6 +33,7 @@ public class GuildCreateResponder(
GuildCache guildCache,
RoleCache roleCache,
ChannelCache channelCache,
EmojiCache emojiCache,
WebhookExecutorService webhookExecutor,
IMemberCache memberCache,
GuildFetchService guildFetchService
@ -55,6 +56,7 @@ public class GuildCreateResponder(
guildName = guild.Name;
guildCache.Set(guild);
emojiCache.Set(guild.ID, guild.Emojis);
foreach (var c in guild.Channels)
channelCache.Set(c, guild.ID);
foreach (var r in guild.Roles)

View file

@ -0,0 +1,128 @@
// Copyright (C) 2021-present sam (starshines.gay)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
using Catalogger.Backend.Cache.InMemoryCache;
using Catalogger.Backend.Database;
using Catalogger.Backend.Database.Queries;
using Catalogger.Backend.Extensions;
using Catalogger.Backend.Services;
using Remora.Discord.API;
using Remora.Discord.API.Abstractions.Gateway.Events;
using Remora.Discord.API.Abstractions.Objects;
using Remora.Discord.Extensions.Embeds;
using Remora.Discord.Gateway.Responders;
using Remora.Results;
namespace Catalogger.Backend.Bot.Responders.Guilds;
public class GuildEmojisUpdateResponder(
ILogger logger,
DatabaseContext db,
EmojiCache emojiCache,
WebhookExecutorService webhookExecutor
) : IResponder<IGuildEmojisUpdate>
{
private readonly ILogger _logger = logger.ForContext<GuildEmojisUpdateResponder>();
public async Task<Result> RespondAsync(IGuildEmojisUpdate evt, CancellationToken ct = default)
{
try
{
if (!emojiCache.TryGet(evt.GuildID, out var oldEmoji))
{
_logger.Information(
"Previous emoji for {GuildId} were not in cache, ignoring event",
evt.GuildID
);
return Result.Success;
}
IEmbed embed;
// As far as I know, only one emoji can be added or removed at once.
var added = evt.Emojis.FirstOrDefault(e => oldEmoji.All(o => o.ID != e.ID));
var removed = oldEmoji.FirstOrDefault(o => evt.Emojis.All(e => o.ID != e.ID));
var updated = evt.Emojis.FirstOrDefault(e =>
oldEmoji.Any(o => o.ID == e.ID && o.Name != e.Name)
);
if (added != null)
{
var url = CDN.GetEmojiUrl(added).GetOrThrow().ToString();
embed = new EmbedBuilder()
.WithTitle("Emoji created")
.WithDescription($"{FormatEmoji(added)} [{added.Name}]({url})")
.WithThumbnailUrl(url)
.WithFooter($"ID: {added.ID}")
.WithColour(DiscordUtils.Green)
.WithCurrentTimestamp()
.Build()
.GetOrThrow();
}
else if (removed != null)
{
var url = CDN.GetEmojiUrl(removed).GetOrThrow().ToString();
embed = new EmbedBuilder()
.WithTitle("Emoji removed")
.WithDescription($"[{removed.Name}]({url})")
.WithThumbnailUrl(url)
.WithFooter($"ID: {removed.ID}")
.WithColour(DiscordUtils.Red)
.WithCurrentTimestamp()
.Build()
.GetOrThrow();
}
else if (updated != null)
{
var url = CDN.GetEmojiUrl(updated).GetOrThrow().ToString();
var previous = oldEmoji.First(o => o.ID == updated.ID);
embed = new EmbedBuilder()
.WithTitle("Emoji renamed")
.WithDescription(
$"""
{FormatEmoji(updated)} [{updated.Name}]({url})
{previous.Name} {updated.Name}
"""
)
.WithThumbnailUrl(url)
.WithFooter($"ID: {updated.ID}")
.WithColour(DiscordUtils.Green)
.WithCurrentTimestamp()
.Build()
.GetOrThrow();
}
else
{
_logger.Warning(
"Received emoji update event for {GuildId} but all emoji were identical, not logging",
evt.GuildID
);
return Result.Success;
}
var guildConfig = await db.GetGuildAsync(evt.GuildID, ct);
webhookExecutor.QueueLog(guildConfig, LogChannelType.GuildEmojisUpdate, embed);
return Result.Success;
}
finally
{
emojiCache.Set(evt.GuildID, evt.Emojis);
}
}
private static string FormatEmoji(IEmoji emoji) =>
emoji.IsAnimated.OrDefault(false)
? $"<a:{emoji.Name}:{emoji.ID}>"
: $"<:{emoji.Name}:{emoji.ID}>";
}