using DailyDigestWorker.Configuration; // Для TelegramClientSettings using Microsoft.Extensions.Options; // Для IOptions using TL; // Основное пространство имен WTelegramClient для типов Telegram API using WTelegram; // Для Client namespace DailyDigestWorker.Services { public class TelegramChannelReader : ITelegramChannelReader // Реализуем интерфейс { private readonly ILogger _logger; private readonly Client _client; // Наш Singleton WTelegramClient private readonly TelegramClientSettings _settings; private InputPeer? _targetPeer; // Кэшированный InputPeer канала // Внедряем зависимости public TelegramChannelReader( ILogger logger, Client client, // Внедряем WTelegramClient IOptions settingsOptions) { _logger = logger; _client = client; _settings = settingsOptions.Value; } public async Task?> GetRecentNewsAsync(int maxAgeHours, int limit, CancellationToken cancellationToken) { _logger.LogInformation("Попытка чтения новостей из канала {ChannelUsername}...", _settings.TargetChannelUsername); try { _logger.LogDebug("Шаг 1: Проверка/выполнение авторизации пользователя..."); // Добавляем try-catch вокруг LoginUserIfNeeded для более детального логгирования User? currentUser = null; try { currentUser = await _client.LoginUserIfNeeded(); // Может запросить ввод в консоль! } catch (Exception loginEx) { _logger.LogError(loginEx, "Ошибка во время выполнения LoginUserIfNeeded."); return null; // Выходим, если логин не удался } if (currentUser == null) { _logger.LogError("Авторизация не удалась (LoginUserIfNeeded вернул null или выбросил исключение)."); return null; } _logger.LogInformation("Шаг 1 Успех: Авторизация как {UserFirstName} (ID: {UserId})", currentUser.first_name, currentUser.id); // 2. Найти канал (получить InputPeer) - кэшируем результат if (_targetPeer == null) { _logger.LogDebug("Шаг 2: Поиск InputPeer для канала {ChannelUsername}...", _settings.TargetChannelUsername); var resolved = await _client.Contacts_ResolveUsername(_settings.TargetChannelUsername); if (resolved?.UserOrChat is Channel channel) { _targetPeer = channel.ToInputPeer(); _logger.LogInformation("Шаг 2 Успех: Найден InputPeer для канала '{ChannelTitle}' (ID: {ChannelId})", channel.title, channel.id); } else { _logger.LogError("Шаг 2 Ошибка: Не удалось найти канал по юзернейму {ChannelUsername} или это не канал. Resolved: {@Resolved}", _settings.TargetChannelUsername, resolved); return null; } } else { _logger.LogDebug("Шаг 2: Используется кэшированный InputPeer для канала."); } // 3. Получить историю сообщений _logger.LogDebug("Шаг 3: Запрос истории сообщений (limit={Limit})...", limit); var history = await _client.Messages_GetHistory(_targetPeer, limit: limit); if (history == null) { _logger.LogWarning("Шаг 3 Ошибка: Не удалось получить историю сообщений (результат null)."); return null; } _logger.LogInformation("Шаг 3 Успех: Получено {Count} сообщений/элементов в истории.", history.Messages.Length); // 4. Отфильтровать сообщения по дате и извлечь текст _logger.LogDebug("Шаг 4: Фильтрация сообщений новее {CutoffDateUtc} UTC...", DateTime.UtcNow.AddHours(-maxAgeHours)); var newsTexts = new List(); var cutoffDate = DateTime.UtcNow.AddHours(-maxAgeHours); foreach (var msgBase in history.Messages) { if (msgBase is Message message) { if (message.Date >= cutoffDate) { if (!string.IsNullOrWhiteSpace(message.message)) { newsTexts.Add(message.message); // Уменьшим детальность этого лога, чтобы не засорять вывод // _logger.LogDebug(" + Добавлено сообщение от {MessageDate:yyyy-MM-dd HH:mm} UTC (ID: {MessageId})", message.Date, message.id); } } else { _logger.LogDebug("Достигнуто сообщение старше {CutoffDateUtc} UTC, остановка фильтрации.", cutoffDate); break; } } } _logger.LogInformation("Шаг 4 Успех: Найдено {Count} новостных сообщений за последние {Hours} часов.", newsTexts.Count, maxAgeHours); newsTexts.Reverse(); return newsTexts; } // ... (остальные catch блоки без изменений) ... catch (RpcException e) { _logger.LogError(e, "Ошибка Telegram API ({ErrorCode}): {ErrorMessage}", e.Code, e.Message); if (e.Code == 420) { _logger.LogWarning("Получен FloodWait на {Seconds} секунд. Пропускаем цикл чтения новостей.", e.X); } return null; } catch (Exception ex) { _logger.LogError(ex, "Неожиданная ошибка при чтении новостей из Telegram канала."); return null; } } } }