public static async Task MessageFilterEventHandlerAsync(FreudShard shard, MessageCreateEventArgs e) { if (e.Author.IsBot || e.Channel.IsPrivate || string.IsNullOrWhiteSpace(e.Message?.Content)) { return; } if (shard.SharedData.BlockedChannels.Contains(e.Channel.Id)) { return; } var gcfg = shard.SharedData.GetGuildConfiguration(e.Guild.Id); if (gcfg.LinkfilterSettings.Enabled) { if (await shard.CNext.Services.GetService <LinkfilterService>().HandleNewMessageAsync(e, gcfg.LinkfilterSettings)) { return; } } if (!shard.SharedData.MessageContainsFilter(e.Guild.Id, e.Message.Content)) { return; } if (!e.Channel.PermissionsFor(e.Guild.CurrentMember).HasFlag(Permissions.ManageMessages)) { return; } await e.Message.DeleteAsync("bot: Filter hit"); await e.Channel.SendMessageAsync($"{e.Author.Mention} said: {FormatterExtensions.Spoiler(Formatter.BlockCode(FormatterExtensions.StripMarkdown(e.Message.Content)))}"); }
public async Task FlagMessageAsync(CommandContext ctx, [Description("Message.")] DiscordMessage msg = null, [Description("Voting timespan.")] TimeSpan?timespan = null) { msg = msg ?? (await ctx.Channel.GetMessagesBeforeAsync(ctx.Channel.LastMessageId, 1))?.FirstOrDefault(); if (msg is null) { throw new CommandFailedException("Cannot retrieve the message!"); } if (timespan?.TotalSeconds < 5 || timespan?.TotalMinutes > 5) { throw new InvalidCommandUsageException("Timespan cannot be greater than 5 minutes or lower than 5 seconds."); } IEnumerable <PollEmoji> res = await msg.DoPollAsync(new[] { StaticDiscordEmoji.ArrowUp, StaticDiscordEmoji.ArrowDown }, PollBehaviour.Default, timeout : timespan ?? TimeSpan.FromMinutes(1)); var votes = res.ToDictionary(pe => pe.Emoji, pe => pe.Voted.Count); if (votes.GetValueOrDefault(StaticDiscordEmoji.ArrowDown) > 2 * votes.GetValueOrDefault(StaticDiscordEmoji.ArrowUp)) { string sanitized = FormatterExtensions.Spoiler(FormatterExtensions.StripMarkdown(msg.Content)); await msg.DeleteAsync(); await ctx.RespondAsync($"{msg.Author.Mention} said: {sanitized}"); } else { await this.InformOfFailureAsync(ctx, "Not enough downvotes required for deletion."); } }
public static async Task MessageUpdateEventHandlerAsync(FreudShard shard, MessageUpdateEventArgs e) { if (e.Author is null || e.Author.IsBot || e.Channel is null || e.Channel.IsPrivate || e.Message is null) { return; } if (shard.SharedData.BlockedChannels.Contains(e.Channel.Id)) { return; } if (e.Message.Author == e.Client.CurrentUser && shard.SharedData.IsEventRunningInChannel(e.Channel.Id)) { return; } if (!(e.Message.Content is null) && shard.SharedData.MessageContainsFilter(e.Guild.Id, e.Message.Content)) { try { await e.Message.DeleteAsync("bot: Filter hit after update"); await e.Channel.SendMessageAsync($"{e.Author.Mention} said: {FormatterExtensions.Spoiler(Formatter.BlockCode(FormatterExtensions.StripMarkdown(e.Message.Content)))}"); } catch { // swallow } } var logchn = shard.SharedData.GetLogChannelForGuild(shard.Client, e.Guild); if (logchn is null || !e.Message.IsEdited || e.Channel.IsExempted(shard)) { return; } var member = await e.Guild.GetMemberAsync(e.Author.Id); if (member.IsExempted(shard)) { return; } string pcontent = string.IsNullOrWhiteSpace(e.MessageBefore?.Content) ? "" : e.MessageBefore.Content.Truncate(700); string acontent = string.IsNullOrWhiteSpace(e.Message?.Content) ? "" : e.Message.Content.Truncate(700); string ctime = e.Message.CreationTimestamp == null ? _unknown : e.Message.CreationTimestamp.ToUtcTimestamp(); string etime = e.Message.EditedTimestamp is null ? _unknown : e.Message.EditedTimestamp.Value.ToUtcTimestamp(); string bextra = $"Embeds: {e.MessageBefore?.Embeds?.Count ?? 0}, Reactions: {e.MessageBefore?.Reactions?.Count ?? 0}, Attachments: {e.MessageBefore.Attachments?.Count ?? 0}"; string aextra = $"Embeds: {e.Message.Embeds.Count}, Reactions: {e.Message.Reactions.Count}, Attachments: {e.Message.Attachments.Count}"; var emb = FormEmbedBuilder(EventOrigin.Message, "Message updated"); emb.WithDescription(Formatter.MaskedUrl("Jump to message", e.Message.JumpLink)); emb.AddField("Location", e.Channel.Mention, inline: true); emb.AddField("Author", e.Message.Author?.Mention ?? _unknown, inline: true); emb.AddField("Before update", $"Created {ctime}\n{bextra}\nContent:{Formatter.BlockCode(FormatterExtensions.StripMarkdown(pcontent))}"); emb.AddField("After update", $"Edited {etime}\n{aextra}\nContent:{Formatter.BlockCode(FormatterExtensions.StripMarkdown(acontent))}"); await logchn.SendMessageAsync(embed : emb.Build()); }
public async Task NsfwAsync(CommandContext ctx, [Description("URL to wrap.")] Uri url, [RemainingText, Description("Additional info")] string info = null) { await ctx.Message.DeleteAsync(); var emb = new DiscordEmbedBuilder { Title = $"{StaticDiscordEmoji.NoEntry} NSFW link from {ctx.Member.DisplayName} {StaticDiscordEmoji.NoEntry}", Description = FormatterExtensions.Spoiler(url.ToString()), Color = DiscordColor.Red }; if (!string.IsNullOrWhiteSpace(info)) { emb.AddField("Additional info", Formatter.BlockCode(FormatterExtensions.StripMarkdown(info))); } await ctx.RespondAsync(embed : emb.Build()); }
public static async Task MessageUpdateEventHandlerAsync(KioskAppShard shard, MessageUpdateEventArgs e) { if (e.Author is null || e.Author.IsBot || e.Channel is null || e.Channel.IsPrivate || e.Message is null) { return; } if (shard.SharedData.BlockedChannels.Contains(e.Channel.Id)) { return; } if (!(e.Message.Content is null) && shard.SharedData.MessageContainsFilter(e.Guild.Id, e.Message.Content)) { try { await e.Message.DeleteAsync("_gf: Filter hit after update"); await e.Channel.SendMessageAsync($"{e.Author.Mention} said: {FormatterExtensions.Spoiler(Formatter.BlockCode(Formatter.Strip(e.Message.Content)))}"); } catch { } } DiscordChannel logchn = shard.SharedData.GetLogChannelForGuild(shard.Client, e.Guild); if (logchn is null || !e.Message.IsEdited) { return; } DiscordMember member = await e.Guild.GetMemberAsync(e.Author.Id); using (DatabaseContext db = shard.Database.CreateContext()) { if (db.LoggingExempts.Any(ee => ee.Type == ExemptedEntityType.Channel && ee.Id == e.Channel.Id)) { return; } if (db.LoggingExempts.Any(ee => ee.Type == ExemptedEntityType.Member && ee.Id == e.Author.Id)) { return; } if (member?.Roles.Any(r => db.LoggingExempts.Any(ee => ee.Type == ExemptedEntityType.Role && ee.Id == r.Id)) ?? false) { return; } } string pcontent = string.IsNullOrWhiteSpace(e.MessageBefore?.Content) ? "" : e.MessageBefore.Content.Truncate(700); string acontent = string.IsNullOrWhiteSpace(e.Message?.Content) ? "" : e.Message.Content.Truncate(700); string ctime = e.Message.CreationTimestamp == null ? _unknown : e.Message.CreationTimestamp.ToUtcTimestamp(); string etime = e.Message.EditedTimestamp is null ? _unknown : e.Message.EditedTimestamp.Value.ToUtcTimestamp(); string bextra = $"Embeds: {e.MessageBefore?.Embeds?.Count ?? 0}, Reactions: {e.MessageBefore?.Reactions?.Count ?? 0}, Attachments: {e.MessageBefore?.Attachments?.Count ?? 0}"; string aextra = $"Embeds: {e.Message.Embeds.Count}, Reactions: {e.Message.Reactions.Count}, Attachments: {e.Message.Attachments.Count}"; DiscordEmbedBuilder emb = FormEmbedBuilder(EventOrigin.Message, "Message updated"); emb.WithDescription(Formatter.MaskedUrl("Jump to message", e.Message.JumpLink)); emb.AddField("Location", e.Channel.Mention, inline: true); emb.AddField("Author", e.Message.Author?.Mention ?? _unknown, inline: true); emb.AddField("Before update", $"Created {ctime}\n{bextra}\nContent:{Formatter.BlockCode(Formatter.Strip(pcontent))}"); emb.AddField("After update", $"Edited {etime}\n{aextra}\nContent:{Formatter.BlockCode(Formatter.Strip(acontent))}"); await logchn.SendMessageAsync(embed : emb.Build()); }