From d6f54bb0e6e516e9394e6ff3fc042fa29b0510ad Mon Sep 17 00:00:00 2001 From: FrigaT Date: Sun, 7 Dec 2025 08:26:45 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=20=D0=BA=D0=BD=D0=BE?= =?UTF-8?q?=D0=BF=D0=BE=D0=BA=20=D0=B4=D0=BB=D1=8F=20=D1=84=D0=B0=D0=B9?= =?UTF-8?q?=D0=BB=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Abstractions/IMessengerAdapter.cs | 23 +++++--- .../Context/PageContextAdapterExtensions.cs | 27 ++++++---- BotPages.Core/Messaging/MessageBuilder.cs | 16 ++++-- BotPages.Telegram/TelegramAdapter.cs | 54 +++++++++++++++---- BotPages.Telegram/TelegramAlbumBuilder.cs | 4 +- Demo/Pages/FilesPage.cs | 2 +- 6 files changed, 93 insertions(+), 33 deletions(-) diff --git a/BotPages.Core/Abstractions/IMessengerAdapter.cs b/BotPages.Core/Abstractions/IMessengerAdapter.cs index 5ba9c22..284bd95 100644 --- a/BotPages.Core/Abstractions/IMessengerAdapter.cs +++ b/BotPages.Core/Abstractions/IMessengerAdapter.cs @@ -9,22 +9,33 @@ namespace BotPages.Core.Abstractions; /// public interface IMessengerAdapter { + /// + /// Доступные возможности мессенджера. + /// Capabilities Capabilities { get; } /// /// Отправить текстовое сообщение в чат. /// - Task SendTextAsync(string chatId, string text, MessageFormat format, - IEnumerable>? inline, - IEnumerable>? reply, - string? messageId, - CancellationToken ct + Task SendTextAsync(string chatId, + string text, + MessageFormat format = MessageFormat.Plain, + IEnumerable>? inline = null, + IEnumerable>? reply = null, + string? messageId = null, + CancellationToken ct = default ); /// /// Отправить файл в чат. /// - Task SendFileAsync(string chatId, FileDescriptor file, string? caption, MessageFormat? captionFormat, CancellationToken ct); + Task SendFileAsync(string chatId, + FileDescriptor file, + string? caption = null, + MessageFormat? captionFormat = null, + IEnumerable>? inline = null, + IEnumerable>? reply = null, + CancellationToken ct = default); /// /// Создать билдер альбома для отправки медиагруппы. diff --git a/BotPages.Core/Context/PageContextAdapterExtensions.cs b/BotPages.Core/Context/PageContextAdapterExtensions.cs index 4024791..c17e79d 100644 --- a/BotPages.Core/Context/PageContextAdapterExtensions.cs +++ b/BotPages.Core/Context/PageContextAdapterExtensions.cs @@ -11,7 +11,9 @@ public static class PageContextAdapterExtensions /// /// Отправить текстовое сообщение. /// - public static Task SendTextAsync(this PageContext ctx, string text, MessageFormat format = MessageFormat.Plain, + public static Task SendTextAsync(this PageContext ctx, + string text, + MessageFormat format = MessageFormat.Plain, IEnumerable>? inline = null, IEnumerable>? reply = null, string? messageId = null, @@ -21,12 +23,19 @@ public static class PageContextAdapterExtensions /// /// Отправить файл. /// - public static Task SendFileAsync(this PageContext ctx, FileDescriptor file, string? caption = null, MessageFormat? captionFormat = null, CancellationToken ct = default) - => ctx.Adapter.SendFileAsync(ctx.Update.Chat.Id, file, caption, captionFormat, ct); - - /// - /// Отправить файл. - /// - public static Task SendFileAsync(this PageContext ctx, FileDescriptor file, string? caption = null, CancellationToken ct = default) - => ctx.Adapter.SendFileAsync(ctx.Update.Chat.Id, file, caption, null, ct); + public static Task SendFileAsync(this PageContext ctx, + FileDescriptor file, + string? caption = null, + MessageFormat? captionFormat = null, + IEnumerable>? inline = null, + IEnumerable>? reply = null, + CancellationToken ct = default + ) + => ctx.Adapter.SendFileAsync(chatId: ctx.Update.Chat.Id, + file: file, + caption: caption, + captionFormat: captionFormat, + inline: inline, + reply: reply, + ct: ct); } \ No newline at end of file diff --git a/BotPages.Core/Messaging/MessageBuilder.cs b/BotPages.Core/Messaging/MessageBuilder.cs index c401f06..4615dcd 100644 --- a/BotPages.Core/Messaging/MessageBuilder.cs +++ b/BotPages.Core/Messaging/MessageBuilder.cs @@ -123,19 +123,25 @@ public sealed class MessageBuilder { string? messageId = null; + List>? reply = null; + if (_disableReplyKeyboard) reply = new(); + else if (_reply.Any()) reply = _reply; + // Текст if (!string.IsNullOrWhiteSpace(_text)) { - List>? reply = null; - if (_disableReplyKeyboard) reply = new(); - else if (_reply.Any()) reply = _reply; - messageId = await _ctx.SendTextAsync(_text, _format, _inline, reply, _editMessageId, ct); } // Файлы foreach (var (file, caption, captionFormat) in _files) - await _ctx.SendFileAsync(file, caption, captionFormat, ct); + await _ctx.SendFileAsync(file: file + , caption: caption + , captionFormat: captionFormat + , reply: reply + , inline: _inline + , ct: ct + ); // Альбом if (_album.Count > 0) diff --git a/BotPages.Telegram/TelegramAdapter.cs b/BotPages.Telegram/TelegramAdapter.cs index 62065a4..5851db6 100644 --- a/BotPages.Telegram/TelegramAdapter.cs +++ b/BotPages.Telegram/TelegramAdapter.cs @@ -85,11 +85,12 @@ public sealed class TelegramAdapter : IMessangerAdapterSetup } /// - public async Task SendTextAsync(string chatId, string text, MessageFormat format, - IEnumerable>? inline, - IEnumerable>? reply, - string? messageId, - CancellationToken ct) + public async Task SendTextAsync(string chatId, string text, + MessageFormat format = MessageFormat.Plain, + IEnumerable>? inline = null, + IEnumerable>? reply = null, + string? messageId = null, + CancellationToken ct = default) { if (_client is null) { @@ -187,7 +188,14 @@ public sealed class TelegramAdapter : IMessangerAdapterSetup } /// - public async Task SendFileAsync(string chatId, FileDescriptor file, string? caption, MessageFormat? captionFormat, CancellationToken ct) + public async Task SendFileAsync(string chatId, + FileDescriptor file, + string? caption = null, + MessageFormat? captionFormat = null, + IEnumerable>? inline = null, + IEnumerable>? reply = null, + CancellationToken ct = default + ) { if (_client is null) { @@ -249,20 +257,46 @@ public sealed class TelegramAdapter : IMessangerAdapterSetup } } + ReplyMarkup? markup = null; + + if (inline is not null && inline.Any()) + { + markup = new InlineKeyboardMarkup( + inline.Select(row => row.Select(b => new InlineKeyboardButton(b.Label, b.Value)).ToArray()) + .ToArray() + ); + } + else if (reply is not null) + { + if (reply.Any()) + { + markup = new ReplyKeyboardMarkup( + reply.Select(row => row.Select(b => new KeyboardButton(b.Label)).ToArray()).ToArray() + ) + { + ResizeKeyboard = true + }; + } + else + { + markup = new ReplyKeyboardRemove(); + } + } + // В зависимости от FileKind выбираем подходящий метод switch (file.Kind) { case FileKind.Photo: - await _client.SendPhoto(long.Parse(chatId), inputFile, caption ?? "", parseMode, cancellationToken: ct); + await _client.SendPhoto(long.Parse(chatId), inputFile, caption ?? "", parseMode, replyMarkup: markup, cancellationToken: ct); break; case FileKind.Video: - await _client.SendVideo(long.Parse(chatId), inputFile, caption: caption ?? "", parseMode, cancellationToken: ct); + await _client.SendVideo(long.Parse(chatId), inputFile, caption: caption ?? "", parseMode, replyMarkup: markup, cancellationToken: ct); break; case FileKind.Audio: - await _client.SendAudio(long.Parse(chatId), inputFile, caption ?? "", parseMode, cancellationToken: ct); + await _client.SendAudio(long.Parse(chatId), inputFile, caption ?? "", parseMode, replyMarkup: markup, cancellationToken: ct); break; default: - await _client.SendDocument(long.Parse(chatId), inputFile, caption ?? "", parseMode, cancellationToken: ct); + await _client.SendDocument(long.Parse(chatId), inputFile, caption ?? "", parseMode, replyMarkup: markup, cancellationToken: ct); break; } } diff --git a/BotPages.Telegram/TelegramAlbumBuilder.cs b/BotPages.Telegram/TelegramAlbumBuilder.cs index f204eec..3d2192b 100644 --- a/BotPages.Telegram/TelegramAlbumBuilder.cs +++ b/BotPages.Telegram/TelegramAlbumBuilder.cs @@ -53,7 +53,7 @@ public sealed class TelegramAlbumBuilder : IAlbumBuilder { _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); + await _adapter.SendFileAsync(_ctx.Update.Chat.Id, file, caption, captionFormat, ct: ct); return; } @@ -95,7 +95,7 @@ public sealed class TelegramAlbumBuilder : IAlbumBuilder { // 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); + await _adapter.SendFileAsync(_ctx.Update.Chat.Id, file, caption, captionFormat, ct: ct); } } diff --git a/Demo/Pages/FilesPage.cs b/Demo/Pages/FilesPage.cs index 392403c..10e89dc 100644 --- a/Demo/Pages/FilesPage.cs +++ b/Demo/Pages/FilesPage.cs @@ -20,7 +20,7 @@ public sealed class FilesPage : SingletonPage { foreach (var file in files) { - await ctx.SendFileAsync(file, $"Файл '{file.Name}' получен и отправлен обратно.", ct); + await ctx.SendFileAsync(file, $"Файл '{file.Name}' получен и отправлен обратно.", ct: ct); } //Обращение через Storage