Merge pull request #326 from spiralw/feat/log-message-edit
Add logging message edits
This commit is contained in:
commit
ab5fceeae6
@ -20,14 +20,16 @@ namespace PluralKit.Bot
|
|||||||
private readonly IClock _clock;
|
private readonly IClock _clock;
|
||||||
private readonly DiscordApiClient _rest;
|
private readonly DiscordApiClient _rest;
|
||||||
private readonly WebhookExecutorService _webhookExecutor;
|
private readonly WebhookExecutorService _webhookExecutor;
|
||||||
|
private readonly LogChannelService _logChannel;
|
||||||
|
|
||||||
public MessageEdit(IDatabase db, ModelRepository repo, IClock clock, DiscordApiClient rest, WebhookExecutorService webhookExecutor)
|
public MessageEdit(IDatabase db, ModelRepository repo, IClock clock, DiscordApiClient rest, WebhookExecutorService webhookExecutor, LogChannelService logChannel)
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
_clock = clock;
|
_clock = clock;
|
||||||
_rest = rest;
|
_rest = rest;
|
||||||
_webhookExecutor = webhookExecutor;
|
_webhookExecutor = webhookExecutor;
|
||||||
|
_logChannel = logChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task EditMessage(Context ctx)
|
public async Task EditMessage(Context ctx)
|
||||||
@ -41,12 +43,16 @@ namespace PluralKit.Bot
|
|||||||
|
|
||||||
var newContent = ctx.RemainderOrNull();
|
var newContent = ctx.RemainderOrNull();
|
||||||
|
|
||||||
|
var originalMsg = await _rest.GetMessage(msg.Channel, msg.Mid);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _webhookExecutor.EditWebhookMessage(msg.Channel, msg.Mid, newContent);
|
await _webhookExecutor.EditWebhookMessage(msg.Channel, msg.Mid, newContent);
|
||||||
|
|
||||||
if (ctx.BotPermissions.HasFlag(PermissionSet.ManageMessages))
|
if (ctx.BotPermissions.HasFlag(PermissionSet.ManageMessages))
|
||||||
await _rest.DeleteMessage(ctx.Channel.Id, ctx.Message.Id);
|
await _rest.DeleteMessage(ctx.Channel.Id, ctx.Message.Id);
|
||||||
|
|
||||||
|
await _logChannel.LogEditedMessage(ctx.MessageContext, msg, ctx.Message, originalMsg!, newContent);
|
||||||
}
|
}
|
||||||
catch (NotFoundException)
|
catch (NotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -112,6 +112,19 @@ namespace PluralKit.Bot {
|
|||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Embed CreateEditedMessageEmbed(PKSystem system, PKMember member, ulong messageId, ulong originalMsgId, User sender, string content, string oldContent, Channel channel) {
|
||||||
|
var timestamp = DiscordUtils.SnowflakeToInstant(messageId);
|
||||||
|
var name = member.NameFor(LookupContext.ByNonOwner);
|
||||||
|
return new EmbedBuilder()
|
||||||
|
.Author(new($"[Edited] #{channel.Name}: {name}", IconUrl: DiscordUtils.WorkaroundForUrlBug(member.AvatarFor(LookupContext.ByNonOwner))))
|
||||||
|
.Thumbnail(new(member.AvatarFor(LookupContext.ByNonOwner)))
|
||||||
|
.Field(new("Old message", oldContent?.NormalizeLineEndSpacing().Truncate(1000)))
|
||||||
|
.Description(content?.NormalizeLineEndSpacing())
|
||||||
|
.Footer(new($"System ID: {system.Hid} | Member ID: {member.Hid} | Sender: {sender.Username}#{sender.Discriminator} ({sender.Id}) | Message ID: {messageId} | Original Message ID: {originalMsgId}"))
|
||||||
|
.Timestamp(timestamp.ToDateTimeOffset().ToString("O"))
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Embed> CreateMemberEmbed(PKSystem system, PKMember member, Guild guild, LookupContext ctx)
|
public async Task<Embed> CreateMemberEmbed(PKSystem system, PKMember member, Guild guild, LookupContext ctx)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Dapper;
|
using Dapper;
|
||||||
@ -34,24 +35,11 @@ namespace PluralKit.Bot {
|
|||||||
|
|
||||||
public async ValueTask LogMessage(MessageContext ctx, ProxyMatch proxy, Message trigger, ulong hookMessage)
|
public async ValueTask LogMessage(MessageContext ctx, ProxyMatch proxy, Message trigger, ulong hookMessage)
|
||||||
{
|
{
|
||||||
if (ctx.SystemId == null || ctx.LogChannel == null || ctx.InLogBlacklist) return;
|
var logChannel = await GetAndCheckLogChannel(ctx, trigger);
|
||||||
|
if (logChannel == null) return;
|
||||||
// Find log channel and check if valid
|
|
||||||
var logChannel = await FindLogChannel(trigger.GuildId!.Value, ctx.LogChannel.Value);
|
|
||||||
if (logChannel == null || logChannel.Type != Channel.ChannelType.GuildText) return;
|
|
||||||
|
|
||||||
var triggerChannel = _cache.GetChannel(trigger.ChannelId);
|
var triggerChannel = _cache.GetChannel(trigger.ChannelId);
|
||||||
|
|
||||||
// Check bot permissions
|
|
||||||
var perms = _bot.PermissionsIn(logChannel.Id);
|
|
||||||
if (!perms.HasFlag(PermissionSet.SendMessages | PermissionSet.EmbedLinks))
|
|
||||||
{
|
|
||||||
_logger.Information(
|
|
||||||
"Does not have permission to proxy log, ignoring (channel: {ChannelId}, guild: {GuildId}, bot permissions: {BotPermissions})",
|
|
||||||
ctx.LogChannel.Value, trigger.GuildId!.Value, perms);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send embed!
|
// Send embed!
|
||||||
await using var conn = await _db.Obtain();
|
await using var conn = await _db.Obtain();
|
||||||
var embed = _embed.CreateLoggedMessageEmbed(await _repo.GetSystem(conn, ctx.SystemId.Value),
|
var embed = _embed.CreateLoggedMessageEmbed(await _repo.GetSystem(conn, ctx.SystemId.Value),
|
||||||
@ -61,6 +49,56 @@ namespace PluralKit.Bot {
|
|||||||
await _rest.CreateMessage(logChannel.Id, new() {Content = url, Embed = embed});
|
await _rest.CreateMessage(logChannel.Id, new() {Content = url, Embed = embed});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async ValueTask LogEditedMessage(MessageContext ctx, PKMessage proxy, Message trigger, Message originalMessage, string newContent)
|
||||||
|
{
|
||||||
|
var logChannel = await GetAndCheckLogChannel(ctx, trigger, proxy);
|
||||||
|
if (logChannel == null) return;
|
||||||
|
|
||||||
|
var triggerChannel = _cache.GetChannel(proxy.Channel);
|
||||||
|
|
||||||
|
// Send embed!
|
||||||
|
await using var conn = await _db.Obtain();
|
||||||
|
var embed = _embed.CreateEditedMessageEmbed(await _repo.GetSystem(conn, ctx.SystemId.Value),
|
||||||
|
await _repo.GetMember(conn, proxy.Member), originalMessage.Id, trigger.Id, trigger.Author, newContent, originalMessage.Content,
|
||||||
|
triggerChannel);
|
||||||
|
var url = $"https://discord.com/channels/{proxy.Guild.Value}/{proxy.Channel}/{proxy.Mid}";
|
||||||
|
await _rest.CreateMessage(logChannel.Id, new() {Content = url, Embed = embed});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Channel?> GetAndCheckLogChannel(MessageContext ctx, Message trigger, PKMessage original = null)
|
||||||
|
{
|
||||||
|
var guildId = trigger.GuildId != null ? trigger.GuildId!.Value : original.Guild.Value;
|
||||||
|
var logChannelId = ctx.LogChannel;
|
||||||
|
var isBlacklisted = ctx.InLogBlacklist;
|
||||||
|
|
||||||
|
if (original != null)
|
||||||
|
{
|
||||||
|
// we're editing a message, get log channel info from the database
|
||||||
|
var guild = await _db.Execute(c => _repo.GetGuild(c, original.Guild.Value));
|
||||||
|
logChannelId = guild.LogChannel;
|
||||||
|
isBlacklisted = guild.Blacklist.Any(x => x == logChannelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.SystemId == null || logChannelId == null || isBlacklisted) return null;
|
||||||
|
|
||||||
|
|
||||||
|
// Find log channel and check if valid
|
||||||
|
var logChannel = await FindLogChannel(guildId, logChannelId.Value);
|
||||||
|
if (logChannel == null || logChannel.Type != Channel.ChannelType.GuildText) return null;
|
||||||
|
|
||||||
|
// Check bot permissions
|
||||||
|
var perms = _bot.PermissionsIn(logChannel.Id);
|
||||||
|
if (!perms.HasFlag(PermissionSet.SendMessages | PermissionSet.EmbedLinks))
|
||||||
|
{
|
||||||
|
_logger.Information(
|
||||||
|
"Does not have permission to proxy log, ignoring (channel: {ChannelId}, guild: {GuildId}, bot permissions: {BotPermissions})",
|
||||||
|
ctx.LogChannel.Value, trigger.GuildId!.Value, perms);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return logChannel;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<Channel?> FindLogChannel(ulong guildId, ulong channelId)
|
private async Task<Channel?> FindLogChannel(ulong guildId, ulong channelId)
|
||||||
{
|
{
|
||||||
// TODO: fetch it directly on cache miss?
|
// TODO: fetch it directly on cache miss?
|
||||||
|
Loading…
Reference in New Issue
Block a user