public async Task HandleAsync(MessageReceivedEventArgs args)
        {
            if (!(args.Message is CachedUserMessage message))
            {
                return;
            }

            using var ctx = new AdminDatabaseContext(_provider);
            if (string.IsNullOrWhiteSpace(message.Content) || message.Author.IsBot ||
                !(message.Channel is CachedTextChannel channel))
            {
                return;
            }

            var completedHighlights = new List <ulong>();

            foreach (var highlight in ctx.Highlights.Where(x => x.UserId != message.Author.Id &&
                                                           Regex.IsMatch(message.Content, $@"\b{x.Text}\b", RegexOptions.IgnoreCase)))
            {
                if (completedHighlights.Contains(highlight.UserId) ||
                    highlight.GuildId.HasValue && highlight.GuildId != channel.Guild.Id)
                {
                    continue;
                }

                if (channel.Guild.GetMember(highlight.UserId) is { } member&&
                    member.GetPermissionsFor(channel).ViewChannel&&
                    channel.GetMessages().OrderByDescending(x => x.Id)
                    .Where(x => DateTimeOffset.UtcNow - x.Id.CreatedAt < TimeSpan.FromMinutes(15))
                    .Take(50).All(x => x.Author.Id != highlight.UserId))
                {
                    var user = await ctx.GetOrCreateGlobalUserAsync(highlight.UserId);

                    if (user.HighlightBlacklist.Contains(message.Author.Id) ||
                        user.HighlightBlacklist.Contains(message.Channel.Id))
                    {
                        continue;
                    }

                    var target = await _client.GetUserAsync(highlight.UserId);

                    var builder = new LocalEmbedBuilder()
                                  .WithSuccessColor()
                                  .WithAuthor(_localization.Localize(user.Language, "highlight_trigger_author",
                                                                     message.Author.Tag, message.Channel), message.Author.GetAvatarUrl())
                                  .WithDescription(new StringBuilder()
                                                   .AppendNewline(message.Content.TrimTo(LocalEmbedBuilder.MAX_DESCRIPTION_LENGTH - 50))
                                                   .AppendNewline()
                                                   .AppendNewline($"[{_localization.Localize(user.Language, "info_jumpmessage")}]({message.JumpUrl})")
                                                   .ToString())
                                  .WithTimestamp(message.Id.CreatedAt);

                    _ = target.SendMessageAsync(_localization.Localize(user.Language, "highlight_trigger_text",
                                                                       channel.Guild.Name.Sanitize()), embed: builder.Build());

                    completedHighlights.Add(highlight.UserId);
                }
            }
        }
Esempio n. 2
0
        private async Task SendRemindersAsync()
        {
            using var ctx = new AdminDatabaseContext(_provider);
            var now = DateTimeOffset.UtcNow;

            foreach (var reminder in ctx.Reminders.Where(x => now >= x.Ending))
            {
                var user = await _client.GetOrDownloadUserAsync(reminder.AuthorId);

                var language = reminder.GuildId.HasValue
                    ? (await ctx.GetOrCreateGuildAsync(reminder.GuildId.Value)).Language
                    : (await ctx.GetOrCreateGlobalUserAsync(reminder.AuthorId)).Language;

                var builder = new LocalEmbedBuilder()
                              .WithSuccessColor()
                              .WithDescription(string.Join('\n',
                                                           (reminder.Text ?? string.Empty).TrimTo(LocalEmbedBuilder.MAX_DESCRIPTION_LENGTH - 50),
                                                           Markdown.Link(_localization.Localize(language, "info_jumpmessage"),
                                                                         $"https://discordapp.com/channels/{reminder.GuildId?.ToString() ?? "@me"}/{reminder.ChannelId}/{reminder.MessageId}")));

                try
                {
                    if (!reminder.GuildId.HasValue)
                    {
                        await user.SendMessageAsync(
                            _localization.Localize(language, "reminder_trigger",
                                                   (reminder.Ending - reminder.CreatedAt).HumanizeFormatted(_localization, language,
                                                                                                            TimeUnit.Second, true)), embed : builder.Build());

                        continue;
                    }

                    await _client.GetGuild(reminder.GuildId.Value).GetTextChannel(reminder.ChannelId).SendMessageAsync(
                        _localization.Localize(language, "reminder_trigger",
                                               (reminder.Ending - reminder.CreatedAt).HumanizeFormatted(_localization, language,
                                                                                                        TimeUnit.Second, true)), embed: builder.Build());
                }
                catch { /* ignored */ }
                finally
                {
                    ctx.Reminders.Remove(reminder);
                }
            }

            await ctx.SaveChangesAsync();
        }
        public async Task LogAppealAsync(IUser target, CachedGuild guild, RevocablePunishment punishment)
        {
            using var ctx = new AdminDatabaseContext(_provider);

            var guildConfig = await ctx.GetOrCreateGuildAsync(guild.Id);

            if (!guildConfig.Settings.HasFlag(GuildSettings.Punishments))
            {
                return;
            }
            if (!(await ctx.GetLoggingChannelAsync(guild.Id, LogType.Appeal) is CachedTextChannel logChannel))
            {
                return;
            }

            await logChannel.SendMessageAsync(embed : new LocalEmbedBuilder()
                                              .WithSuccessColor()
                                              .WithTitle(_localization.Localize(guildConfig.Language,
                                                                                $"punishment_{punishment.GetType().Name.ToLower()}") +
                                                         $" - {_localization.Localize(guildConfig.Language, "punishment_case", punishment.Id)}")
                                              .WithDescription(_localization.Localize(guildConfig.Language, "punishment_appeal_description_guild",
                                                                                      target.Format()))
                                              .AddField("title_reason", punishment.AppealReason)
                                              .WithTimestamp(punishment.AppealedAt.Value).Build());
        }
Esempio n. 4
0
        public async Task HandleAsync(MessageUpdatedEventArgs args)
        {
            if (!(args.Channel is CachedTextChannel channel) ||
                !args.OldMessage.HasValue ||                                                            // TODO: What to do when message doesn't have value, other than ignore
                args.OldMessage.Value.Content?.Equals(args.NewMessage.Content ?? string.Empty) == true) // message content is identical
            {
                return;
            }

            using var ctx = new AdminDatabaseContext(_provider);
            var guild = await ctx.GetOrCreateGuildAsync(channel.Guild.Id);

            if (!(await ctx.GetLoggingChannelAsync(channel.Guild.Id, LogType.MessageUpdate) is { } logChannel))
            {
                return;
            }

            var builder = new LocalEmbedBuilder()
                          .WithErrorColor()
                          .WithTitle(_localization.Localize(guild.Language, "logging_message_update", channel.Tag))
                          .WithDescription(args.NewMessage.Author.Format(false))
                          .AddField(_localization.Localize(guild.Language, "info_id"), args.NewMessage.Id)
                          .WithTimestamp(DateTimeOffset.UtcNow);

            if (!string.IsNullOrWhiteSpace(args.OldMessage.Value.Content))
            {
                builder.AddField(_localization.Localize(guild.Language, "logging_message_update_oldcontent"),
                                 args.OldMessage.Value.Content.TrimTo(1024, true));
            }

            if (!string.IsNullOrWhiteSpace(args.NewMessage.Content))
            {
                builder.AddField(_localization.Localize(guild.Language, "logging_message_update_newcontent"),
                                 args.NewMessage.Content.TrimTo(1024, true));
            }

            await logChannel.SendMessageAsync(embed : builder.Build());
        }
Esempio n. 5
0
        public async Task HandleAsync(ReactionAddedEventArgs args)
        {
            if (!(args.Channel is CachedTextChannel channel))
            {
                return;
            }

            if (args.User.HasValue && args.User.Value.IsBot)
            {
                return;
            }

            using var ctx = new AdminDatabaseContext(_provider);
            var star = await ctx.GetSpecialEmojiAsync(channel.Guild.Id, EmojiType.Star);

            if (!args.Emoji.Equals(star))
            {
                return;
            }

            if (!(await ctx.GetLoggingChannelAsync(channel.Guild.Id, LogType.Starboard) is { } starboardChannel))
            {
                return;
            }

            var guild = await ctx.GetOrCreateGuildAsync(channel.Guild.Id);

            if (guild.BlacklistedStarboardIds.ContainsAny(channel.Id.RawValue, args.User.Id.RawValue))
            {
                return;
            }

            var message = args.Message.HasValue
                ? args.Message.Value as IUserMessage
                : await args.Message.Downloadable.DownloadAsync() as IUserMessage;

            if (message is null)
            {
                return;
            }

            if (!(await ctx.Starboard.FirstOrDefaultAsync(x => x.MessageId == message.Id ||
                                                          x.EntryMessageId == message.Id) is { } entry))
            {
                var stars = (await message.GetReactionsAsync(star)).Select(x => x.Id.RawValue).ToList();
                stars = stars.Where(x => !guild.BlacklistedStarboardIds.Contains(x)).ToList();

                if (stars.Count >= guild.MinimumStars)
                {
                    var entryMessage = await starboardChannel.SendMessageAsync(
                        $"{star} {stars.Count} `#{channel.Name}` {_localization.Localize(guild.Language, "info_id")}: `{message.Id}`",
                        embed : new LocalEmbedBuilder()
                        .WithSuccessColor()
                        .WithAuthor(message.Author)
                        .WithDescription(new StringBuilder()
                                         .AppendNewline((message.Content ?? message.Embeds.FirstOrDefault()?.Description)?
                                                        .TrimTo(LocalEmbedBuilder.MAX_DESCRIPTION_LENGTH - 50))
                                         .AppendNewline()
                                         .AppendNewline(Markdown.Link(_localization.Localize(guild.Language, "info_jumpmessage"),
                                                                      $"https://discordapp.com/channels/{channel.Guild.Id}/{channel.Id}/{message.Id}"))
                                         .ToString())
                        .WithImageUrl(
                            message.Attachments.FirstOrDefault(x => x.FileName.HasImageExtension(out _))?.Url ??
                            message.Embeds.FirstOrDefault()?.Image?.Url)
                        .WithTimestamp(message.Id.CreatedAt)
                        .Build());

                    ctx.Starboard.Add(new StarboardEntry(message.Id, message.ChannelId, channel.Guild.Id,
                                                         message.Author.Id, stars, entryMessage.Id, entryMessage.ChannelId));
                    await ctx.SaveChangesAsync();
                }

                return;
            }

            if (entry.Stars.Contains(args.User.Id))
            {
                return;
            }

            entry.Stars.Add(args.User.Id);
            ctx.Starboard.Update(entry);
            await ctx.SaveChangesAsync();

            await starboardChannel.ModifyMessageAsync(entry.EntryMessageId,
                                                      x => x.Content = $"{star} {entry.Stars.Count} `#{channel.Name}` {_localization.Localize(guild.Language, "info_id")}: `{message.Id}`");
        }