diff --git a/BotPages.Core/Abstractions/IMessengerAdapter.cs b/BotPages.Core/Abstractions/IMessengerAdapter.cs
index 6bc9f72..491832e 100644
--- a/BotPages.Core/Abstractions/IMessengerAdapter.cs
+++ b/BotPages.Core/Abstractions/IMessengerAdapter.cs
@@ -1,5 +1,4 @@
using BotPages.Core.Context;
-using BotPages.Core.Messaging;
namespace BotPages.Core.Abstractions;
diff --git a/BotPages.Core/Abstractions/SendRequest.cs b/BotPages.Core/Abstractions/SendRequest.cs
index 08e2376..d009c97 100644
--- a/BotPages.Core/Abstractions/SendRequest.cs
+++ b/BotPages.Core/Abstractions/SendRequest.cs
@@ -4,7 +4,6 @@ namespace BotPages.Core.Abstractions;
///
/// /, .
-/// Core .
///
public sealed class SendRequest
{
diff --git a/BotPages.Core/Context/PageContextAdapterExtensions.cs b/BotPages.Core/Context/PageContextAdapterExtensions.cs
index c316fb0..d1426bb 100644
--- a/BotPages.Core/Context/PageContextAdapterExtensions.cs
+++ b/BotPages.Core/Context/PageContextAdapterExtensions.cs
@@ -1,5 +1,4 @@
using BotPages.Core.Abstractions;
-using BotPages.Core.Messaging;
namespace BotPages.Core;
diff --git a/BotPages.Telegram/TelegramAdapter.cs b/BotPages.Telegram/TelegramAdapter.cs
index 63ee7c6..2119af0 100644
--- a/BotPages.Telegram/TelegramAdapter.cs
+++ b/BotPages.Telegram/TelegramAdapter.cs
@@ -2,6 +2,7 @@
using BotPages.Core.Abstractions;
using BotPages.Core.Context;
using BotPages.Core.Logging;
+using BotPages.Core.Messaging;
using System;
using System.Collections.Generic;
using System.IO;
@@ -114,147 +115,144 @@ public sealed class TelegramAdapter : IMessengerAdapterSetup
var disableNotification = !telegramOptions.NotifyOnSend;
// Build markup
- InlineKeyboardMarkup? inlineMarkup = null;
- ReplyMarkup? markup = null;
+ var inlineMarkup = BuildInlineMarkup(req.Inline);
+ ReplyMarkup? markup = BuildReplyMarkup(req.Reply);
- if (req.Inline is not null && req.Inline.Any())
- {
- inlineMarkup = new InlineKeyboardMarkup(
- req.Inline.Select(row => row.Select(b => new InlineKeyboardButton(b.Label, b.Value)).ToArray()).ToArray()
- );
- }
- else if (req.Reply is not null)
- {
- if (req.Reply.Any())
- {
- markup = new ReplyKeyboardMarkup(req.Reply.Select(row => row.Select(b => new KeyboardButton(b.Label)).ToArray()).ToArray())
- {
- ResizeKeyboard = true
- };
- }
- else
- {
- markup = new ReplyKeyboardRemove();
- }
- }
-
- // Если есть файл - отправить файл
+ // Файлы: сейчас поддерживается один файл через SendRequest.File.
+ // При необходимости для нескольких файлов следует использовать альбомы (CreateAlbumBuilder)
if (req.File is not null)
{
- var file = req.File;
-
- // Получаем поток, если он задан
- Stream? stream = null;
- if (file.GetStreamAsync is not null)
- {
- stream = await file.GetStreamAsync(ct);
- if (stream is not null) stream.Position = 0;
- }
-
- 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);
- }
-
- var parseMode = ParseMode.None;
- switch (req.CaptionFormat)
- {
- case MessageFormat.Html:
- parseMode = ParseMode.Html;
- break;
- case MessageFormat.Markdown:
- parseMode = ParseMode.MarkdownV2;
- break;
- case MessageFormat.Plain:
- case null:
- parseMode = ParseMode.None;
- break;
- }
-
if (inlineMarkup is not null) markup = inlineMarkup;
- Message? sentMessage = req.File.Kind switch
- {
- FileKind.Photo => await _client.SendPhoto(long.Parse(req.ChatId), inputFile, req.Caption ?? "", parseMode, replyMarkup: markup, disableNotification: disableNotification, cancellationToken: ct),
- FileKind.Video => await _client.SendVideo(long.Parse(req.ChatId), inputFile, caption: req.Caption ?? "", parseMode, replyMarkup: markup, disableNotification: disableNotification, cancellationToken: ct),
- FileKind.Audio => await _client.SendAudio(long.Parse(req.ChatId), inputFile, req.Caption ?? "", parseMode, replyMarkup: markup, disableNotification: disableNotification, cancellationToken: ct),
- _ => await _client.SendDocument(long.Parse(req.ChatId), inputFile, req.Caption ?? "", parseMode, replyMarkup: markup, disableNotification: disableNotification, cancellationToken: ct),
- };
-
- return sentMessage?.MessageId.ToString();
+ var sent = await SendFileAsync(req.File, req.ChatId, markup, disableNotification, req.Caption, req.CaptionFormat, ct);
+ return sent?.MessageId.ToString();
}
- // Иначе - отправить текст
+ // Текст
if (!string.IsNullOrWhiteSpace(req.Text))
{
- var format = req.TextFormat ?? MessageFormat.Plain;
- var parseMode = ParseMode.None;
-
- switch (format)
- {
- case MessageFormat.Html:
- parseMode = ParseMode.Html;
- break;
- case MessageFormat.Markdown:
- parseMode = ParseMode.MarkdownV2;
- break;
- case MessageFormat.Plain:
- default:
- parseMode = ParseMode.None;
- break;
- }
-
- // Длина сообщения
- var text = req.Text!;
- if (text.Length > Capabilities.MaxMessageLength)
- {
- _logger.Log(LogLevel.Warn, $"Message too long ({text.Length}). Truncated to {Capabilities.MaxMessageLength}.");
- text = text.Substring(0, Capabilities.MaxMessageLength);
- }
-
- if (!string.IsNullOrWhiteSpace(req.MessageId))
- {
- await _client.EditMessageText(
- messageId: int.Parse(req.MessageId),
- chatId: long.Parse(req.ChatId),
- text: text,
- parseMode: parseMode,
- replyMarkup: inlineMarkup,
- cancellationToken: ct
- );
-
- return req.MessageId;
- }
- else
- {
- if (inlineMarkup is not null) markup = inlineMarkup;
-
- var message = await _client.SendMessage(
- chatId: long.Parse(req.ChatId),
- text: text,
- parseMode: parseMode,
- replyMarkup: markup,
- disableNotification: disableNotification,
- cancellationToken: ct
- );
-
- return message.MessageId.ToString();
- }
+ return await SendTextAsync(req, inlineMarkup, markup, disableNotification, ct);
}
return null;
}
+ // --- Helpers ---
+
+ private InlineKeyboardMarkup? BuildInlineMarkup(IEnumerable>? inline)
+ {
+ if (inline is null || !inline.Any()) return null;
+ return new InlineKeyboardMarkup(
+ inline.Select(row => row.Select(b => new InlineKeyboardButton(b.Label, b.Value)).ToArray()).ToArray()
+ );
+ }
+
+ private ReplyMarkup? BuildReplyMarkup(IEnumerable>? reply)
+ {
+ if (reply is null) return null;
+
+ if (reply.Any())
+ {
+ return new ReplyKeyboardMarkup(reply.Select(row => row.Select(b => new KeyboardButton(b.Label)).ToArray()).ToArray())
+ {
+ ResizeKeyboard = true
+ };
+ }
+ else
+ {
+ return new ReplyKeyboardRemove();
+ }
+ }
+
+ private static ParseMode GetParseMode(MessageFormat? format)
+ {
+ return format switch
+ {
+ MessageFormat.Html => ParseMode.Html,
+ MessageFormat.Markdown => ParseMode.MarkdownV2,
+ _ => ParseMode.None,
+ };
+ }
+
+ private async Task CreateInputFileAsync(FileDescriptor file, CancellationToken ct)
+ {
+ Stream? stream = null;
+ if (file.GetStreamAsync is not null)
+ {
+ stream = await file.GetStreamAsync(ct);
+ if (stream is not null) stream.Position = 0;
+ }
+
+ if (stream is not null && stream != Stream.Null)
+ {
+ return new InputFileStream(stream, file.Name);
+ }
+ else if (file.Id.StartsWith("http://") || file.Id.StartsWith("https://"))
+ {
+ return new InputFileUrl(file.Id);
+ }
+ else
+ {
+ return new InputFileId(file.Id);
+ }
+ }
+
+ private async Task SendFileAsync(FileDescriptor file, string chatId, ReplyMarkup? markup, bool disableNotification, string? caption, MessageFormat? captionFormat, CancellationToken ct)
+ {
+ var inputFile = await CreateInputFileAsync(file, ct);
+ var parseMode = GetParseMode(captionFormat);
+
+ return file.Kind switch
+ {
+ FileKind.Photo => await _client.SendPhoto(long.Parse(chatId), inputFile, caption ?? "", parseMode, replyMarkup: markup, disableNotification: disableNotification, cancellationToken: ct),
+ FileKind.Video => await _client.SendVideo(long.Parse(chatId), inputFile, caption: caption ?? "", parseMode, replyMarkup: markup, disableNotification: disableNotification, cancellationToken: ct),
+ FileKind.Audio => await _client.SendAudio(long.Parse(chatId), inputFile, caption ?? "", parseMode, replyMarkup: markup, disableNotification: disableNotification, cancellationToken: ct),
+ _ => await _client.SendDocument(long.Parse(chatId), inputFile, caption ?? "", parseMode, replyMarkup: markup, disableNotification: disableNotification, cancellationToken: ct),
+ };
+ }
+
+ private async Task SendTextAsync(SendRequest req, InlineKeyboardMarkup? inlineMarkup, ReplyMarkup? markup, bool disableNotification, CancellationToken ct)
+ {
+ var format = req.TextFormat ?? MessageFormat.Plain;
+ var parseMode = GetParseMode(format);
+
+ var text = req.Text!;
+ if (text.Length > Capabilities.MaxMessageLength)
+ {
+ _logger.Log(LogLevel.Warn, $"Message too long ({text.Length}). Truncated to {Capabilities.MaxMessageLength}.");
+ text = text.Substring(0, Capabilities.MaxMessageLength);
+ }
+
+ if (!string.IsNullOrWhiteSpace(req.MessageId))
+ {
+ await _client.EditMessageText(
+ messageId: int.Parse(req.MessageId),
+ chatId: long.Parse(req.ChatId),
+ text: text,
+ parseMode: parseMode,
+ replyMarkup: inlineMarkup,
+ cancellationToken: ct
+ );
+
+ return req.MessageId;
+ }
+ else
+ {
+ if (inlineMarkup is not null) markup = inlineMarkup;
+
+ var message = await _client.SendMessage(
+ chatId: long.Parse(req.ChatId),
+ text: text,
+ parseMode: parseMode,
+ replyMarkup: markup,
+ disableNotification: disableNotification,
+ cancellationToken: ct
+ );
+
+ return message.MessageId.ToString();
+ }
+ }
+
///
public IAlbumBuilder CreateAlbumBuilder(PageContext ctx) => new TelegramAlbumBuilder(this, ctx, _logger, _client);