/// <summary> /// Posts a notification that a message was deleted. /// </summary> /// <param name="message">The deleted message.</param> /// <param name="messageChannel">The channel the message was deleted from.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task <OperationResult> NotifyMessageDeletedAsync(IMessage message, ISocketMessageChannel messageChannel) { if (!(messageChannel is ITextChannel textChannel)) { return(OperationResult.FromError("The channel was not a text channel.")); } // We don't care about bot messages if (message.Author.IsBot | message.Author.IsWebhook) { return(OperationResult.FromSuccess()); } var getChannel = await GetMonitoringChannelAsync(textChannel.Guild); if (!getChannel.IsSuccess) { return(OperationResult.FromError(getChannel)); } var channel = getChannel.Entity; var eb = _feedback.CreateEmbedBase(); eb.WithTitle("Message Deleted"); eb.WithColor(Color.Orange); var extra = string.Empty; if ((await textChannel.Guild.GetUserAsync(_client.CurrentUser.Id)).GuildPermissions.ViewAuditLog) { var mostProbableDeleter = await FindMostProbableDeleterAsync(message, textChannel); // We don't care about bot deletions if (!(mostProbableDeleter.IsBot || mostProbableDeleter.IsWebhook)) { extra = $"by {mostProbableDeleter.Mention}."; } } eb.WithDescription ( $"A message was deleted from {MentionUtils.MentionChannel(textChannel.Id)} {extra}" ); var quote = _quotes.CreateMessageQuote(message, _client.CurrentUser); await _feedback.SendEmbedAsync(channel, eb.Build()); await _feedback.SendEmbedAsync(channel, quote.Build()); return(OperationResult.FromSuccess()); }
/// <summary> /// Posts a notification that a message was deleted. /// </summary> /// <param name="message">The deleted message.</param> /// <param name="guildID">The ID of the guild in which the message was.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task <Result> NotifyMessageDeletedAsync(IMessage message, Snowflake guildID) { // We don't care about bot messages var isNonFeedbackMessage = (message.Author.IsBot.IsDefined(out var isBot) && isBot) || (message.Author.IsSystem.IsDefined(out var isSystem) && isSystem); if (isNonFeedbackMessage) { return(Result.FromSuccess()); } var getChannel = await GetMonitoringChannelAsync(guildID); if (!getChannel.IsSuccess) { return(Result.FromError(getChannel)); } var getSelf = await _userAPI.GetCurrentUserAsync(); if (!getSelf.IsSuccess) { return(Result.FromError(getSelf)); } var self = getSelf.Entity; var channel = getChannel.Entity; var eb = new Embed { Colour = _feedback.Theme.Warning, Title = "Message Deleted" }; var getGuildRoles = await _guildAPI.GetGuildRolesAsync(guildID); if (!getGuildRoles.IsSuccess) { return(Result.FromError(getGuildRoles)); } var guildRoles = getGuildRoles.Entity; var everyoneRole = guildRoles.First(r => r.ID == guildID); var getGuildMember = await _guildAPI.GetGuildMemberAsync(guildID, self.ID); if (!getGuildMember.IsSuccess) { return(Result.FromError(getGuildMember)); } var botGuildMember = getGuildMember.Entity; var botRoles = guildRoles.Where(r => botGuildMember.Roles.Contains(r.ID)).ToList(); var botPermissions = DiscordPermissionSet.ComputePermissions ( self.ID, everyoneRole, botRoles ); var extra = string.Empty; if (botPermissions.HasPermission(DiscordPermission.ViewAuditLog)) { var getMostProbableDeleter = await FindMostProbableDeleterAsync(message, guildID); if (!getMostProbableDeleter.IsSuccess) { return(Result.FromError(getMostProbableDeleter)); } var userID = getMostProbableDeleter.Entity; var getUser = await _userAPI.GetUserAsync(userID); if (!getUser.IsSuccess) { return(Result.FromError(getUser)); } var mostProbableDeleter = getUser.Entity; var isNonUserDeleter = (mostProbableDeleter.IsBot.IsDefined(out var isDeleterBot) && isDeleterBot) || (mostProbableDeleter.IsSystem.IsDefined(out var isDeleterSystem) && isDeleterSystem); // We don't care about bot deletions if (!isNonUserDeleter) { extra = $" (probably) by <@{mostProbableDeleter.ID}>"; } } eb = eb with { Description = $"A message was deleted from <#{message.ChannelID}>{extra}." }; var quote = QuoteService.CreateMessageQuote(message, self.ID); var sendResult = await _feedback.SendEmbedAsync(channel, eb); if (!sendResult.IsSuccess) { return(Result.FromError(sendResult)); } sendResult = await _feedback.SendEmbedAsync(channel, quote); return(sendResult.IsSuccess ? Result.FromSuccess() : Result.FromError(sendResult)); }
/// <inheritdoc /> protected override async Task <OperationResult> MessageReceivedAsync(SocketMessage arg) { if (!(arg is SocketUserMessage message)) { return(OperationResult.FromError("The message was not a user message.")); } if (!(message.Author is SocketGuildUser guildUser)) { return(OperationResult.FromError("The author was not a guild user.")); } if (arg.Author.IsBot || arg.Author.IsWebhook) { return(OperationResult.FromSuccess()); } var discard = 0; if (message.HasCharPrefix('!', ref discard)) { return(OperationResult.FromSuccess()); } if (message.HasMentionPrefix(this.Client.CurrentUser, ref discard)) { return(OperationResult.FromSuccess()); } if (IsQuote(message)) { return(OperationResult.FromSuccess()); } var matches = Pattern.Matches(message.Content); if (matches.Count == 0) { return(OperationResult.FromSuccess()); } foreach (Match?match in matches) { if (match is null) { continue; } if (!ulong.TryParse(match.Groups["GuildId"].Value, out _) || !ulong.TryParse(match.Groups["ChannelId"].Value, out var channelId) || !ulong.TryParse(match.Groups["MessageId"].Value, out var messageId)) { continue; } var quotedChannel = this.Client.GetChannel(channelId); if (!(quotedChannel is IGuildChannel) || !(quotedChannel is ISocketMessageChannel quotedMessageChannel)) { continue; } var quotedMessage = await quotedMessageChannel.GetMessageAsync(messageId); if (quotedMessage == null || IsQuote(quotedMessage)) { return(OperationResult.FromSuccess()); } var embed = _quotes.CreateMessageQuote(quotedMessage, guildUser); embed.WithTimestamp(quotedMessage.Timestamp); try { await message.Channel.SendMessageAsync(string.Empty, embed : embed.Build()); } catch (HttpException hex) { if (!hex.WasCausedByMissingPermission()) { throw; } } } if (!(message.Channel is IGuildChannel messageGuildChannel)) { return(OperationResult.FromSuccess()); } var guildBotUser = await messageGuildChannel.Guild.GetUserAsync(this.Client.CurrentUser.Id); var messageCharacterCount = message.Content.Select(c => !char.IsWhiteSpace(c)).Count(); var matchesCharacterCount = matches.Sum(m => m.Length); // If the message consists of just links (i.e, no other text outside of the links, not counting // whitespace), we'll delete it if (messageCharacterCount == matchesCharacterCount && guildBotUser.GuildPermissions.ManageMessages) { await message.DeleteAsync(); } return(OperationResult.FromSuccess()); }
/// <inheritdoc /> protected override async Task MessageReceived(SocketMessage arg) { if (!(arg is SocketUserMessage message)) { return; } if (!(message.Author is SocketGuildUser guildUser)) { return; } if ((arg.Author.IsBot && !arg.Author.IsMe(this.Client)) || arg.Author.IsWebhook) { return; } var discard = 0; if (message.HasCharPrefix('!', ref discard)) { return; } if (message.HasMentionPrefix(this.Client.CurrentUser, ref discard)) { return; } foreach (Match?match in Pattern.Matches(message.Content)) { if (match is null) { continue; } if (!ulong.TryParse(match.Groups["GuildId"].Value, out _) || !ulong.TryParse(match.Groups["ChannelId"].Value, out var channelId) || !ulong.TryParse(match.Groups["MessageId"].Value, out var messageId)) { continue; } var quotedChannel = this.Client.GetChannel(channelId); if (!(quotedChannel is IGuildChannel) || !(quotedChannel is ISocketMessageChannel quotedMessageChannel)) { continue; } var quotedMessage = await quotedMessageChannel.GetMessageAsync(messageId); if (quotedMessage == null || IsQuote(quotedMessage)) { return; } if (message.Channel is IGuildChannel messageGuildChannel) { var guildBotUser = await messageGuildChannel.Guild.GetUserAsync(this.Client.CurrentUser.Id); // It's just a single quote link, so we'll delete it if (message.Content == match.Value && guildBotUser.GuildPermissions.ManageMessages) { await message.DeleteAsync(); } } var embed = _quotes.CreateMessageQuote(quotedMessage, guildUser); embed.WithTimestamp(quotedMessage.Timestamp); try { await message.Channel.SendMessageAsync(string.Empty, embed : embed.Build()); } catch (HttpException hex) { if (!hex.WasCausedByMissingPermission()) { throw; } } } }