daily_digest/Services/TelegramChannelReader.cs
2025-04-12 00:27:03 +07:00

132 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<TelegramChannelReader> _logger;
private readonly Client _client; // Наш Singleton WTelegramClient
private readonly TelegramClientSettings _settings;
private InputPeer? _targetPeer; // Кэшированный InputPeer канала
// Внедряем зависимости
public TelegramChannelReader(
ILogger<TelegramChannelReader> logger,
Client client, // Внедряем WTelegramClient
IOptions<TelegramClientSettings> settingsOptions)
{
_logger = logger;
_client = client;
_settings = settingsOptions.Value;
}
public async Task<List<string>?> 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<string>();
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;
}
}
}
}