BotFramework.NET.Previewer 1.0.0

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet tool install --global BotFramework.NET.Previewer --version 1.0.0                
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest # if you are setting up this repo
dotnet tool install --local BotFramework.NET.Previewer --version 1.0.0                
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=BotFramework.NET.Previewer&version=1.0.0                
nuke :add-package BotFramework.NET.Previewer --version 1.0.0                

BotFramework

nuget build downloads issues pull requests

Фреймворк для создания ботов под любую платформу

Возможности

  • Последовательное ожидание обновлений от платформы прямо внутри обработчика;
  • Запуск из любого места в приложении;
  • Работа с расширяемыми абстракциями, предназначенные для реализации поддерживаемой логики обработчиков:
    • Безопасная передача типизированного обновления в обработчик;
    • Проверка пользовательских условий перед обработкой обновления.
  • Поддержка Dependency Injection в обработчиках;
  • Отображение дерева обработчиков в отдельном приложении.

BotFramework Previewer

Особая благодарность @inyutin-maxim

Начиная с версии 3.1.0, у Вас имеется возможность просматривать дерево своих обработчиков. build

Установка

Перед использованием Вам нужно установить 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 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.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last updated