BotFramework.NET.Previewer
1.0.0
See the version list below for details.
dotnet tool install --global BotFramework.NET.Previewer --version 1.0.0
dotnet new tool-manifest # if you are setting up this repo dotnet tool install --local BotFramework.NET.Previewer --version 1.0.0
#tool dotnet:?package=BotFramework.NET.Previewer&version=1.0.0
nuke :add-package BotFramework.NET.Previewer --version 1.0.0
BotFramework
Фреймворк для создания ботов под любую платформу
Возможности
- Последовательное ожидание обновлений от платформы прямо внутри обработчика;
- Запуск из любого места в приложении;
- Работа с расширяемыми абстракциями, предназначенные для реализации поддерживаемой логики обработчиков:
- Безопасная передача типизированного обновления в обработчик;
- Проверка пользовательских условий перед обработкой обновления.
- Поддержка Dependency Injection в обработчиках;
- Отображение дерева обработчиков в отдельном приложении.
BotFramework Previewer
Особая благодарность @inyutin-maxim
Начиная с версии 3.1.0, у Вас имеется возможность просматривать дерево своих обработчиков.
Установка
Перед использованием Вам нужно установить Previewer в качестве инструмента, используя следующую команду терминала:
dotnet tool install --global BotFramework.NET.Previewer
Использование
Зарегистрируйте Previewer в контейнере зависимостей следующим образом:
var services = new ServiceCollection();
// Внедряем BotFramework и обработчики
services.AddBotFramework<ITelegramBotClient>()
.AddHandler<SimpleHandler>()
.AddPreviewer();
В том месте Вашего кода, где необходимо открыть Previewer, используйте IPreviewerRunner:
var serviceProvider = services.BuildServiceProvider();
var runner = serviceProvider.GetRequiredService<IPreviewerRunner>();
runner.Run();
Обновление
Следующая команда терминала выполнит обновление инструмента:
dotnet tool update --global BotFramework.NET.Previewer
Удаление
Следующая команда терминала выполнит удаление инструмента:
dotnet tool uninstall --global BotFramework.NET.Previewer
Начало работы
Регистрация BotFramework в контейнере зависимостей
Пример регистрации BotFramework с использованием ITelegramBotClient от Telegram.Bot:
var services = new ServiceCollection();
// Внедряем нужные сервисы как обычно
services.AddTransient<ISimpleService, SimpleService>();
services.AddTransient<ITelegramBotClient>(provider => new TelegramBotClient("TOKEN"))
// Внедряем BotFramework и обработчики
services.AddBotFramework<ITelegramBotClient>()
.AddHandler<SimpleHandler>();
Передача обновлений в BotFramework
Для передачи обновлений на обработку используется интерфейс IUpdateReceiver. В нем определен единственный метод Receive(...), который выполнит за Вас все необходимое, чтобы доставить обновление к нужному обработчику:
[ApiController]
[Route("[controller]")]
public class BotController : ControllerBase
{
private readonly IUpdateReceiver _receiver;
public BotController(IUpdateReceiver receiver)
{
_receiver = receiver;
}
[HttpPost]
[Route("GetUpdates")]
public IActionResult Post([FromBody] Update update)
{
// Получение новых сообщений от Telegram
if (update.Type == UpdateType.Message)
{
_receiver.Receive(update.Message);
}
return Ok();
}
}
Помните, что IUpdateReceiver регистрируется в контейнере зависимостей, как Singleton. Таким образом, Вы можете вызывать метод Receive(...) из любой точки приложения.
Обработчики
Реализация обработчика
Типичный обработчик выглядит следующим образом:
public class SimpleHandler : IUpdateHandler<string, ITelegramBotClient>
{
public Task HandleAsync(string update, IBotContext<ITelegramBotClient> context)
{
Console.WriteLine($"Получено обновление: {update}");
}
}
Интерфейс IUpdateHandler реализуется с использованием типа обновления и типа внешней системы. В данном случае, ITelegramBotClient выступает в роли внешней системы, а string - тип обрабатываемого обновления.
Внедрение зависимостей в обработчики
Обработчики внедряются в контейнер зависимостей также, как и прочие пользовательские зависимости. Допустим, у нас есть некоторый внешний сервис, выполняющий сложную логику. Вам достаточно внедрить его в контейнер зависимостей и затем получить через конструктор обработчика:
public class SimpleHandler : IUpdateHandler<string, ITelegramBotClient>
{
private readonly ISimpleService _simpleService;
public SimpleHandler(ISimpleService simpleService)
{
_simpleService = simpleService;
}
public async Task HandleAsync(string update, IBotContext<ITelegramBotClient> context)
{
Console.WriteLine($"Получено обновление: {update}");
await _simpleService.DoWorkAsync(update);
}
}
Условные обработчики
Чтобы BotFramework выполнял конкретный обработчик по условию, необходимо реализовать для него интерфейс IWithAsyncPrerequisite:
public class StartHandler : IUpdateHandler<Message, ITelegramBotClient>, IWithAsyncPrerequisite<Message>
{
public async Task HandleAsync(Message command, IBotContext<ITelegramBotClient> context)
{
await context.Client.SendTextMessageAsync(chatId, "Hello world!");
}
public async Task<bool> CanHandleAsync(Message command)
{
return Task.FromResult(command.Text == "/start");
}
}
Примечание. Асинхронный дизайн для условия выбран потому, что зачастую в этой части кода возникает необходимость выполнять асинхронные задачи.
Взаимодействие с внешней системой
Для взаимодействия с внешней системой в метод обработчика поставляется интерфейс IBotContext. Он содержит в себе ссылку на внешнюю систему и дополнительный метод, позволяющий создать запрос на ожидание будущего обновления. Отличным примером может служить пошаговая обработка ботом сообщений от пользователя:
public class SimpleHandler : IUpdateHandler<Message, ITelegramBotClient>
{
private readonly ISimpleService _simpleService;
public SimpleHandler(ISimpleService simpleService)
{
_simpleService = simpleService;
}
public async Task HandleAsync(Message command, IBotContext<ITelegramBotClient> context)
{
var chatId = update.Chat.Id;
await context.Client.SendTextMessageAsync(chatId, "Пожалуйста, введите Вашу фамилию");
var lastname = await context.WaitNextUpdateAsync<Message>();
await context.Client.SendTextMessageAsync(chatId, "Хорошо, теперь введите Ваше имя");
var firstname = await context.WaitNextUpdateAsync<Message>();
await context.Client.SendTextMessageAsync(chatId, $"{lastname} {firstname}");
}
}
Примечание. Такой дизайн обработчиков позволяет эффективно сдерживать логику в конкретных местах и не размазывать ее по всему приложению.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. |
This package has no dependencies.