Убраны старые api

This commit is contained in:
FrigaT
2025-12-24 16:30:43 +03:00
parent 37cb6599ba
commit 4124e8c554
7 changed files with 66 additions and 150 deletions

View File

@@ -14,66 +14,4 @@ public static class PageContextAdapterExtensions
/// </summary>
public static Task<string?> SendAsync(this PageContext ctx, SendRequest request, CancellationToken ct = default)
=> ctx.Adapter.SendAsync(request, ct);
/// <summary>
/// Удобная оболочка: отправить текстовое сообщение.
/// </summary>
public static Task<string?> SendTextAsync(this PageContext ctx,
string text,
MessageFormat format = MessageFormat.Plain,
IEnumerable<IEnumerable<InlineButton>>? inline = null,
IEnumerable<IEnumerable<ReplyButton>>? reply = null,
string? messageId = null,
object? adapterOptions = null,
CancellationToken ct = default)
{
var bag = adapterOptions switch
{
null => null,
AdapterOptionsBag b => b,
_ => throw new ArgumentException("adapterOptions must be an AdapterOptionsBag or null. Use MessageBuilder extensions to set adapter options.", nameof(adapterOptions))
};
return ctx.SendAsync(new SendRequest
{
ChatId = ctx.Update.Chat.Id,
Text = text,
TextFormat = format,
Inline = inline,
Reply = reply,
MessageId = messageId,
AdapterOptions = bag
}, ct);
}
/// <summary>
/// Удобная оболочка: отправить файл.
/// </summary>
public static Task<string?> SendFileAsync(this PageContext ctx,
FileDescriptor file,
string? caption = null,
MessageFormat? captionFormat = null,
IEnumerable<IEnumerable<InlineButton>>? inline = null,
IEnumerable<IEnumerable<ReplyButton>>? reply = null,
object? adapterOptions = null,
CancellationToken ct = default)
{
var bag = adapterOptions switch
{
null => null,
AdapterOptionsBag b => b,
_ => throw new ArgumentException("adapterOptions must be an AdapterOptionsBag or null. Use MessageBuilder extensions to set adapter options.", nameof(adapterOptions))
};
return ctx.SendAsync(new SendRequest
{
ChatId = ctx.Update.Chat.Id,
File = file,
Caption = caption,
CaptionFormat = captionFormat,
Inline = inline,
Reply = reply,
AdapterOptions = bag
}, ct);
}
}

View File

@@ -25,10 +25,10 @@ public sealed class MessageBuilder
/// <summary>
/// Установить опции для конкретного адаптера. Ключ адаптера определяется адаптером (напр., "telegram").
/// </summary>
public MessageBuilder WithAdapterOption<T>(string adapterKey, T options)
public MessageBuilder WithAdapterOption<T>(string adapterType, T options)
{
if (_adapterOptions is null) _adapterOptions = new AdapterOptionsBag();
_adapterOptions.Set(adapterKey, options);
_adapterOptions.Set(adapterType, options);
return this;
}
@@ -141,13 +141,35 @@ public sealed class MessageBuilder
// Текст
if (!string.IsNullOrWhiteSpace(_text))
{
messageId = await _ctx.SendTextAsync(_text, _format, _inline, reply, _editMessageId, _adapterOptions, ct);
var req = new SendRequest
{
ChatId = _ctx.Update.Chat.Id,
Text = _text,
TextFormat = _format,
Inline = _inline,
Reply = reply,
MessageId = _editMessageId,
AdapterOptions = _adapterOptions
};
messageId = await _ctx.SendAsync(req, ct);
}
// Файлы
foreach (var (file, caption, captionFormat) in _files)
{
var res = await _ctx.SendFileAsync(file, caption, captionFormat, _inline, reply, _adapterOptions, ct);
var req = new SendRequest
{
ChatId = _ctx.Update.Chat.Id,
File = file,
Caption = caption,
CaptionFormat = captionFormat,
Inline = _inline,
Reply = reply,
AdapterOptions = _adapterOptions
};
var res = await _ctx.SendAsync(req, ct);
// сохранить первый возвращённый id сообщения
if (messageId is null && res is not null) messageId = res;
}

View File

@@ -1,4 +1,3 @@
using BotPages.Core.Abstractions;
using BotPages.Core.Messaging;
namespace BotPages.Telegram;
@@ -15,29 +14,6 @@ public static class MessageBuilderExtensions
/// </summary>
public static MessageBuilder WithTelegramOptions(this MessageBuilder builder, TelegramOptions options)
{
// Ensure bag exists
var bag = (builder as object) switch
{
MessageBuilder mb => GetAdapterBag(mb) ?? CreateAndSetAdapterBag(mb),
_ => null
};
bag?.Set("telegram", options);
return builder;
}
// Reflection helpers to access private adapterOptions field on MessageBuilder
private static AdapterOptionsBag? GetAdapterBag(MessageBuilder builder)
{
var fi = typeof(MessageBuilder).GetField("_adapterOptions", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
return fi?.GetValue(builder) as AdapterOptionsBag;
}
private static AdapterOptionsBag CreateAndSetAdapterBag(MessageBuilder builder)
{
var fi = typeof(MessageBuilder).GetField("_adapterOptions", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var bag = new AdapterOptionsBag();
fi?.SetValue(builder, bag);
return bag;
return builder.WithAdapterOption(TelegramAdapter.AdapterType, options);
}
}

View File

@@ -2,7 +2,6 @@
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;
@@ -23,6 +22,8 @@ namespace BotPages.Telegram;
/// </summary>
public sealed class TelegramAdapter : IMessengerAdapterSetup
{
internal static readonly string AdapterType = typeof(TelegramAdapter).FullName;
private readonly ILogger _logger;
private TelegramBotClient? _client;
private string _token;
@@ -104,9 +105,9 @@ public sealed class TelegramAdapter : IMessengerAdapterSetup
return null;
}
// determine adapter-specific options (TelegramOptions) from bag or use adapter default
// Определите параметры адаптера (TelegramOptions) из папки или используйте параметры адаптера по умолчанию.
TelegramOptions telegramOptions = _options;
if (req.AdapterOptions is AdapterOptionsBag bag && bag.TryGet("telegram", out TelegramOptions? opt) && opt is not null)
if (req.AdapterOptions is AdapterOptionsBag bag && bag.TryGet(AdapterType, out TelegramOptions? opt) && opt is not null)
{
telegramOptions = opt;
}
@@ -137,7 +138,7 @@ public sealed class TelegramAdapter : IMessengerAdapterSetup
}
}
// If there is a file — send file
// Если есть файл - отправить файл
if (req.File is not null)
{
var file = req.File;
@@ -193,7 +194,7 @@ public sealed class TelegramAdapter : IMessengerAdapterSetup
return sentMessage?.MessageId.ToString();
}
// Otherwise treat as text
// Иначе - отправить текст
if (!string.IsNullOrWhiteSpace(req.Text))
{
var format = req.TextFormat ?? MessageFormat.Plain;
@@ -254,54 +255,6 @@ public sealed class TelegramAdapter : IMessengerAdapterSetup
return null;
}
/// <inheritdoc />
public Task<string?> SendTextAsync(string chatId, string text,
MessageFormat format = MessageFormat.Plain,
IEnumerable<IEnumerable<InlineButton>>? inline = null,
IEnumerable<IEnumerable<ReplyButton>>? reply = null,
string? messageId = null,
object? adapterOptions = null,
CancellationToken ct = default)
{
var req = new SendRequest
{
ChatId = chatId,
Text = text,
TextFormat = format,
Inline = inline,
Reply = reply,
MessageId = messageId,
AdapterOptions = adapterOptions as AdapterOptionsBag
};
return SendAsync(req, ct);
}
/// <inheritdoc />
public Task SendFileAsync(string chatId,
FileDescriptor file,
string? caption = null,
MessageFormat? captionFormat = null,
IEnumerable<IEnumerable<InlineButton>>? inline = null,
IEnumerable<IEnumerable<ReplyButton>>? reply = null,
object? adapterOptions = null,
CancellationToken ct = default
)
{
var req = new SendRequest
{
ChatId = chatId,
File = file,
Caption = caption,
CaptionFormat = captionFormat,
Inline = inline,
Reply = reply,
AdapterOptions = adapterOptions as AdapterOptionsBag
};
return SendAsync(req, ct);
}
/// <inheritdoc />
public IAlbumBuilder CreateAlbumBuilder(PageContext ctx) => new TelegramAlbumBuilder(this, ctx, _logger, _client);

View File

@@ -53,7 +53,17 @@ 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: ct);
{
var req = new SendRequest
{
ChatId = _ctx.Update.Chat.Id,
File = file,
Caption = caption,
CaptionFormat = captionFormat
};
await _ctx.SendAsync(req, ct);
}
return;
}
@@ -95,7 +105,16 @@ 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: ct);
var req = new SendRequest
{
ChatId = _ctx.Update.Chat.Id,
File = file,
Caption = caption,
CaptionFormat = captionFormat
};
await _ctx.SendAsync(req, ct);
}
}

View File

@@ -8,7 +8,7 @@ namespace Demo.Pages;
[Route("FileSend")]
public sealed class FileSendPage : SingletonPage
{
public override Task OnEnter(PageContext ctx, CancellationToken ct)
public override async Task OnEnter(PageContext ctx, CancellationToken ct)
{
var content = "Hello from BotPages! This file is generated on the fly.";
var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(content));
@@ -23,9 +23,11 @@ public sealed class FileSendPage : SingletonPage
GetStreamAsync = _ => Task.FromResult<Stream>(stream)
};
return new MessageBuilder(ctx)
await new MessageBuilder(ctx)
.Text("Вот пример отправки нового файла 📎", MessageFormat.Markdown)
.File(demoFile, "Демонстрационный файл")
.SendAsync(ct);
await ctx.GoToHomeAsync(ct);
}
}

View File

@@ -26,7 +26,13 @@ namespace Demo
{
if (args is null || !args.TryGetValue("page", out var pageName))
{
await ctx.SendTextAsync("Не указана страница для открытия.", ct: ct);
var req = new BotPages.Core.Abstractions.SendRequest
{
ChatId = ctx.Update.Chat.Id,
Text = "Не указана страница для открытия."
};
await ctx.SendAsync(req, ct: ct);
return;
}
@@ -37,7 +43,7 @@ namespace Demo
var app = new BotPagesApp(state, logger)
.AddDefaultPage<WelcomePage>()
.MapCommand<WelcomePage>("/start", true, "Главная")
.MapCommand("/open {page}", openHandler, true, "открыть станицу /open {page}")
.MapCommand("/open {page}", openHandler, true, "открыть страницу /open {page}")
.MapCommand(DetailsPage.Command, DetailsPage.CommandHandler, true, DetailsPage.CommandDescription)
.AutoMapRoute()
.AddMiddleware(new ErrorHandlingMiddleware(logger))