using System.Text; using JetBrains.Annotations; using Octobot.Data; using Octobot.Services; using Remora.Discord.API.Abstractions.Gateway.Events; using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.API.Abstractions.Rest; using Remora.Discord.Extensions.Embeds; using Remora.Discord.Extensions.Formatting; using Remora.Discord.Gateway.Responders; using Remora.Results; namespace Octobot.Responders; /// /// Handles logging the contents of a deleted message and the user who deleted the message /// to a guild's if one is set. /// [UsedImplicitly] public class MessageDeletedResponder : IResponder { private readonly IDiscordRestAuditLogAPI _auditLogApi; private readonly IDiscordRestChannelAPI _channelApi; private readonly GuildDataService _guildData; private readonly IDiscordRestUserAPI _userApi; public MessageDeletedResponder( IDiscordRestAuditLogAPI auditLogApi, IDiscordRestChannelAPI channelApi, GuildDataService guildData, IDiscordRestUserAPI userApi) { _auditLogApi = auditLogApi; _channelApi = channelApi; _guildData = guildData; _userApi = userApi; } public async Task RespondAsync(IMessageDelete gatewayEvent, CancellationToken ct = default) { if (!gatewayEvent.GuildID.IsDefined(out var guildId)) { return Result.FromSuccess(); } var cfg = await _guildData.GetSettings(guildId, ct); if (GuildSettings.PrivateFeedbackChannel.Get(cfg).Empty()) { return Result.FromSuccess(); } var messageResult = await _channelApi.GetChannelMessageAsync(gatewayEvent.ChannelID, gatewayEvent.ID, ct); if (!messageResult.IsDefined(out var message)) { return Result.FromError(messageResult); } if (string.IsNullOrWhiteSpace(message.Content)) { return Result.FromSuccess(); } var auditLogResult = await _auditLogApi.GetGuildAuditLogAsync( guildId, actionType: AuditLogEvent.MessageDelete, limit: 1, ct: ct); if (!auditLogResult.IsDefined(out var auditLogPage)) { return Result.FromError(auditLogResult); } var auditLog = auditLogPage.AuditLogEntries.Single(); var deleterResult = Result.FromSuccess(message.Author); if (auditLog.UserID is not null && auditLog.Options.Value.ChannelID == gatewayEvent.ChannelID && DateTimeOffset.UtcNow.Subtract(auditLog.ID.Timestamp).TotalSeconds <= 2) { deleterResult = await _userApi.GetUserAsync(auditLog.UserID.Value, ct); } if (!deleterResult.IsDefined(out var deleter)) { return Result.FromError(deleterResult); } Messages.Culture = GuildSettings.Language.Get(cfg); var builder = new StringBuilder().AppendLine( string.Format(Messages.DescriptionActionJumpToChannel, Mention.Channel(gatewayEvent.ChannelID))) .AppendLine(message.Content.InBlockCode()); var embed = new EmbedBuilder() .WithSmallTitle( string.Format( Messages.CachedMessageDeleted, message.Author.GetTag()), message.Author) .WithDescription(builder.ToString()) .WithActionFooter(deleter) .WithTimestamp(message.Timestamp) .WithColour(ColorsList.Red) .Build(); if (!embed.IsDefined(out var built)) { return Result.FromError(embed); } return (Result)await _channelApi.CreateMessageAsync( GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: new[] { built }, allowedMentions: Octobot.NoMentions, ct: ct); } }