Чистка кода
All checks were successful
CI / build-test (push) Successful in 52s
Release / pack-and-publish (release) Successful in 42s

This commit is contained in:
FrigaT
2025-12-24 17:09:15 +03:00
parent 4124e8c554
commit 0089926fb0
4 changed files with 125 additions and 130 deletions

View File

@@ -1,5 +1,4 @@
using BotPages.Core.Context; using BotPages.Core.Context;
using BotPages.Core.Messaging;
namespace BotPages.Core.Abstractions; namespace BotPages.Core.Abstractions;

View File

@@ -4,7 +4,6 @@ namespace BotPages.Core.Abstractions;
/// <summary> /// <summary>
/// Óíèâåðñàëüíàÿ ñòðóêòóðà çàïðîñà íà îòïðàâêó ñîîáùåíèÿ/ôàéëà, èñïîëüçóåìàÿ àäàïòåðàìè. /// Óíèâåðñàëüíàÿ ñòðóêòóðà çàïðîñà íà îòïðàâêó ñîîáùåíèÿ/ôàéëà, èñïîëüçóåìàÿ àäàïòåðàìè.
/// Ïîìåùåíà â Core ÷òîáû áûòü äîñòóïíîé äëÿ âñåõ àäàïòåðîâ.
/// </summary> /// </summary>
public sealed class SendRequest public sealed class SendRequest
{ {

View File

@@ -1,5 +1,4 @@
using BotPages.Core.Abstractions; using BotPages.Core.Abstractions;
using BotPages.Core.Messaging;
namespace BotPages.Core; namespace BotPages.Core;

View File

@@ -2,6 +2,7 @@
using BotPages.Core.Abstractions; using BotPages.Core.Abstractions;
using BotPages.Core.Context; using BotPages.Core.Context;
using BotPages.Core.Logging; using BotPages.Core.Logging;
using BotPages.Core.Messaging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@@ -114,147 +115,144 @@ public sealed class TelegramAdapter : IMessengerAdapterSetup
var disableNotification = !telegramOptions.NotifyOnSend; var disableNotification = !telegramOptions.NotifyOnSend;
// Build markup // Build markup
InlineKeyboardMarkup? inlineMarkup = null; var inlineMarkup = BuildInlineMarkup(req.Inline);
ReplyMarkup? markup = null; ReplyMarkup? markup = BuildReplyMarkup(req.Reply);
if (req.Inline is not null && req.Inline.Any()) // Файлы: сейчас поддерживается один файл через SendRequest.File.
{ // При необходимости для нескольких файлов следует использовать альбомы (CreateAlbumBuilder)
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();
}
}
// Если есть файл - отправить файл
if (req.File is not null) 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; if (inlineMarkup is not null) markup = inlineMarkup;
Message? sentMessage = req.File.Kind switch var sent = await SendFileAsync(req.File, req.ChatId, markup, disableNotification, req.Caption, req.CaptionFormat, ct);
{ return sent?.MessageId.ToString();
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();
} }
// Иначе - отправить текст // Текст
if (!string.IsNullOrWhiteSpace(req.Text)) if (!string.IsNullOrWhiteSpace(req.Text))
{ {
var format = req.TextFormat ?? MessageFormat.Plain; return await SendTextAsync(req, inlineMarkup, markup, disableNotification, ct);
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 null; return null;
} }
// --- Helpers ---
private InlineKeyboardMarkup? BuildInlineMarkup(IEnumerable<IEnumerable<InlineButton>>? 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<IEnumerable<ReplyButton>>? 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<InputFile> 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<Message?> 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<string?> 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();
}
}
/// <inheritdoc /> /// <inheritdoc />
public IAlbumBuilder CreateAlbumBuilder(PageContext ctx) => new TelegramAlbumBuilder(this, ctx, _logger, _client); public IAlbumBuilder CreateAlbumBuilder(PageContext ctx) => new TelegramAlbumBuilder(this, ctx, _logger, _client);