using BotPages.Core; using BotPages.Core.Abstractions; using BotPages.Core.Logging; using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; using Telegram.Bot; using Telegram.Bot.Types; namespace BotPages.Telegram; /// /// Внутренний билдер альбомов (медиагрупп) для Telegram. /// public sealed class TelegramAlbumBuilder : IAlbumBuilder { private readonly TelegramAdapter _adapter; private readonly PageContext _ctx; private readonly ILogger _logger; private readonly TelegramBotClient? _client; private readonly List<(FileDescriptor file, string? caption, MessageFormat? captionFormat)> _items = new(); /// Создать билдер альбома. public TelegramAlbumBuilder(TelegramAdapter adapter, PageContext ctx, ILogger logger, TelegramBotClient? client) { _adapter = adapter; _ctx = ctx; _logger = logger; _client = client; } /// public IAlbumBuilder Add(FileDescriptor file, string? caption = null, MessageFormat? captionFormat = null) { _items.Add((file, caption, captionFormat)); return this; } /// public async Task SendAsync(CancellationToken ct = default) { if (_client is null) { _logger.Log(LogLevel.Critical, "Telegram client is not initialized."); return; } var chatId = long.Parse(_ctx.Update.Chat.Id); if (!_adapter.Capabilities.SupportsAlbums) { _logger.Log(LogLevel.Warn, "Albums not supported. Degraded to sequential sends."); foreach (var (file, caption, captionFormat) in _items) await _adapter.SendFileAsync(_ctx.Update.Chat.Id, file, caption, captionFormat, ct: ct); return; } var media = new List(); foreach (var (file, caption, captionFormat) in _items) { Stream? stream = null; if (file.GetStreamAsync is not null) { stream = await file.GetStreamAsync(ct); } InputFile inputFile; if (stream is not null && stream != Stream.Null) { inputFile = new InputFileStream(stream, file.Name); } else if (file.Id.StartsWith("http://") || file.Id.StartsWith("https://")) { inputFile = new InputFileUrl(file.Id); } else { inputFile = new InputFileId(file.Id); } IAlbumInputMedia? m = file.Kind switch { FileKind.Audio => new InputMediaAudio(inputFile) { Caption = caption ?? "" }, FileKind.Document => new InputMediaDocument(inputFile) { Caption = caption ?? "" }, FileKind.Photo => new InputMediaPhoto(inputFile) { Caption = caption ?? "" }, FileKind.Video => new InputMediaVideo(inputFile) { Caption = caption ?? "" }, _ => null }; if (m is not null) media.Add(m); else { // Telegram не поддерживает document в альбомах — деградация _logger.Log(LogLevel.Warn, $"Document '{file.Kind}' in album not supported. Sending document separately."); await _adapter.SendFileAsync(_ctx.Update.Chat.Id, file, caption, captionFormat, ct: ct); } } if (media.Count > 0) await _client.SendMediaGroup(chatId, media, cancellationToken: ct); } }