diff --git a/modules/CodeWatcher/CodeWatcher.cs b/modules/CodeWatcher/CodeWatcher.cs index 0dfe046..d759347 100644 --- a/modules/CodeWatcher/CodeWatcher.cs +++ b/modules/CodeWatcher/CodeWatcher.cs @@ -1,9 +1,17 @@ -using Kruzya.TelegramBot.Core; +using System.Collections.Concurrent; +using Kruzya.TelegramBot.Core; +using Microsoft.Extensions.DependencyInjection; namespace West.TelegramBot.CodeWatcher { public class CodeWatcher : Module { public CodeWatcher(Core core) : base(core) {} + + public override void ConfigureServices(IServiceCollection services) + { + services.AddSingleton>(); + services.AddHostedService(); + } } } \ No newline at end of file diff --git a/modules/CodeWatcher/DeleteRequest.cs b/modules/CodeWatcher/DeleteRequest.cs new file mode 100644 index 0000000..6f6c82b --- /dev/null +++ b/modules/CodeWatcher/DeleteRequest.cs @@ -0,0 +1,10 @@ +using Telegram.Bot.Types; + +namespace West.TelegramBot.CodeWatcher; + +public class DeleteRequest +{ + public ChatId ChatId { get; set; } + public int MessageId { get; set; } + public DateTime DeleteAt { get; set; } +} \ No newline at end of file diff --git a/modules/CodeWatcher/DeleteService.cs b/modules/CodeWatcher/DeleteService.cs new file mode 100644 index 0000000..42a0a4c --- /dev/null +++ b/modules/CodeWatcher/DeleteService.cs @@ -0,0 +1,59 @@ +using System.Collections.Concurrent; +using BotFramework.Abstractions; +using Kruzya.TelegramBot.Core.Service; +using Microsoft.Extensions.Logging; +using Telegram.Bot; +using Telegram.Bot.Exceptions; + +namespace West.TelegramBot.CodeWatcher; + +public class DeleteService : AbstractTimedHostedService +{ + private readonly ConcurrentBag _deleteRequests; + protected override TimeSpan TimerPeriod => TimeSpan.FromSeconds(10); + + public DeleteService(ILogger logger, IBotInstance bot, ConcurrentBag deleteRequests) : base(logger, + bot) + { + _deleteRequests = deleteRequests; + } + + protected override async Task OnRun() + { + var now = DateTime.Now; + var skippedRequestList = new List(); + + _logger.LogDebug("Spinning up the delete requests loop. Request count: {RequestCount}", _deleteRequests.Count); + for (var i = 0; i < _deleteRequests.Count; i++) + { + if (!_deleteRequests.TryTake(out var request)) + { + _logger.LogDebug("Nothing to take, breaking..."); + break; + } + + if (request.DeleteAt < now) + { + try + { + await _bot.BotClient.DeleteMessageAsync(request.ChatId, request.MessageId); + } + catch (ApiRequestException e) + { + _logger.LogError("Error deleting message, code - {ErrorCode}, msg - {ErrorMessage}", e.ErrorCode, + e.Message); + } + } + else + { + _logger.LogDebug("Skipping {MessageId}", request.MessageId); + skippedRequestList.Add(request); + } + } + + foreach (var request in skippedRequestList) + { + _deleteRequests.Add(request); + } + } +} \ No newline at end of file diff --git a/modules/CodeWatcher/Handler.cs b/modules/CodeWatcher/Handler.cs index 81ba20c..3abeaa8 100644 --- a/modules/CodeWatcher/Handler.cs +++ b/modules/CodeWatcher/Handler.cs @@ -1,4 +1,5 @@ -using BotFramework; +using System.Collections.Concurrent; +using BotFramework; using BotFramework.Attributes; using BotFramework.Enums; using Kruzya.TelegramBot.Core.Extensions; @@ -10,12 +11,19 @@ namespace West.TelegramBot.CodeWatcher; public class Handler : BotEventHandler { - [Message(InChat.Public, MessageFlag.HasText)] + private readonly ConcurrentBag _requests; + + public Handler(ConcurrentBag requests) + { + _requests = requests; + } + + [Update(InChat.Public, UpdateFlag.Message | UpdateFlag.EditedMessage)] public async Task HandleMessage() { - var message = RawUpdate.Message!; + var message = RawUpdate.Message ?? RawUpdate.EditedMessage; - if (message.Entities == null) + if (message?.Entities == null) { return; } @@ -34,6 +42,11 @@ public class Handler : BotEventHandler .SplitToLines() .ToList(); + if (entityLines.Count < 2) + { + continue; + } + if (entityLines.Count >= 20 || entityLines.Any(line => line.Length > 160)) { await DeleteAndNotifyAsync(message); @@ -46,12 +59,17 @@ public class Handler : BotEventHandler public async Task DeleteAndNotifyAsync(Message message) { await Bot.DeleteMessageAsync(Chat.Id, message.MessageId); - var notifyMsg = await Bot.SendTextMessageAsync(Chat.Id, + var notifyMsg = await Bot.SendTextMessageAsync(Chat.Id, (message.From?.ToHtml() ?? "") + ", не стоит публиковать столь большой код прямо в чат. " + "Вместо этого загрузите его на https://pastebin.com и отправьте в виде ссылки.", ParseMode.Html); - - await Task.Delay(TimeSpan.FromMinutes(1)); - await Bot.DeleteMessageAsync(Chat.Id, notifyMsg.MessageId); + + // TODO: maybe write a wrapper-service around collection to avoid direct interactions with the collection, West, 07.07.2022, 16:53 + _requests.Add(new DeleteRequest + { + ChatId = notifyMsg.Chat.Id, + MessageId = notifyMsg.MessageId, + DeleteAt = DateTime.Now.AddSeconds(30) + }); } } \ No newline at end of file