readme
Some checks failed
CI / build-test (push) Successful in 36s
Release / pack-and-publish (release) Failing after 26s

This commit is contained in:
2025-12-05 13:51:57 +03:00
parent 7f81ca85b8
commit e1b8fa2119

152
README.md
View File

@@ -1,100 +1,92 @@
# BotPages.Core # BotPages Framework
**BotPages.Core** — это универсальный фреймворк для построения ботов с декларативными страницами, навигацией и единым контекстом. BotPages — это архитектурный фреймворк для построения Telegram/MAXботов с чистыми слоями, расширяемыми API и удобным developer experience.
Поддерживает работу сразу с несколькими транспортами (например, Telegram и MAX), сохраняя чистую архитектуру и удобный developer experience.
--- ## ✨ Возможности
- **Навигация через страницы**: каждая страница — отдельный обработчик логики.
## ✨ Основные идеи - **Единый метод GoToAsync**: автоматически поддерживает как `SingletonPage`, так и `StatefulPage`.
- **StatefulPage**: свойства автоматически сохраняются в `StateStorage`.
- **PageResult** — декларативный результат обработки страницы (сообщение, файлы, кнопки, навигация). - **SingletonPage**: один экземпляр на всё приложение, без состояния.
- **PageMessage** — объект сообщения с поддержкой форматов (Plain/Markdown/HTML), флагов (`IsSilent`, `DisableWebPreview`). - **Middleware**: подключение промежуточных обработчиков (логирование, обработка ошибок).
- **PageNavigate** — объект навигации (переход на другую страницу, аргументы, режим Replace). - **Автоматическая регистрация страниц**: через рефлексию.
- **PageAction** — кнопки (inline/reply, ссылки, запрос контакта/локации, стили). - **Роутинг страниц**: возможность устанавливать пути вызова для страниц.
- **UpdateContext** — универсальный контекст обновления, независимый от транспорта, с полем `Transport` для разделения Telegram/MAX. - **Команды**: возможность установки команд, которые работают приоритетнее обработчиков страниц.
- **PageRegistry** — реестр страниц, умеет собирать их автоматически из сборки (`CreateFromAssembly`, `CreateFromApplication`). - **Минимум boilerplate**: декларативные интерфейсы и fluent API.
- **IStateStore** — хранилище состояния пользователя, ключом является `(Transport, ChatId)`.
---
## 🚀 Быстрый старт ## 🚀 Быстрый старт
```csharp ```csharp
// Создаём реестр страниц var app = new BotPagesApp(factory, state, logger)
var registry = PageRegistry.CreateFromApplication(defaultPageId: "main"); .UseDefaultPage<WelcomePage>()
.MapCommand<WelcomePage>("/start")
// Хранилище состояния .AddMiddleware(new LoggingMiddleware(logger))
IStateStore store = new InMemoryStateStore(); .AddMiddleware(new ErrorHandlingMiddleware(logger));
// Навигация
INavigationService nav = new NavigationService(registry, store);
// Запуск Telegram
var telegramBot = new TelegramBotClient("TELEGRAM_TOKEN");
telegramBot.StartReceiving(async (bot, update, ct) =>
{
var ctx = TelegramUpdateMapper.Map(bot, nav, store, update);
await nav.HandleAsync(ctx, ct);
});
// Запуск MAX
var maxClient = new MaxClientAdapter("MAX_CONFIG");
maxClient.OnUpdate(async (update, ct) =>
{
var ctx = MaxUpdateMapper.Map(maxClient, nav, store, update);
ctx.Transport = "max";
await nav.HandleAsync(ctx, ct);
});
``` ```
--- ## 📄 Пример страниц
## 📌 Пример страницы
### StatefulPage
```csharp ```csharp
public sealed class MainPage : IPage public sealed class WelcomePage : StatefulPage
{ {
public string Id => "main"; [Statefull("visitCount")]
private int VisitCount;
public PageResult Handle(UpdateContext ctx) private PageContext? Context { get; set; }
public override async Task OnEnter(PageContext ctx, CancellationToken ct)
{ {
return PageResult.Text("🏠 Главная страница", new[] Context = ctx;
{
new PageAction { Label = "Перейти", Value = "inlinePage", Placement = ActionPlacement.Inline } LoadState();
}); VisitCount++;
SaveState();
await ctx.SendTextAsync($"Добро пожаловать 🚀. Вы заходили сюда {VisitCount} раз(а).", ct: ct);
} }
} }
``` ```
--- ### SingletonPage
```csharp
## 🛠️ Возможности public sealed class HelpPage : SingletonPage
{
- ✅ Декларативные страницы (`PageResult`) public override Task OnEnter(PageContext ctx, CancellationToken ct)
- ✅ Навигация (`PageNavigate`) => ctx.SendTextAsync("Это справка 📖", ct: ct);
- ✅ Сообщения с форматами и флагами (`PageMessage`) }
- ✅ Кнопки с расширенными параметрами (`PageAction`)
- ✅ Поддержка нескольких транспортов (Telegram)
- ✅ Автоматическая регистрация страниц (`PageRegistry.CreateFromApplication`)
- ✅ Хранение состояния по `(ChatClientId, ChatId)`
---
## 📂 Структура проекта
```
BotPages/
├── BotPages.Core/ # Основные классы (PageResult, PageMessage, PageNavigate, UpdateContext)
├── Demo/ # Пример страниц и запуск
├── Adapters/ # Транспортные адаптеры (Telegram)
└── README.md
``` ```
--- ## 🧩 Навигация
```csharp
await ctx.Navigation.GoToAsync<WelcomePage>(ctx, ct); // Stateful
await ctx.Navigation.GoToAsync<WelcomePage>(ctx, agrs, ct); // Stateful with arguments
await ctx.Navigation.GoToAsync<HelpPage>(ctx, ct); // Singleton
await ctx.Navigation.GoToHome(ctx, ct); // Stateful
```
## 📖 TODO ## ⚙️ Middleware
```csharp
public sealed class LoggingMiddleware : IPageMiddleware
{
private readonly ILogger _logger;
public LoggingMiddleware(ILogger logger) => _logger = logger;
- [ ] Поддержка медиагрупп (альбомов) в Telegram public async Task InvokeAsync(PageContext ctx, Func<Task> next, CancellationToken ct)
- [ ] Расширенные стили кнопок {
- [ ] TTL для сообщений _logger.Log(LogLevel.Info, $"Update: {ctx.Update.Kind}");
- [ ] Плагины для сторонних транспортов await next();
}
}
```
## 🏗 Архитектурные принципы
- **Separation of concerns**: страницы не знают о транспорте, всё через адаптеры.
- **Расширяемость**: новые страницы и middleware подключаются декларативно.
- **Прозрачность**: минимум скрытой логики, всё явно через контекст.
- **Developer Experience**: удобные API, автоматическая регистрация, документация через `///summary`.
## 📌 Итог
BotPages позволяет писать чистые, расширяемые и удобные для команды боты:
- минимум boilerplate,
- декларативные интерфейсы,
- прозрачная навигация,
- автоматическое управление состоянием.