91 lines
3.3 KiB
C#
91 lines
3.3 KiB
C#
using BotPages.Core;
|
||
using Telegram.Bot;
|
||
using Telegram.Bot.Types;
|
||
using Telegram.Bot.Types.Enums;
|
||
using Telegram.Bot.Types.ReplyMarkups;
|
||
using static System.Net.Mime.MediaTypeNames;
|
||
|
||
namespace BotPages.Telegram
|
||
{
|
||
/// <summary>
|
||
/// Адаптер клиента для Telegram Bot API.
|
||
/// </summary>
|
||
public sealed class TelegramClientAdapter : IChatClient
|
||
{
|
||
private readonly ITelegramBotClient _bot;
|
||
|
||
public string Id { get; init; } = nameof(TelegramClientAdapter);
|
||
|
||
/// <summary>
|
||
/// Создаёт адаптер на основе ITelegramBotClient.
|
||
/// </summary>
|
||
public TelegramClientAdapter(ITelegramBotClient bot) => _bot = bot;
|
||
|
||
/// <summary>
|
||
/// Отправляет текстовое сообщение с опциональной клавиатурой.
|
||
/// </summary>
|
||
public Task SendTextAsync(long chatId, PageMessage message, IEnumerable<PageAction>? actions, CancellationToken ct)
|
||
{
|
||
ReplyMarkup? replyMarkup = null;
|
||
|
||
if (actions is { })
|
||
{
|
||
var inlineGroups = actions
|
||
.Where(a => a.Placement == ActionPlacement.Inline)
|
||
.GroupBy(a => a.Row)
|
||
.OrderBy(g => g.Key)
|
||
.Select(g => g.Select(a => InlineKeyboardButton.WithCallbackData(a.Label, a.Value)).ToArray())
|
||
.ToArray();
|
||
|
||
var replyGroups = actions
|
||
.Where(a => a.Placement == ActionPlacement.Reply)
|
||
.GroupBy(a => a.Row)
|
||
.OrderBy(g => g.Key)
|
||
.Select(g => g.Select(a => new KeyboardButton(a.Label)).ToArray())
|
||
.ToArray();
|
||
|
||
if (inlineGroups.Any())
|
||
replyMarkup = new InlineKeyboardMarkup(inlineGroups);
|
||
else if (replyGroups.Any())
|
||
replyMarkup = new ReplyKeyboardMarkup(replyGroups) { ResizeKeyboard = true };
|
||
}
|
||
|
||
var parseMode = message.Format switch
|
||
{
|
||
MessageFormat.Markdown => ParseMode.MarkdownV2,
|
||
MessageFormat.Html => ParseMode.Html,
|
||
_ => ParseMode.None,
|
||
};
|
||
|
||
|
||
return _bot.SendMessage(new ChatId(chatId),
|
||
message.Text,
|
||
parseMode: parseMode,
|
||
replyMarkup: replyMarkup,
|
||
disableNotification: message.IsSilent,
|
||
cancellationToken: ct
|
||
);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// Отправляет файлы как документы (по одному или пачкой).
|
||
/// </summary>
|
||
public async Task SendFilesAsync(long chatId, IEnumerable<FileDescriptor> files, CancellationToken ct)
|
||
{
|
||
foreach (var f in files)
|
||
{
|
||
if (f.Content is not null)
|
||
{
|
||
var input = new InputFileStream(f.Content, f.Name);
|
||
await _bot.SendDocument(chatId, input, cancellationToken: ct);
|
||
}
|
||
else
|
||
{
|
||
// Если контент не загружен, и есть FileId — отправляем по Id
|
||
await _bot.SendDocument(chatId, new InputFileId(f.Id), cancellationToken: ct);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} |