161 lines
No EOL
7.2 KiB
C#
161 lines
No EOL
7.2 KiB
C#
using Discord;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using RegexBot.Data;
|
|
using System.Text;
|
|
|
|
namespace RegexBot.Modules.ModLogs;
|
|
// Contains handlers and all logic relating to logging message edits and deletions
|
|
internal partial class ModLogs {
|
|
const string PreviewCutoffNotify = "**Message too long to preview; showing first {0} characters.**\n\n";
|
|
const string NotCached = "Message not cached.";
|
|
const string MessageContentNull = "(blank)";
|
|
|
|
private async Task HandleDelete(Cacheable<IMessage, ulong> argMsg, Cacheable<IMessageChannel, ulong> argChannel) {
|
|
const int MaxPreviewLength = 750;
|
|
if (argChannel.Value is not SocketTextChannel channel) return;
|
|
var conf = GetGuildState<ModuleConfig>(channel.Guild.Id);
|
|
var reportChannel = conf?.ReportingChannel?.FindChannelIn(channel.Guild, true);
|
|
if (reportChannel == null) return;
|
|
if ((conf?.LogMessageDeletions ?? false) == false) return;
|
|
if (reportChannel.Id == channel.Id) {
|
|
Log($"[{channel.Guild.Name}] Message deletion detected in the reporting channel. Regular report has been suppressed.");
|
|
return;
|
|
}
|
|
|
|
using var db = new BotDatabaseContext();
|
|
var cachedMsg = db.GuildMessageCache
|
|
.Include(gm => gm.Author)
|
|
.Where(gm => gm.MessageId == (long)argMsg.Id)
|
|
.SingleOrDefault();
|
|
|
|
var reportEmbed = new EmbedBuilder()
|
|
.WithTitle("Message deleted")
|
|
.WithCurrentTimestamp()
|
|
.WithFooter($"User ID: {(cachedMsg == null ? "Unknown" : cachedMsg.AuthorId)}");
|
|
|
|
if (cachedMsg != null) {
|
|
if (cachedMsg.Content == null) {
|
|
reportEmbed.Description = MessageContentNull;
|
|
} else if (cachedMsg.Content.Length > MaxPreviewLength) {
|
|
reportEmbed.Description = string.Format(PreviewCutoffNotify, MaxPreviewLength) +
|
|
cachedMsg.Content[MaxPreviewLength..];
|
|
} else {
|
|
reportEmbed.Description = cachedMsg.Content;
|
|
}
|
|
if (cachedMsg.Author == null) {
|
|
reportEmbed.Author = new EmbedAuthorBuilder() {
|
|
Name = $"User ID {cachedMsg.AuthorId}",
|
|
IconUrl = GetDefaultAvatarUrl("0")
|
|
};
|
|
} else {
|
|
reportEmbed.Author = new EmbedAuthorBuilder() {
|
|
Name = $"{cachedMsg.Author.Username}#{cachedMsg.Author.Discriminator}",
|
|
IconUrl = cachedMsg.Author.AvatarUrl ?? GetDefaultAvatarUrl(cachedMsg.Author.Discriminator)
|
|
};
|
|
}
|
|
var attach = CheckAttachments(cachedMsg.AttachmentNames);
|
|
if (attach != null) reportEmbed.AddField(attach);
|
|
} else {
|
|
reportEmbed.Description = NotCached;
|
|
}
|
|
|
|
var contextStr = new StringBuilder();
|
|
contextStr.AppendLine($"User: {(cachedMsg != null ? $"<@!{cachedMsg.AuthorId}>" : "Unknown")}");
|
|
contextStr.AppendLine($"Channel: <#{channel.Id}> (#{channel.Name})");
|
|
contextStr.AppendLine($"Posted: {MakeTimestamp(SnowflakeUtils.FromSnowflake(argMsg.Id))}");
|
|
if (cachedMsg?.EditedAt != null) contextStr.AppendLine($"Last edit: {MakeTimestamp(cachedMsg.EditedAt.Value)}");
|
|
contextStr.AppendLine($"Message ID: {argMsg.Id}");
|
|
reportEmbed.AddField(new EmbedFieldBuilder() {
|
|
Name = "Context",
|
|
Value = contextStr.ToString()
|
|
});
|
|
|
|
await reportChannel.SendMessageAsync(embed: reportEmbed.Build());
|
|
}
|
|
|
|
private async Task FilterIncomingEvents(ISharedEvent ev) {
|
|
if (ev is MessageCacheUpdateEvent upd) {
|
|
await HandleUpdate(upd.OldMessage, upd.NewMessage);
|
|
}
|
|
}
|
|
|
|
private async Task HandleUpdate(CachedGuildMessage? oldMsg, SocketMessage newMsg) {
|
|
const int MaxPreviewLength = 500;
|
|
var channel = (SocketTextChannel)newMsg.Channel;
|
|
var conf = GetGuildState<ModuleConfig>(channel.Guild.Id);
|
|
var reportChannel = conf?.ReportingChannel?.FindChannelIn(channel.Guild, true);
|
|
if (reportChannel == null) return;
|
|
if ((conf?.LogMessageEdits ?? false) == false) return;
|
|
if (reportChannel.Id == channel.Id) {
|
|
Log($"[{channel.Guild.Name}] Message edit detected in the reporting channel. Regular report has been suppressed.");
|
|
return;
|
|
}
|
|
|
|
var reportEmbed = new EmbedBuilder()
|
|
.WithTitle("Message edited")
|
|
.WithCurrentTimestamp()
|
|
.WithFooter($"User ID: {newMsg.Author.Id}");
|
|
|
|
reportEmbed.Author = new EmbedAuthorBuilder() {
|
|
Name = $"{newMsg.Author.Username}#{newMsg.Author.Discriminator}",
|
|
IconUrl = newMsg.Author.GetAvatarUrl() ?? newMsg.Author.GetDefaultAvatarUrl()
|
|
};
|
|
|
|
var oldField = new EmbedFieldBuilder() { Name = "Old" };
|
|
if (oldMsg != null) {
|
|
if (oldMsg.Content == null) {
|
|
oldField.Value = MessageContentNull;
|
|
} else if (oldMsg.Content.Length > MaxPreviewLength) {
|
|
oldField.Value = string.Format(PreviewCutoffNotify, MaxPreviewLength) +
|
|
oldMsg.Content[MaxPreviewLength..];
|
|
} else {
|
|
oldField.Value = oldMsg.Content;
|
|
}
|
|
} else {
|
|
oldField.Value = NotCached;
|
|
}
|
|
reportEmbed.AddField(oldField);
|
|
|
|
// TODO shorten 'new' preview, add clickable? check if this would be good usability-wise
|
|
var newField = new EmbedFieldBuilder() { Name = "New" };
|
|
if (newMsg.Content == null) {
|
|
newField.Value = MessageContentNull;
|
|
} else if (newMsg.Content.Length > MaxPreviewLength) {
|
|
newField.Value = string.Format(PreviewCutoffNotify, MaxPreviewLength) +
|
|
newMsg.Content[MaxPreviewLength..];
|
|
} else {
|
|
newField.Value = newMsg.Content;
|
|
}
|
|
reportEmbed.AddField(newField);
|
|
|
|
var attach = CheckAttachments(newMsg.Attachments.Select(a => a.Filename));
|
|
if (attach != null) reportEmbed.AddField(attach);
|
|
|
|
var contextStr = new StringBuilder();
|
|
contextStr.AppendLine($"User: <@!{newMsg.Author.Id}>");
|
|
contextStr.AppendLine($"Channel: <#{channel.Id}> (#{channel.Name})");
|
|
if ((oldMsg?.EditedAt) == null) contextStr.AppendLine($"Posted: {MakeTimestamp(SnowflakeUtils.FromSnowflake(newMsg.Id))}");
|
|
else contextStr.AppendLine($"Previous edit: {MakeTimestamp(oldMsg.EditedAt.Value)}");
|
|
contextStr.AppendLine($"Message ID: {newMsg.Id}");
|
|
var contextField = new EmbedFieldBuilder() {
|
|
Name = "Context",
|
|
Value = contextStr.ToString()
|
|
};
|
|
reportEmbed.AddField(contextField);
|
|
|
|
await reportChannel.SendMessageAsync(embed: reportEmbed.Build());
|
|
}
|
|
|
|
private static EmbedFieldBuilder? CheckAttachments(IEnumerable<string> attachments) {
|
|
if (attachments.Any()) {
|
|
var field = new EmbedFieldBuilder { Name = "Attachments" };
|
|
var attachNames = new StringBuilder();
|
|
foreach (var name in attachments) {
|
|
attachNames.AppendLine($"`{name}`");
|
|
}
|
|
field.Value = attachNames.ToString().TrimEnd();
|
|
return field;
|
|
}
|
|
return null;
|
|
}
|
|
} |