using System; using System.Collections.Concurrent; using System.Text; using System.Threading.Tasks; using BotFramework.Abstractions; using Kruzya.TelegramBot.Core.Service; using Microsoft.Extensions.Logging; using Telegram.Bot; using Telegram.Bot.Exceptions; using Telegram.Bot.Types; namespace Kruzya.TelegramBot.RichSiteSummary.Service; public class MessageSender : AbstractTimedHostedService { protected override TimeSpan TimerPeriod => TimeSpan.FromSeconds(1); protected readonly ConcurrentQueue Queue; protected readonly ConcurrentQueue UnsubscribeQueue; public MessageSender(ILogger logger, IBotInstance bot, ConcurrentQueue userMessageQueue, ConcurrentQueue userUnsubscribeQueue) : base(logger, bot) { UnsubscribeQueue = userUnsubscribeQueue; Queue = userMessageQueue; } protected override async Task OnRun() { if (Queue.IsEmpty || !Queue.TryDequeue(out var message)) { return; } _logger.LogDebug("Message for {ChatId} dequeued.", message.ChatId.Identifier); try { if (string.IsNullOrWhiteSpace(message.ImageUrl)) { await _bot.BotClient.SendMessage(message.ChatId, message.Text, message.ParseMode, linkPreviewOptions: message.DisableWebPagePreview); } else { await _bot.BotClient.SendPhoto(message.ChatId, new InputFileUrl(message.ImageUrl), message.Text, message.ParseMode); } } catch (ApiRequestException e) { _logger.LogDebug("Message for {ChatId} is failed: {error}.", message.ChatId.Identifier, e.Message); if (!e.Message.Contains("bot was blocked by user")) { ReEnqueue(message, e, message.ChatId); // looks like a network issue return; } // User added bot to blacklist. // Unsubscribe him. UnsubscribeQueue.Enqueue(new UserUnsubscribe { ChatId = message.ChatId }); } catch (Exception e) { _logger.LogDebug("Message for {ChatId} is failed: {error}.", message.ChatId.Identifier, e.Message); ReEnqueue(message, e); } } private void ReEnqueue(UserMessage message, Exception e = null, ChatId chatId = null) { if (e != null) { var eMessage = new StringBuilder(); eMessage.Append(e.Message); if (chatId != null) { eMessage.Append($" ({chatId.Identifier})"); } _logger.LogError(eMessage.ToString()); } Queue.Enqueue(message); } }