Чистка кода
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
using BotPages.Core.Context;
|
using BotPages.Core.Context;
|
||||||
using BotPages.Core.Messaging;
|
|
||||||
|
|
||||||
namespace BotPages.Core.Abstractions;
|
namespace BotPages.Core.Abstractions;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ namespace BotPages.Core.Abstractions;
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Óíèâåðñàëüíàÿ ñòðóêòóðà çàïðîñà íà îòïðàâêó ñîîáùåíèÿ/ôàéëà, èñïîëüçóåìàÿ àäàïòåðàìè.
|
/// Óíèâåðñàëüíàÿ ñòðóêòóðà çàïðîñà íà îòïðàâêó ñîîáùåíèÿ/ôàéëà, èñïîëüçóåìàÿ àäàïòåðàìè.
|
||||||
/// Ïîìåùåíà â Core ÷òîáû áûòü äîñòóïíîé äëÿ âñåõ àäàïòåðîâ.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class SendRequest
|
public sealed class SendRequest
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using BotPages.Core.Abstractions;
|
using BotPages.Core.Abstractions;
|
||||||
using BotPages.Core.Messaging;
|
|
||||||
|
|
||||||
namespace BotPages.Core;
|
namespace BotPages.Core;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user